Mostrando entradas con la etiqueta Layout. Mostrar todas las entradas
Mostrando entradas con la etiqueta Layout. Mostrar todas las entradas

sábado, 3 de diciembre de 2011

Formularios en Java. Componentes (III)

Para ir terminando con los componentes de los formularios, o mejor dicho, para terminar de explicar tan sólo algunos de los más importantes y frecuentes, he hecho otro ejemplo, en el que aparecen fundamentalmente los siguientes componentes:
  • JMenu y JMenuItem
  • JToolBar
  • JFileChoser
  • JColorChoser
El ejemplo pretende ser un editor de texto, pero muy, muy sencillo, ya que la idea es ver la funcionalidad de los componentes anteriores. Las clases que he implementado han sido dos, una para el formulario (editor) y otra para el selector de color. A continuación dejo el código, así como unas capturas de pantalla de como ha quedado.

Los iconos de los botones los he cargado con una clase que nos había pasado el profesor con esta finalidad.

EDITOR

@SuppressWarnings("serial")
public class EditorForm extends JFrame {

 private JTextArea texto;
 private JButton colorButton, negritaButton, cursivaButton;
 
 public EditorForm() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Editor");
  setSize(640, 480);
  setResizable(false);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 }

 private void initComponents() {
  crearMenu();
  crearBarraHerramientas();
  
  texto = new JTextArea();
  texto.setMargin(new Insets(10, 10, 10, 10));
  
  getContentPane().add(new JScrollPane(texto), BorderLayout.CENTER);
 }

 private void crearMenu() {
  JMenuItem nuevoMenuItem = new JMenuItem("Nuevo");
  nuevoMenuItem.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onNuevoMenuItemActionPerformed(e); }
  });
  JMenuItem guardarMenuItem = new JMenuItem("Guardar");
  JMenuItem guardarComoMenuItem = new JMenuItem("Guardar como...");
  guardarComoMenuItem.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onGuardarComoMenuItemActionPerformed(e); }
  });
  JMenuItem salirMenuItem = new JMenuItem("Salir");
  salirMenuItem.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onSalirMenuItemActionPerformed(e);
   }
  });
  
  JMenu archivoMenu = new JMenu("Archivo");
  archivoMenu.add(nuevoMenuItem);
  archivoMenu.addSeparator();
  archivoMenu.add(guardarMenuItem);
  archivoMenu.add(guardarComoMenuItem);
  archivoMenu.addSeparator();
  archivoMenu.add(salirMenuItem);
  
  JMenuBar barraMenu = new JMenuBar();
  barraMenu.add(archivoMenu);
  
  setJMenuBar(barraMenu);
 }

 protected void onNuevoMenuItemActionPerformed(ActionEvent e) {
  texto.setText("");
 }

 protected void onGuardarComoMenuItemActionPerformed(ActionEvent e) {
  JFileChooser guardarDialog = new JFileChooser();
  int resultado = guardarDialog.showSaveDialog(this);
  
  //Si la opción elegida ha sido "Guardar", le han dado a ese botón
  if (resultado == JFileChooser.APPROVE_OPTION) {
   //Donde se va a guardar
   File fichero = guardarDialog.getSelectedFile();

   //TODO Aquí implementaríamos el código necesario para guardar el texto
  }
 }

 protected void onSalirMenuItemActionPerformed(ActionEvent e) {
  dispose();
 }

 private void crearBarraHerramientas() {
  colorButton = new JButton(Iconos.COLOR);
  colorButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onColorButtonActionPerformed(e); }
  });
  negritaButton = new JButton(Iconos.NEGRITA);
  negritaButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onNegritaButtonActionPerformed(e); }
  });
  cursivaButton = new JButton(Iconos.CURSIVA);
  cursivaButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onCursivaButtonActionPerformed(e); }
  });
  
  JToolBar barraHerramientas = new JToolBar();
  barraHerramientas.add(colorButton);
  barraHerramientas.add(negritaButton);
  barraHerramientas.add(cursivaButton);
  //Esta propiedad indica si el usuario puede mover la barra de herramientas o no
  barraHerramientas.setFloatable(false);
  barraHerramientas.setOrientation(JToolBar.HORIZONTAL);
  getContentPane().add(barraHerramientas, BorderLayout.NORTH);
 }

 protected void onColorButtonActionPerformed(ActionEvent e) {
  ColorDialog dialogo = new ColorDialog();
  dialogo.setVisible(true);
  texto.setForeground(dialogo.getColor());
  dialogo.dispose();
 }

 protected void onNegritaButtonActionPerformed(ActionEvent e) {
  // TODO Aquí implementaríamos la funcionalidad de este botón
 }

 protected void onCursivaButtonActionPerformed(ActionEvent e) {
  // TODO Aquí implementaríamos la funcionalidad de este botón
 }
 
}




