Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/efrain-svg/Potes_Freddy_ProgInterfacesG_U3/llms.txt

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

logica_ventana is the single controller in the Contact Management App’s MVC architecture. It receives a reference to the ventana view at construction, registers all event listeners, sets up the table sorter and keyboard shortcuts, then loads contacts from disk — all before the window becomes interactive. Every user action flows through this class, which coordinates between the ventana view and the personaDAO persistence layer while keeping all UI mutations safely on the Event Dispatch Thread.

Class declaration

src/controlador/logica_ventana.java
public class logica_ventana implements ActionListener, ListSelectionListener, ItemListener
Implementing three listener interfaces allows a single instance to handle button clicks (ActionListener), table row selection changes (ListSelectionListener), and combo box / checkbox state changes (ItemListener) without anonymous inner classes for those events.

Constructor

src/controlador/logica_ventana.java
public logica_ventana(ventana delegado) {
    this.delegado = delegado;
    this.dao = new personaDAO(new persona());
    this.i18n = new I18n();
    this.contactos = new ArrayList<persona>();

    configurarEventos();
    configurarTablaYFiltro();
    configurarAtajos();
    configurarMenuContextual();
    configurarCierre();
    aplicarIdioma(I18n.LANG_ES);
    cargarContactosRegistrados();
}
The constructor performs a strict initialization sequence:
1

configurarEventos()

Adds this as an ActionListener on all buttons and as an ItemListener on all combo boxes and the checkbox. Also registers the context-menu items.
2

configurarTablaYFiltro()

Creates a TableRowSorter, attaches it to the table, wires a DocumentListener on txt_buscar to trigger async search on every keystroke, and adds a MouseAdapter that toggles favorites on star-column clicks and shows the context menu on right-click.
3

configurarAtajos()

Binds five keyboard shortcuts to the root pane’s InputMap/ActionMap so they work regardless of which component has focus.
4

configurarMenuContextual()

Calls tbl_contactos.setComponentPopupMenu(delegado.menuContextual) so the popup appears on right-click automatically.
5

configurarCierre()

Attaches a WindowAdapter that calls shutdown() on both executor services when the window closes, preventing thread leaks.
6

aplicarIdioma(I18n.LANG_ES)

Sets Spanish as the initial language, translates every visible label and combo item, and refreshes the table column headers.
7

cargarContactosRegistrados()

Reads the CSV file on a SwingWorker background thread, updating the progress bar while busy, and populates the table when done.

Key fields

FieldTypePurpose
delegadoventanaThe view instance — all UI reads/writes go through this reference
daopersonaDAOData access object for CSV read/write
i18nI18nInternationalisation helper; holds current language and formats dates
contactosList<persona>In-memory contact list; the authoritative source for table data
sorterTableRowSorter<DefaultTableModel>Attached to the table for live text/category filtering and column sorting
editLockReentrantLockPrevents two concurrent edit operations on the same row
exportExecutorExecutorServiceFixed thread pool (size 2) for background CSV export tasks
notificationExecutorExecutorServiceSingle-thread executor that serialises status-bar update messages
searchSeqAtomicIntegerMonotonically-increasing sequence number; stale SwingWorker results are discarded when seq != searchSeq.get()
busyCountAtomicIntegerReference-counted busy flag; UI controls are disabled while count > 0

Setup methods

configurarEventos()

Registers listeners on every interactive component exposed by ventana. Buttons and menu items get addActionListener(this); combos and the checkbox get addItemListener(this); the table selection model gets addListSelectionListener(this).

configurarTablaYFiltro()

src/controlador/logica_ventana.java
sorter = new TableRowSorter<DefaultTableModel>(delegado.modeloTabla);
delegado.tbl_contactos.setRowSorter(sorter);

delegado.txt_buscar.getDocument().addDocumentListener(new DocumentListener() {
    @Override public void insertUpdate(DocumentEvent e) { solicitarBusquedaAsync(); }
    @Override public void removeUpdate(DocumentEvent e) { solicitarBusquedaAsync(); }
    @Override public void changedUpdate(DocumentEvent e) { solicitarBusquedaAsync(); }
});
Also configures column widths, hides grid lines, and sets row height to 34 px. A MouseAdapter on the table dispatches single clicks on the favorite column to alternarFavoritoSeleccionado() and right-click to the context menu.

configurarAtajos()

ShortcutAction
Ctrl + SSave (add or update depending on selection)
Ctrl + NClear form fields
DeleteDelete selected contact
Ctrl + EExport visible contacts to CSV
Ctrl + FFocus and select-all in the search field

configurarMenuContextual()

Sets the popup menu on the table via setComponentPopupMenu, which handles both the right-click trigger and the platform-specific popup gesture automatically.

configurarCierre()

