Buenas prácticas generales
Estructura de proyecto recomendada
src/
├── main/
│ ├── Main.java ← Solo main() y SwingUtilities.invokeLater
│ ├── ui/
│ │ ├── MainWindow.java ← JFrame principal
│ │ ├── panels/
│ │ │ ├── FormPanel.java ← JPanel reutilizables
│ │ │ └── TablePanel.java
│ │ └── dialogs/
│ │ └── ConfigDialog.java
│ ├── model/
│ │ └── Usuario.java ← Clases de datos
│ ├── controller/
│ │ └── UsuarioController.java
│ └── util/
│ └── SwingHelper.java ← Utilidades reutilizables
└── resources/
├── icons/
├── images/
└── mensajes.properties
Checklist de calidad
// ✅ 1. Siempre crear la GUI en el EDT
SwingUtilities.invokeLater(() -> new MainWindow().setVisible(true));
// ✅ 2. Usar setPreferredSize() en vez de setSize() en los paneles
panel.setPreferredSize(new Dimension(300, 200));
frame.pack(); // Ajusta automáticamente al tamaño preferido
// ✅ 3. Usar constantes de Look and Feel antes de crear la GUI
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
// ✅ 4. Liberar recursos en dispose()
@Override
public void dispose() {
timer.stop();
worker.cancel(true);
super.dispose();
}
// ✅ 5. Usar BorderFactory para bordes (los crea una vez, son inmutables)
Border borde = BorderFactory.createEmptyBorder(10, 10, 10, 10);
// ❌ MAL: new EmptyBorder(10, 10, 10, 10) crea un objeto nuevo cada vez
// ✅ 6. Separar la lógica de negocio de la interfaz
// NO: calcular en actionPerformed
// SÍ: llamar a un método del modelo/servicio
// ✅ 7. Evitar magia de píxeles — usar layouts siempre
// ❌ MAL: componente.setBounds(10, 20, 100, 30)
// ✅ BIEN: usar GridBagLayout, BoxLayout, etc.
// ✅ 8. Deshabilitar botones durante operaciones largas
btnProcesar.setEnabled(false);
new MiSwingWorker(btnProcesar).execute(); // re-habilita en done()
// ✅ 9. Usar Action para comandos reutilizables (menú + botón + atajo)
Action guardarAction = new AbstractAction("Guardar", iconoGuardar) {
{
putValue(ACCELERATOR_KEY,
KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK));
putValue(SHORT_DESCRIPTION, "Guardar el documento actual");
putValue(MNEMONIC_KEY, KeyEvent.VK_G);
}
@Override
public void actionPerformed(ActionEvent e) {
guardar();
}
};
// Asignar la misma acción al botón y al item de menú:
new JButton(guardarAction);
new JMenuItem(guardarAction);
// ✅ 10. Centralizar la creación de componentes
public static JButton crearBoton(String texto, String tooltip, ActionListener al) {
JButton btn = new JButton(texto);
btn.setToolTipText(tooltip);
btn.addActionListener(al);
return btn;
}