SELECTOR DE COLOR

@SuppressWarnings("serial")
public class ColorDialog extends JDialog {
 
 private Color color;

 private JColorChooser colorChooser;
 private JButton seleccionarButton, cancelarButton;
 
 public ColorDialog() {
  initForm();
  initComponents();
 }

 private void initForm() {
  setTitle("Seleccionar color");
  setSize(450, 300);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  setLocationRelativeTo(null);
  setModal(true);
 }

 private void initComponents() {
  colorChooser = new JColorChooser();
  
  seleccionarButton = new JButton("Seleccionar");
  seleccionarButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onSeleccionarButtonActionPerformed(e); }
  });
  cancelarButton = new JButton("Cancelar");
  cancelarButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onCancelarButtonActionPerformed(e); }
  });
  
  JPanel botonesPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  botonesPanel.add(seleccionarButton);
  botonesPanel.add(cancelarButton);
  
  getContentPane().add(colorChooser, BorderLayout.CENTER);
  getContentPane().add(botonesPanel, BorderLayout.SOUTH);
 }

 protected void onSeleccionarButtonActionPerformed(ActionEvent e) {
  this.color = colorChooser.getColor();
  //No hacemos dispose() porque tenemos que recuperar el color seleccionado
  setVisible(false);
 }

 protected void onCancelarButtonActionPerformed(ActionEvent e) {
  setVisible(false);
 }
 
 public Color getColor() {
  return color;
 }
 
}

martes, 29 de noviembre de 2011

Formularios en Java. Componentes (II)

Continúo con ejemplos de componentes Swing para formularios. Para realizar estos ejemplos, he implementado un sencillo formulario que nos permita "gestionar" nuestros hobbies, por ejemplo, que nos permita ver el listado de libros que tenemos, añadir alguno nuevo, etc.

Los nuevos componentes utilizados han sido:
  • JTable. A su vez utiliza una clase que implementa TableModel.
  • JTabbedPane
  • JOptionPane
  • JCheckBox
  • JComboBox<E>
  • JTextArea
  • JRadioButton y ButtonGroup
Además, he utilizado algunos de los layouts vistos anteriormente, lo que le da mucho mejor aspecto a los fomrularios, sin necesidad de estar cuadrando coordenadas.

FORMULARIO INICIAL
Es el que se muestra al abrir la aplicación. Consiste en un panel con varias pestañas para cada uno de los hobbies que queramos gestionar. En la primera, se muestra un listado de libros.
Si hacemos clic en "Salir", se muestra un cuadro de diálogo creado con la clase JOptionPane, tal y como se puede ver en el código.

@SuppressWarnings("serial")
public class ComponentesFormII extends JFrame {

 JButton salirButton, nuevoDiscoButton, nuevoLibroButton;
 JTable discosTable, librosTable;
 LibrosTableModel librosTableModel;
 
