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);
 }

}

No hay comentarios:

Publicar un comentario