lunes, 20 de febrero de 2012

Bordes Java Swing, BorderFactory y ejemplos

1 comentarios
A cualquier JComponent se le puede poner uno o mas bordes. Un objeto Border sabe como dibujar los límites de un componente Swing y además de para dibujar lineas o cualquier otro aspecto visual, se pueden utilizar por ejemplo para dar mayor tamaño a los componentes.

Para establecer un borde a un componente debemos usar el método setBorder(Border border).
En otro tutorial ya enseñamos con anterioridad como definir nuestros propios bordes, hoy os enseñaré el uso de la clase BorderFactory que nos permite crear la mayoría de los tipos de bordes que Swing puede crear.

Veamos unos ejemplos de como crear los bordes mas comunes y las opciones que tenemos. En el código podéis leer comentarios sobre que tipos de bordes podemos crear con BorderFactory.

package borderFactory;

import java.awt.Color;
import java.awt.Container;
import java.net.URL;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

public class BorderSamples extends JPanel {

 /**
  * Constructor.
  */
 public BorderSamples() {
  super();
  addComponents();
 }

 /**
  * Añade los componentes.
  */
 private void addComponents() {

  // Borde vacio con 10px por cada lado
  Border empty = BorderFactory.createEmptyBorder(10, 10, 10, 10);

  /** Bordes simples */
  // Borde de color rojo con grosor de linea de 2px
  Border line = BorderFactory.createLineBorder(Color.RED, 2);
  // Bordes biselado de varios colores
  Border bevelRaised = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.BLUE, Color.GREEN, Color.BLACK, Color.RED);
  Border bevelLowered = BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.BLUE, Color.GREEN, Color.BLACK, Color.RED);
  // Bordes grabados de varios colores
  Border etchedRaised = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.RED, Color.GRAY);
  Border etchedLowered = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.RED, Color.GRAY);

  /** Bordes mate */
  /* En este tipo de bordes podemos elegir el grosor de cada uno de los lados y el color con el que pintarlo*/
  Border matte  = BorderFactory.createMatteBorder(3, 3, 5, 5, Color.ORANGE);
  URL imgURL = getClass().getResource("images/star.png");
  ImageIcon ico = new ImageIcon(imgURL);
  /* Ademas de elegir el grosor podemos establecer una icono como imagen de fondo del borde. */
  Border matteIco = BorderFactory.createMatteBorder(10, 10, 0, 20, ico);

  /** Bordes compuestos */
  /* El TitledBorder añade una etiqueta al borde que utilizamos para crearlo,
   * podemos elegir la posición del texto */
  Border titled = BorderFactory.createTitledBorder(line, "titulo", TitledBorder.CENTER, TitledBorder.TOP, null, Color.BLUE);
  /* Un CompoundBorder lo creamos por la combinación de 2 bordes simples. */
  Border compound = BorderFactory.createCompoundBorder(titled, etchedRaised);

  // Paneles
  JPanel simplePanel = new JPanel();
  JPanel mattePanel = new JPanel();
  JPanel compoundPanel = new JPanel();
  simplePanel.setLayout(new BoxLayout(simplePanel, BoxLayout.Y_AXIS));
  mattePanel.setLayout(new BoxLayout(mattePanel, BoxLayout.Y_AXIS));
  compoundPanel.setLayout(new BoxLayout(compoundPanel, BoxLayout.Y_AXIS));

  createComponent("LineBorder", line, simplePanel);
  createComponent("EmptyBorder", empty, simplePanel);
  createComponent("BevelBorder elevado", bevelRaised, simplePanel);
  createComponent("BevelBorder rebajado", bevelLowered, simplePanel);
  createComponent("EtchedBorder elevado", etchedRaised, simplePanel);
  createComponent("EtchedBorder rebajado", etchedLowered, simplePanel);
  createComponent("MatteBorder", matte, mattePanel);
  createComponent("MatteBorder con icono", matteIco, mattePanel);
  createComponent("TitledBorder", titled, compoundPanel);
  createComponent("CompoundBorder", compound, compoundPanel);

  simplePanel.setBorder(BorderFactory.createTitledBorder("Bordes simples"));
  mattePanel.setBorder(BorderFactory.createTitledBorder("Bordes mate"));
  compoundPanel.setBorder(BorderFactory.createTitledBorder("Bordes compuestos"));
  this.add(simplePanel);
  this.add(mattePanel);
  this.add(compoundPanel);
 }

 /**
  * Crea un panel al que le inserta un label con el texto especificado,
  * le establece el borde deseado y lo inserta
  * en el contenedor que le pasamos como parametro
  * @param text Texto de la etiqueta
  * @param border Borde a establecer
  * @param container Contenedor a usar
  */
 private void createComponent(String text, Border border, Container container) {
  JPanel panel = new JPanel();
  JLabel label = new JLabel(text);
  label.setBorder(border);

  panel.add(label);
  container.add(panel);
 }

}