 public ComponentesFormII() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Mis hobbies");
  setSize(640, 480);
  setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent e) { onWindowClosing(e); }
  });
  setLocationRelativeTo(null);
 }

 private void initComponents() {
  salirButton = new JButton("Salir");
  salirButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onSalirButtonActionPerformed(e); }
  });
  salirButton.setMnemonic(KeyEvent.VK_S);
  
  JPanel botonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  botonPanel.add(salirButton);
  
  JTabbedPane hobbiesPanel = new JTabbedPane();
  hobbiesPanel.add("Libros", librosPanel());
  //Paneles vacíos
  hobbiesPanel.add("Música", new JPanel());
  hobbiesPanel.add("Viajes", new JPanel());
  
  getContentPane().add(hobbiesPanel, BorderLayout.CENTER);
  getContentPane().add(botonPanel, BorderLayout.SOUTH);
 }

 protected void onWindowClosing(WindowEvent e) {
  salir();
 }

 protected void onSalirButtonActionPerformed(ActionEvent e) {
  salir();
 }

 private void salir() {
  BaseDatos.desconectar();
  //La clase JOptionPane nos permite mostrar diferentes cuadros de diálogo
  //Estableciendo las opciones en el constructor
  int respuesta = JOptionPane.showConfirmDialog(this, "¿Está seguro de que quiere salir?", "Salir", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
  if (respuesta == JOptionPane.YES_OPTION) {
   dispose();
  }
 }
 
 private JPanel librosPanel() {
  nuevoLibroButton = new JButton("Añadir libro");
  nuevoLibroButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onNuevoLibroButtonActionPerformed(e); }
  });
  nuevoLibroButton.setMnemonic(KeyEvent.VK_L);
  
  JPanel botonPanel = new JPanel();
  botonPanel.add(nuevoLibroButton);
  
  librosTableModel = new LibrosTableModel();
  librosTable = new JTable(librosTableModel);
  
  JPanel tablaPanel = new JPanel(new BorderLayout());
  tablaPanel.setBorder(BorderFactory.createTitledBorder(" Libros: "));
  //Debemos poner la tabla dentro de un panel de tipo JScrollPane
  //Para que se muestre correctamente
  tablaPanel.add(new JScrollPane(librosTable), BorderLayout.CENTER);
  tablaPanel.add(botonPanel, BorderLayout.SOUTH);
  
  return tablaPanel;
 }

 protected void onNuevoLibroButtonActionPerformed(ActionEvent e) {
  new LibrosForm();
  librosTableModel.refrescar();
 }
 
 
}

LibrosTableModel

public class LibrosTableModel implements TableModel {

 Hobbies hobbies;
 List<Libro> libros;
 private TableModelListener listener;
 
 public LibrosTableModel() {
  hobbies = new Hobbies();
  libros = hobbies.recuperarLibros();
 }
 
 @Override
 public void addTableModelListener(TableModelListener arg0) {
  listener = arg0;
 }

 @Override
 public Class<?> getColumnClass(int arg0) {
  switch (arg0) {
   case 0: return Long.class;
   case 1: return String.class;
   case 2: return Boolean.class;
   case 3: return Boolean.class;
   case 4: return String.class;
  }
  return null;
 }

 @Override
 public int getColumnCount() {
  return 5;
 }

 @Override
 public String getColumnName(int arg0) {
  switch (arg0) {
   case 0: return "ISBN";
   case 1: return "Título";
   case 2: return "Leído";
   case 3: return "Lo tengo";
   case 4: return "Autor";
  }
  return null;
 }

 @Override
 public int getRowCount() {
  return libros.size();
 }

 @Override
 public Object getValueAt(int arg0, int arg1) {
  Libro libro = libros.get(arg0);
  switch (arg1) {
   case 0: return libro.getIsbn();
   case 1: return libro.getTitulo();
   case 2: return libro.getLeido();
   case 3: return libro.getTengo();
   case 4: return libro.getAutor().getNombre();
  }
  return null;
 }

