Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/kenri89/PROYECTO_UTP_AED_1_1/llms.txt

Use this file to discover all available pages before exploring further.

The Course Management panel (PanelCursos) is available to users with the Administrator (admin) and Secretary (secretaria) roles. It provides the full academic course catalog — registration, search, update, deletion, and Excel export. What makes this module architecturally distinctive is that every course is maintained simultaneously in three separate in-memory data structures, each optimised for a different usage pattern, all backed by CursoDAO for SQL Server persistence.

The Curso Data Model

Each course record holds four fields. codigo is the unique primary key used to identify courses across all three structures.
FieldTypeDescriptionConstraint
codigoStringUnique course code — acts as the primary key.Non-null (Guava checkNotNull)
nombreStringFull course name.Non-null
creditosintCredit value of the course.≥ 0 (constructor); > 0 (setter via checkArgument)
semestreintAcademic semester this course belongs to.1 – 10 (Guava checkArgument)
public Curso(String codigo, String nombre, int creditos, int semestre) {
    this.codigo   = checkNotNull(codigo,  "El código no puede ser nulo");
    this.nombre   = checkNotNull(nombre,  "El nombre no puede ser nulo");
    checkArgument(creditos >= 0, "Los créditos no pueden ser negativos: %s", creditos);
    checkArgument(semestre >= 1 && semestre <= 10, "Semestre debe estar entre 1 y 10: %s", semestre);
    this.creditos = creditos;
    this.semestre = semestre;
}

Three Parallel Data Structures

Courses are stored in all three structures at the same time. Each structure serves a distinct role:

ArregloCursos

A fixed-capacity array (default 100, auto-resizes by doubling). Used for index-based access, table rendering, and Excel export via obtenerCursos(). Supports buscar(codigo) by linear scan and eliminarPorCodigo(codigo) by shifting.

ListaCursos

A singly-linked list. Used for combo-box population in the enrollment panel (recorrer(Consumer<Curso>)) and for buscar(codigo) lookups during enrollment creation. Traversal visits nodes in insertion order.

MatrizSemestres

A 10 × 10 two-dimensional array (Curso[10][10]). Row index = semestre - 1. Used for semester-grouped views. Each row holds up to 10 courses per semester. insertarPorSemestre(curso) finds the first null slot in the correct row.
When the panel loads, cargarDatosDesdeSQL() calls limpiar() on all three structures and re-inserts every course returned by CursoDAO.listar():
for (String[] datos : cursosSQL) {
    Curso curso = new Curso(datos[0], datos[1],
                            Integer.parseInt(datos[2]),
                            Integer.parseInt(datos[3]));
    arregloCursos.insertar(curso);
    matrizSemestres.insertarPorSemestre(curso);
    listaCursos.insertar(curso);
}

CRUD Operations

1

Register a New Course

Fill in Código, Nombre, Créditos (integer), and select a Semestre (1–10) from the combo-box. Click Agregar Curso.The panel parses creditos and calls CursoDAO.insertar(codigo, nombre, creditos, semestre). On success it reloads all three structures via cargarDatosDesdeSQL().
dao.CursoDAO cursoDAO = new dao.CursoDAO();
boolean exitoSQL = cursoDAO.insertar(codigo, nombre, creditos, semestre);
if (exitoSQL) {
    cargarDatosDesdeSQL(); // re-syncs all three structures
}
2

Search by Code

Direct lookup on ArregloCursos uses a linear scan comparing codigo case-insensitively:
Curso encontrado = arregloCursos.buscar("AED101");
ListaCursos.buscar(codigo) provides the same search for the enrollment panel when resolving a course by code during matriculation.
3

Update a Course

Right-click any row in the table and choose Actualizar from the context menu. The row data is loaded into the form; the Código field is disabled to prevent key changes. Modify Nombre, Créditos, and/or Semestre, then click Actualizar Curso.The panel calls CursoDAO.actualizar(codigo, nombre, creditos, semestre) and refreshes all three structures. If the semestre changes, MatrizSemestres.actualizarCurso() moves the course to the new row automatically.
dao.CursoDAO cursoDAO = new dao.CursoDAO();
cursoDAO.actualizar(codigo, nombre, creditos, semestre);
cargarDatosDesdeSQL();
txtCodigo.setEnabled(true); // re-enable code field after update
4

Delete a Course

Select a row and click Eliminar por Código. A confirmation dialog is shown. On approval, CursoDAO.eliminar(codigo) removes the record from the database. The three in-memory structures are then cleared and reloaded from SQL.
new dao.CursoDAO().eliminar(codigo);
cargarDatosDesdeSQL();

Semester Constraints

The semestre field is validated at both the model layer (Guava checkArgument) and implicitly by the UI (the combo-box is pre-populated with values 1–10 only). The MatrizSemestres maps semestre to a zero-based row index:
// MatrizSemestres.insertarPorSemestre()
int fila = curso.getSemestre() - 1; // semestre 1 → row 0, semestre 10 → row 9
if (fila < 0 || fila >= filas) return false;
Each row can hold up to 10 courses (default column count). Attempting to insert an 11th course into a semester silently returns false — a warning dialog should be added in a future version.
The Curso constructor uses checkArgument(creditos >= 0, ...) (allows zero), but the setter uses checkArgument(creditos > 0, ...) (requires positive). When creating a course programmatically, pass creditos > 0 to stay consistent with the update path.

Excel Export

Click Exportar a Excel in the toolbar. A file-chooser opens, defaulting to cursos.xls. The export calls:
ExportadorExcel.exportarCursos(arregloCursos, archivo);
The method iterates arregloCursos.obtenerCursos() and writes an HSSFWorkbook with four columns:
Column AColumn BColumn CColumn D
CódigoNombreCréditosSemestre
The header row uses a royal-blue background with bold white text. All columns are auto-sized.

Full Usage Example

// Instantiate the three structures
ArregloCursos    arregloCursos    = new ArregloCursos();
ListaCursos      listaCursos      = new ListaCursos();
MatrizSemestres  matrizSemestres  = new MatrizSemestres(); // 10×10

// Create a course (semestre validated 1-10 by Guava checkArgument)
Curso curso = new Curso("AED101", "Algoritmos y Estructuras de Datos", 4, 2);

// Insert into all three structures
arregloCursos.insertar(curso);
listaCursos.insertar(curso);
matrizSemestres.insertarPorSemestre(curso); // places in row 1 (semestre 2 → index 1)

// Search by code
Curso encontrado = arregloCursos.buscar("AED101");

// Combo-box population (linked traversal)
listaCursos.recorrer(c -> comboBox.addItem(c.getCodigo()));
Because courses are rebuilt from the database on every reload, the in-memory structures always reflect the authoritative SQL Server state. Avoid mutating the structures directly without also calling CursoDAO — the change will be lost on the next cargarDatosDesdeSQL() call.

Build docs developers (and LLMs) love