src/controlador/logica_ventana.java
delegado.addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        exportExecutor.shutdown();
        notificationExecutor.shutdown();
    }
});
Gracefully shuts down both executor services so background threads complete or terminate before the JVM exits.

CRUD methods

agregarContacto()

Reads and validates the form fields, then calls validarContactoAsync(-1, ...) to check for duplicates on a background thread. If no duplicate is found, a new persona is appended to contactos, persisted via dao.actualizarContactos(), and the table is refreshed.

modificarContactoSeleccionado()

src/controlador/logica_ventana.java
if (!bloquearEdicion(index)) {
    JOptionPane.showMessageDialog(delegado, i18n.t("msg.editLocked"));
    return;
}
Acquires editLock via tryLock() before proceeding. If the lock is already held by another edit operation, the user sees an “edit locked” message. On success the contact at the selected model index is mutated in place, saved, and the lock is released.

eliminarSeleccionado()

Shows a localised confirmation dialog before removing the contact from contactos under synchronized(contactosLock), then calls guardarCambiosDisco() and refreshes the table and statistics panels.

alternarFavoritoSeleccionado()

Flips persona.isFavorito() for the selected row under contactosLock, persists, and refreshes without clearing form fields — so the edit form remains populated.

Async methods

solicitarBusquedaAsync()

src/controlador/logica_ventana.java
final int seq = searchSeq.incrementAndGet();

if (searchWorker != null && !searchWorker.isDone()) {
    searchWorker.cancel(true);
}

searchWorker = new SwingWorker<RowFilter<Object, Object>, Void>() {
    @Override
    protected RowFilter<Object, Object> doInBackground() {
        // build combined RowFilter from text and category selection
    }

    @Override
    protected void done() {
        if (isCancelled() || seq != searchSeq.get()) { return; }
        SwingUtilities.invokeLater(new Runnable() {
                @Override public void run() { sorter.setRowFilter(filtroFinal); }
            });
    }
};
searchWorker.execute();
Each keystroke cancels the previous SwingWorker and increments searchSeq. The done() callback drops stale results by comparing the local seq snapshot with the current atomic value — only the most recent search applies the filter.

validarContactoAsync(int indexIgnorado, Runnable onValid)

Runs duplicate detection on a background thread under contactosLock. A contact is considered a duplicate if it shares an email address or phone number with any existing contact (excluding the one at indexIgnorado for update operations). Calls onValid.run() on the EDT if no duplicate is found, otherwise shows a warning dialog.

cargarContactosRegistrados()

Sets the progress bar to indeterminate, then delegates to a SwingWorker that calls dao.leerArchivo(). The done() callback populates contactos, refreshes the table, and updates the statistics panel.

exportarCsv()

Opens a JFileChooser, sets UI busy, then submits the export task to exportExecutor. The export runs under synchronized(exportLock) to prevent concurrent writes to the same destination. The EDT is notified on completion via SwingUtilities.invokeLater.

notificarAsync(String mensaje)

src/controlador/logica_ventana.java
notificationExecutor.submit(new Runnable() {
    @Override
    public void run() {
        SwingUtilities.invokeLater(new Runnable() {
                @Override public void run() { actualizarEstado(mensaje); }
            });
    }
});
Queues status-bar updates through the single-thread notificationExecutor so messages are always applied in submission order, even when multiple async operations produce notifications simultaneously.

Language method: aplicarIdioma(String code)

Accepts one of "es", "en", or "pt". Updates i18n, sets the window title, translates every label, button, menu item, and table column header, rebuilds the combo box items while preserving selection indices, then calls refrescarTabla() and actualizarEstadisticas() to redraw localised content. The actualizandoCombos flag prevents the ItemListener from triggering spurious filter resets during the repopulation loop.

Interface methods

actionPerformed(ActionEvent e)

Dispatches to the appropriate CRUD or export method by comparing e.getSource() against the known button and menu item references.
SourceDispatches to
btn_addagregarContacto()
btn_modificarmodificarContactoSeleccionado()
mnu_editarprepararEdicionSeleccionada()
btn_eliminar, mnu_eliminareliminarSeleccionado()
btn_exportar, mnu_exportarexportarCsv()
mnu_favoritoalternarFavoritoSeleccionado()

valueChanged(ListSelectionEvent e)

Ignores adjusting events (e.getValueIsAdjusting()). When a stable selection exists, calls cargarContacto(index) to populate the form fields with the selected contact’s data.

itemStateChanged(ItemEvent e)

Handles three sources:
  • chb_favorito — updates the local favorito boolean immediately on any state change.
  • cmb_categoria — updates the local categoria code when SELECTED and not rebuilding combos.
  • cmb_filtro_categoria — calls aplicarFiltro() (→ solicitarBusquedaAsync()) when SELECTED.
  • cmb_idioma — calls aplicarIdioma() with the newly selected language code when SELECTED.

Build docs developers (and LLMs) love