 @Override
 public boolean isCellEditable(int arg0, int arg1) {
  return false;
 }

 @Override
 public void removeTableModelListener(TableModelListener arg0) {
  // TODO Auto-generated method stub

 }

 @Override
 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
  // TODO Auto-generated method stub

 }
 
 //Método que nos permite actualizar el listado de libros cuando hemos añadido alguno
 public void refrescar() {
  libros = hobbies.recuperarLibros();
  listener.tableChanged(new TableModelEvent(this));
 }

}


JOPTIONPANE


CUADRO DE DIÁLOGO "CREAR LIBRO"
Si en el formulario anterior hacemos clic sobre "Añadir libro", se abre un cuadro de diálogo en el que podremos indicar los diferentes datos del ejemplar que queramos. Además, si en el JComboBox, no está el autor que queremos, podemos hacer clic en "Nuevo autor" para añadirlo.

@SuppressWarnings("serial")
public class LibrosForm extends JDialog {

 private JButton guardarButton, cancelarButton, nuevoAutorButton;
 private JLabel isbnLabel, tituloLabel, autorLabel, sinopsisLabel, generoLabel;
 private JTextField isbnText, tituloText;
 private JCheckBox leidoCheck, tengoCheck;
 private JComboBox<String> autores;
 private JTextArea sinopsisTextArea;
 private JRadioButton terrorRadio, cienciaFiccionRadio, romanceRadio, fantasiaRadio;
 private ButtonGroup generoGroup;
 
 private Hobbies hobbies;
 private List<Autor> listado;
 
 public LibrosForm() {
  hobbies = new Hobbies();
  listado = hobbies.recuperarAutores();
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Crear libro");
  setSize(480, 400);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  setResizable(false);
  setModal(true);
 }