Este sería el resultado de aplicar a las etiquetas creadas cada uno de los distintos bordes.


Y para lanzar la aplicación de ejemplo.

package borderFactory;

import javax.swing.JFrame;


public class Main {

 private static void createAndShowGUI() {
  JFrame frame = new JFrame("Ejemplos de uso de BorderFactory");

  BorderSamples panel = new BorderSamples();

     frame.getContentPane().add(panel);
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     frame.setSize(350, 450);
     frame.setVisible(true);
 }

 public static void main(String[] args) {

  javax.swing.SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    createAndShowGUI();
   }
  });
 }
}


Por supuesto hay muchas más opciones que explotar, pero esa tarea de investigación la dejo para vosotros :)
Esto es todo por hoy, gracias por leerme y espero haberos sido de ayuda.

jueves, 9 de febrero de 2012

BorderLayout y GridLayout, ejemplos de layouts en java

4 comentarios
Hola a todos, hoy vamos a hablar sobre la manera en la que disponemos los componentes Swing en los contenedores de nuestras aplicaciones. Es aquí donde los LayoutManager entran en juego. Por ejemplo cuando hacemos:

JPanel panel = new JPanel();
for(int i = 0; i < 10; i++) {
 panel.add(new JLabel("Etiqueta " + i));
}
Las etiquetas que estamos añadiendo se disponen en fila de izquierda a derecha, esto es porque al crear un panel, por defecto tiene establecido un FlowLayout. Este dispondrá de esta manera los componentes, con una separación de 10 pixeles entre componentes hasta que no quepan mas componentes en la misma línea, momento en el cual saltará a la siguiente. Pero no debemos limitarnos a la manera de disponer los componentes por defecto, vamos a pasar a explicar dos de los LayoutManager que mas se usan. Estos son: BorderLayout y GridLayout.

BorderLayout 

Una disposición Border, dispone un contenedor ordenando y redimensionando sus componentes para adaptarse a cinco regiones: NORTE, SUR, ESTE, OESTE y CENTRO.
Cada una de estas regiones está definida por constantes propias de la clase BordeLayout:

  • BorderLayout.NORTH 
  • BorderLayout.SOUTH 
  • BorderLayout.EAST 
  • BorderLayout.WEST 
  • BorderLayout.CENTER 
Para utilizarlo, bastará con especificar una de estas constantes como limitación al añadir el componente.

JPanel panel = new JPanel();
//Establecemos el BorderLayout al panel
panel.setLayout(new BorderLayout(10, 10));
panel.add(new JButton(“boton”), BorderLayout.CENTER);
Por conveniencia si no especificamos ninguna de estas constantes el componente se insertará en el centro del contenedor. El constructor BorderLayout(int hgap, int vgap) nos permite especificar el espacio en pixeles que existirá entre los componentes en el contenedor, así por ejemplo para hacer que entre los componentes exista un espacio horizontal de 10 pixeles y otro vertical de 20 pixeles bastaría con:
BorderLayout layout = new BorderLayout(10, 20);
Si no especificamos ningún espacio, por defecto no habrá separación entre los componentes. Veamos un ejemplo real de como usarlo:
package layout.borderLayout;