 private void initComponents() {
  guardarButton = new JButton("Guardar");
  guardarButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onGuardarButtonActionPerformed(e); }
  });
  cancelarButton = new JButton("Cancelar");
  cancelarButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onCancelarButtonActionPerformed(e); }
  });
  nuevoAutorButton = new JButton("Nuevo autor");
  nuevoAutorButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onNuevoAutorButtonActionPerformed(e); }
  });
  isbnLabel = new JLabel("ISBN:");
  tituloLabel = new JLabel("Título:");
  autorLabel = new JLabel("Autor:");
  sinopsisLabel = new JLabel("Sinopsis:");
  sinopsisLabel.setVerticalAlignment(JLabel.TOP);
  generoLabel = new JLabel("Género:");
  generoLabel.setVerticalAlignment(JLabel.TOP);
  isbnText = new JTextField();
  tituloText = new JTextField();
  sinopsisTextArea = new JTextArea();
  //Debemos indicar el número de filas que queremos que tenga el JTextArea
  sinopsisTextArea.setRows(3);
  leidoCheck = new JCheckBox("Leído");
  tengoCheck = new JCheckBox("Lo tengo");
  terrorRadio  = new JRadioButton("Terror");
  //El método setActionCommand(), nos permite saber a través del JButtonGroup, cuál es el elemento seleccionado
  terrorRadio.setActionCommand("Terror");
  cienciaFiccionRadio = new JRadioButton("Ciencia ficción");
  cienciaFiccionRadio.setActionCommand("Ciencia ficción");
  romanceRadio = new JRadioButton("Romance");
  romanceRadio.setActionCommand("Romance");
  fantasiaRadio = new JRadioButton("Fantasía");
  fantasiaRadio.setActionCommand("Fantasía");
  //El ButtonGroup realiza una agrupación lógica de los JRadioButton, que permite saber cuál es el seleccionado
  generoGroup = new ButtonGroup();
  generoGroup.add(terrorRadio);
  generoGroup.add(cienciaFiccionRadio);
  generoGroup.add(romanceRadio);
  generoGroup.add(fantasiaRadio);
  autores = new JComboBox<String>();
  
  for (Autor autor : listado) {
   autores.addItem(autor.getNombre());
  }
  
  JPanel botonesPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  botonesPanel.add(guardarButton);
  botonesPanel.add(cancelarButton);
  
  //Ponemos el JTextArea dentro de un JScrollPane, para que podamos ver todas las filas si se escribe más de las indicadas
  JScrollPane sinopsisPanel = new JScrollPane(sinopsisTextArea);
  
  JPanel checkPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
  checkPanel.add(leidoCheck);
  checkPanel.add(tengoCheck);
  
  JPanel generoPanel = new JPanel(new GridLayout(2, 2));
  generoPanel.add(terrorRadio);
  generoPanel.add(cienciaFiccionRadio);
  generoPanel.add(romanceRadio);
  generoPanel.add(fantasiaRadio);
  
  JPanel datosPanel = new JPanel(new GridBagLayout());
  datosPanel.add(isbnLabel, new GridBagConstraints(0, 0, 1, 1, 0.25, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(isbnText, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(tituloLabel, new GridBagConstraints(0, 1, 1, 1, 0.25, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(tituloText, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(autorLabel, new GridBagConstraints(0, 2, 1, 1, 0.25, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(autores, new GridBagConstraints(1, 2, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(nuevoAutorButton, new GridBagConstraints(1, 3, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(sinopsisLabel, new GridBagConstraints(0, 4, 1, 1, 0.25, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(sinopsisPanel, new GridBagConstraints(1, 4, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(generoLabel, new GridBagConstraints(0, 5, 1, 1, 0.25, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(generoPanel, new GridBagConstraints(1, 5, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(checkPanel, new GridBagConstraints(1, 6, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  
  getContentPane().setLayout(new BorderLayout());
  getContentPane().add(datosPanel, BorderLayout.NORTH);
  getContentPane().add(botonesPanel, BorderLayout.SOUTH);
 }

 protected void onGuardarButtonActionPerformed(ActionEvent e) {
  Libro libro = new Libro();
  libro.setIsbn(Long.parseLong(isbnText.getText()));
  libro.setTitulo(tituloText.getText());
  libro.setLeido(leidoCheck.isSelected());
  libro.setTengo(tengoCheck.isSelected());
  libro.setAutor(listado.get(autores.getSelectedIndex()));
  libro.setGenero(generoGroup.getSelection().getActionCommand());
  libro.setSinopsis(sinopsisTextArea.getText());
  
  hobbies.insertarLibro(libro);
  dispose();
 }

 protected void onCancelarButtonActionPerformed(ActionEvent e) {
  dispose();
 }

 protected void onNuevoAutorButtonActionPerformed(ActionEvent e) {
  new AutorForm();
  
  //Para actualizar el listado de autores, eliminamos primero todos los elementos
  autores.removeAllItems();
  //Y los volvemos a añadir (así estará el que se acaba de añadir)
  listado = hobbies.recuperarAutores();
  for (Autor autor : listado) {
   autores.addItem(autor.getNombre());
  }
  //Para que aparezca seleccionado el autor que acabamos de añadir
  autores.setSelectedIndex(listado.size()-1);
 }
}


CUADRO DE DIÁLOGO "NUEVO AUTOR"

@SuppressWarnings("serial")
public class AutorForm extends JDialog {
 
 private JButton guardarButton, cancelarButton;
 private JLabel nombreLabel;
 private JTextField nombreText;

 public AutorForm() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Nuevo autor");
  setSize(350, 100);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
  setLocationRelativeTo(null);
  setResizable(false);
  setModal(true);
 }

 private void initComponents() {
  guardarButton = new JButton("Guardar");
  guardarButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onGuardarButtonActionPerformed(e); }
  });
  cancelarButton = new JButton("Cancelar");
  cancelarButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) { onCancelarButtonActionPerformed(e); }
  });
  nombreLabel = new JLabel("Nombre:");
  nombreText = new JTextField();
  
  JPanel botonesPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
  botonesPanel.add(guardarButton);
  botonesPanel.add(cancelarButton);
  
  JPanel datosPanel = new JPanel(new GridBagLayout());
  datosPanel.add(nombreLabel, new GridBagConstraints(0, 0, 1, 1, 0.1, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  datosPanel.add(nombreText, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
  
  getContentPane().setLayout(new BorderLayout());
  getContentPane().add(datosPanel, BorderLayout.NORTH);
  getContentPane().add(botonesPanel, BorderLayout.SOUTH);
 }

 protected void onGuardarButtonActionPerformed(ActionEvent e) {
  Hobbies hobbies = new Hobbies();
  Autor autor = new Autor();
  autor.setNombre(nombreText.getText());
  
  hobbies.insertarAutor(autor);
  dispose();
 }

 protected void onCancelarButtonActionPerformed(ActionEvent e) {
  dispose();
 }
}

martes, 22 de noviembre de 2011

Formularios en Java. Layout

En la entrada anterior puse un ejemplo del uso de varios componentes Swing que podemos usar en formularios. En ese ejemplo no utilicé ningún layout, por lo que para colocar los componentes donde queramos tenemos que hacerlo mediante coordenadas. Esto resulta bastante complicado, sobre todo a medida que aumenta la complejidad del formulario, por lo que se suele hacer es trabajar con layout.

Los layout indican la forma de organizar los componentes dentro de un contenedor. De manera que crearemos el contenedor, que puede ser un JPanel, JFrame, JDialog, etc., estableceremos el layout que más nos interese en cada caso y añadiremos los elementos

Algunos de los layout más importantes, de los que se muestra posteriormente un sencillo ejemplo de código y una imagen, son:
  • FlowLayout. Es el layout por defecto de los paneles (JPanel). En él los componentes se van añadiendo uno junto a otro en filas (de izquierda a derecha y de arriba a abajo). Se creará una nueva fila cuando sea necesario y se redistribuye el contenido al cambiar las dimensiones del contenedor.
  • BoxLayout. Organiza los componentes en una línea horizontal o vertical, sin dejar espacio entre ellos. Un ejemplo de su uso podría ser una barra de herramientas, donde hay varios botones uno junto a otro.
  • GridLayout. Este layout es similar a una tabla, ya que los elementos se distribuirán en sus celdas, que son de tamaño idéntico. Los elementos se añadirán a las celdas siguiendo el orden: de izquierda a derecha y de arriba a abajo.
  • GridBagLayout. Es el layout más complejo, pero también el más flexible. Coloca los componentes dentro de una rejilla, pero gracias al objeto "GridBagConstraints", el componente puede ocupar varias celdas, centrarse a uno u otro lado, que su columna sea más ancha, etc.
  • BorderLayout. Utiliza 5 áreas para colocar los componentes (norte, sur, este, oeste y centro), por lo que sólo se pueden añadir 5 componentes (si los componentes son paneles pueden tener a su vez varios componentes dentro).
Estos ejemplos sólo pretenden dar una noción de "cómo" son los distintos layout. Se han asignado los mismos a un JFrame y se les han añadido algunos componentes para hacerse una idea más fácil de cómo quedan. Normalmente en un formulario se utilizan distintos paneles (JPanel), cada uno con el layout más apropiado, y en ellos se distribuyen los componentes.

FLOWLAYOUT

@SuppressWarnings("serial")
public class EjemploFlowLayout extends JFrame {

 private JLabel unoLabel, dosLabel, tresLabel, cuatroLabel;
 
 public EjemploFlowLayout() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Ejemplo de FlowLayout");
  setSize(400, 300);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 }

 private void initComponents() {
  unoLabel = new JLabel("UNO");
  unoLabel.setOpaque(true);
  unoLabel.setBackground(Color.CYAN);
  dosLabel = new JLabel("DOS");
  dosLabel.setOpaque(true);
  dosLabel.setBackground(Color.RED);
  tresLabel = new JLabel("TRES");
  tresLabel.setOpaque(true);
  tresLabel.setBackground(Color.YELLOW);
  cuatroLabel = new JLabel("CUATRO");
  cuatroLabel.setOpaque(true);
  cuatroLabel.setBackground(Color.GREEN);
  
  //Añadimos el layout
  //Si en el constructor del FlowLayout no ponemos nada, los elementos se colocarán centrados
  getContentPane().setLayout(new FlowLayout(FlowLayout.RIGHT));
  getContentPane().add(unoLabel);
  getContentPane().add(dosLabel);
  getContentPane().add(tresLabel);
  getContentPane().add(cuatroLabel);
 }
}

En la imagen se puede apreciar la redistribución de los componentes:


BOXLAYOUT

@SuppressWarnings("serial")
public class EjemploBoxLayout extends JFrame {

 private JLabel unoLabel, dosLabel, tresLabel, cuatroLabel;
 
 public EjemploBoxLayout() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Ejemplo de BoxLayout");
  setSize(400, 300);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 }

 private void initComponents() {
  unoLabel = new JLabel("UNO");
  unoLabel.setOpaque(true);
  unoLabel.setBackground(Color.CYAN);
  dosLabel = new JLabel("DOS");
  dosLabel.setOpaque(true);
  dosLabel.setBackground(Color.RED);
  tresLabel = new JLabel("TRES");
  tresLabel.setOpaque(true);
  tresLabel.setBackground(Color.YELLOW);
  cuatroLabel = new JLabel("CUATRO");
  cuatroLabel.setOpaque(true);
  cuatroLabel.setBackground(Color.GREEN);
  
  //Añadimos el layout, en este caso los componentes seguirán el eje Y
  getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
  getContentPane().add(unoLabel);
  getContentPane().add(dosLabel);
  getContentPane().add(tresLabel);
  getContentPane().add(cuatroLabel);
 }
}


GRIDLAYOUT

@SuppressWarnings("serial")
public class EjemploGridLayout extends JFrame {

 private JLabel unoLabel, dosLabel, tresLabel, cuatroLabel;
 
 public EjemploGridLayout() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Ejemplo de GridLayout");
  setSize(400, 300);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 }

 private void initComponents() {
  unoLabel = new JLabel("UNO");
  unoLabel.setOpaque(true);
  unoLabel.setBackground(Color.CYAN);
  dosLabel = new JLabel("DOS");
  dosLabel.setOpaque(true);
  dosLabel.setBackground(Color.RED);
  tresLabel = new JLabel("TRES");
  tresLabel.setOpaque(true);
  tresLabel.setBackground(Color.YELLOW);
  cuatroLabel = new JLabel("CUATRO");
  cuatroLabel.setOpaque(true);
  cuatroLabel.setBackground(Color.GREEN);
  
  //Añadimos el layout
  //En el constructor he indicado el número de filas y columnas
  //Si el número de filas es 0, se irán creando a medida que se añaden elementos
  getContentPane().setLayout(new GridLayout(2, 2));
  getContentPane().add(unoLabel);
  getContentPane().add(dosLabel);
  getContentPane().add(tresLabel);
  getContentPane().add(cuatroLabel);
 }
}


GRIDBAGLAYOUT

@SuppressWarnings("serial")
public class EjemploGridBagLayout extends JFrame {

 private JLabel unoLabel, dosLabel, tresLabel;
 
 public EjemploGridBagLayout() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Ejemplo de GridBagLayout");
  setSize(400, 300);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 }

 private void initComponents() {
  unoLabel = new JLabel("UNO");
  unoLabel.setOpaque(true);
  unoLabel.setBackground(Color.CYAN);
  dosLabel = new JLabel("DOS");
  dosLabel.setOpaque(true);
  dosLabel.setBackground(Color.RED);
  tresLabel = new JLabel("TRES");
  tresLabel.setOpaque(true);
  tresLabel.setBackground(Color.YELLOW);
  
  //Creamos la constraint para el primer elemento
  GridBagConstraints constraint = new GridBagConstraints();
  //Coordenadas, celda en la que se colocará el componente "unoLabel"
  constraint.gridx = 0;
  constraint.gridy = 0;
  //Número de celdas que ocupa a lo ancho y a lo alto
  constraint.gridwidth = 1;
  constraint.gridheight = 1;
  //Peso. Cuando los componentes no ocupan todo el espacio, el espacio sobrante se reparte
  //Si lo ponemos a cero cada componente cogerá lo que necesite
  //En este caso se extiende a lo ancho
  constraint.weightx = 1.0;
  constraint.weighty = 0.0;
  //Anclaje. Posición en la que se coloca el componente dentro de la propia celda. Depende del fill
  constraint.anchor = GridBagConstraints.CENTER;
  //Cómo se coloca el componente dentro de la celda. Both (se estira en todo su espacio), Vertical, Horizontal
  constraint.fill = GridBagConstraints.BOTH;
  //Margen con los bordes de la celda
  constraint.insets = new Insets(5, 5, 5, 5);
  
  //Añadimos el layout
  getContentPane().setLayout(new GridBagLayout());
  getContentPane().add(unoLabel, constraint);
  //Con otro de los constructores de la clase GridBagConstraints, podemos instanciarla directamente
  //al añadir el elemento:
  getContentPane().add(dosLabel, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
  //El tercer componente ocupa dos celdas y se extiende a lo alto
  getContentPane().add(tresLabel, new GridBagConstraints(0, 1, 2, 1, 0.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
 }
 
}


BORDERLAYOUT

@SuppressWarnings("serial")
public class EjemploBorderLayout extends JFrame {
 
 private JLabel norteLabel, surLabel, esteLabel, oesteLabel, centroLabel;
 
 public EjemploBorderLayout() {
  initForm();
  initComponents();
  setVisible(true);
 }

 private void initForm() {
  setTitle("Ejemplo de BorderLayout");
  setSize(400, 300);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(DISPOSE_ON_CLOSE);
 }

 private void initComponents() {
  norteLabel = new JLabel("NORTE");
  norteLabel.setOpaque(true);
  norteLabel.setBackground(Color.CYAN);
  norteLabel.setHorizontalAlignment(JLabel.CENTER);
  surLabel = new JLabel("SUR");
  surLabel.setOpaque(true);
  surLabel.setBackground(Color.RED);
  surLabel.setHorizontalAlignment(JLabel.CENTER);
  esteLabel = new JLabel("ESTE");
  esteLabel.setOpaque(true);
  esteLabel.setBackground(Color.YELLOW);
  oesteLabel = new JLabel("OESTE");
  oesteLabel.setOpaque(true);
  oesteLabel.setBackground(Color.GREEN);
  centroLabel = new JLabel("CENTRO");
  centroLabel.setOpaque(true);
  centroLabel.setBackground(Color.WHITE);
  centroLabel.setHorizontalAlignment(JLabel.CENTER);
  centroLabel.setVerticalAlignment(JLabel.CENTER);
  
  //Este paso no sería necesario, ya que por defecto, los JFrame tienen este layout
  getContentPane().setLayout(new BorderLayout());
  //Añadimos los elementos indicando en que posición
  getContentPane().add(norteLabel, BorderLayout.NORTH);
  getContentPane().add(surLabel, BorderLayout.SOUTH);
  getContentPane().add(esteLabel, BorderLayout.EAST);
  getContentPane().add(oesteLabel, BorderLayout.WEST);
  //Lo que se añade en el centro ocupará el mayor espacio posible
  //Deja al resto sólo lo que necesitan.
  getContentPane().add(centroLabel, BorderLayout.CENTER);
 }

}