import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JPanel;

public class BorderLayoutPanel extends JPanel {

 public BorderLayoutPanel() {
  // establecemos el layout
  this.setLayout(new BorderLayout(5, 10));
  init();
 }

 /**
  * Añadimos componentes
  */
 private void init() {
  JButton north = new JButton("NORTH");
  JButton south = new JButton("SOUTH");
  JButton east = new JButton("EAST");
  JButton west = new JButton("WEST");
  JButton center = new JButton("CENTER");

  this.add(north, BorderLayout.NORTH);
  this.add(south, BorderLayout.SOUTH);
  this.add(east, BorderLayout.EAST);
  this.add(west, BorderLayout.WEST);
  this.add(center, BorderLayout.CENTER);


 }

}
Este código nos creará un panel al que se le establece un BorderLayout con 5 pixeles de separación horizontal entre los componentes y 10 pixeles de separación vertical.
Para verlo en funcionamiento:
package layout.borderLayout;

import javax.swing.JFrame;


public class Main {

 private static void createAndShowGUI() {
  JFrame frame = new JFrame("Ejemplos de uso de layouts");

  BorderLayoutPanel panel = new BorderLayoutPanel();

     frame.getContentPane().add(panel);
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     frame.setSize(400, 400);
     frame.setVisible(true);
 }

 public static void main(String[] args) {

  javax.swing.SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    createAndShowGUI();
   }
  });
 }
}

Y este sería el resultado.



GridLayout

El GridLayout dispone los componentes de un contenedor en una rejilla rectangular. El contenedor se dividirá en rectangulos iguales y en cada uno se colocará uno de los componentes. A la hora de construir este layout debemos especificar el número de filas y columnas que necesitamos para nuestros componentes, para ello usaremos el siguiente constructor GridLayout(int rows, int cols) , además si queremos controlar el espacio que existirá entre los componentes en el contenedor de manera similar a como hicimos con BorderLayout podemos usar este otro: GridLayout(int rows, int cols, int hgap, int vgap). Pasemos a un ejemplo que nos aclaré más las cosas, por ejemplo digamos que queremos disponer 10 JButton en un panel de manera que se distribuyan en 2 filas y 5 columnas, con una separación horizontal de 15 pixeles y una separación vertical de 5 pixeles. Aquí os dejo el código que configuraría el panel:
package layout.gridLayout;

import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JPanel;

public class GridLayoutPanel extends JPanel {

 public GridLayoutPanel() {
  // establecemos el layout
  this.setLayout(new GridLayout(2, 5, 15, 5));
  init();
 }

 /**
  * Añadimos componentes
  */
 private void init() {

  for(int i = 0; i < 10; i++) {
   this.add(new JButton("Boton " +  i));
  }

 }

}
Para verlo en funcionamiento:
package layout.gridLayout;

import javax.swing.JFrame;


public class Main {

 private static void createAndShowGUI() {
  JFrame frame = new JFrame("Ejemplos de uso de layouts");

  GridLayoutPanel panel = new GridLayoutPanel();

     frame.getContentPane().add(panel);
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     frame.setSize(500, 400);
     frame.setVisible(true);
 }

 public static void main(String[] args) {

  javax.swing.SwingUtilities.invokeLater(new Runnable() {
   public void run() {
    createAndShowGUI();
   }
  });
 }
}
Y este sería el aspecto que tendría este contenedor.




Podríamos hablar largo y tendido sobre LayoutManager en Java, pero esto será tema de siguiente artículos.

Un saludo y gracias por leerme.