Download la interfaz gráfica de usuario en Java s
Document related concepts
no text concepts found
Transcript
1 Capitulo 4 PROGRAMACION GRAFICA 1. Programación Visual Básica La interfaz gráfica de usuario, también conocido como GUI – Graphical User Interface, en Java se realiza a través de bibliotecas de clases, y el primero en surgir fue AWT (Abstract Window Toolkit). El AWT apareció con la versión 1.0, pero se convirtió confiable a partir de la versión 1.1. La forma como las clases de biblioteca trabaja asegura la creación de los elementos de la interfaz de usuario siguiendo el comportamiento destinado a las herramientas GUI nativas para cada plataforma (Windows, Mac, Solaris,..). Algunos ejemplos de estos elementos son: botones, listas, menús, componentes de texto, los contenedores (ventanas y barras de menú), cuadros de diálogo para abrir o guardar archivos y elementos para la manipulación de imágenes, fuentes y colores. La portabilidad de su plataforma funcionaba bien para aplicaciones sencillas, pero las aplicaciones que incluyen elementos más complejos, como menús y barras de desplazamiento, por ejemplo, mostraron diferencias en el comportamiento de acuerdo con la plataforma. Lo que sucedió fue que las aplicaciones visuales hechas en Java no aparecen, ni tenía las mismas características, con las aplicaciones convencionales de cada plataforma. A partir de la versión 2 de Java, JFC (Java Foundation Classes) introdujo nuevas características para crear aplicaciones GUI, que mejoró enormemente los problemas de portabilidad. Ellos son: · Java 2D: nuevas funciones para dibujos y gráficos. · Arrastrar y soltar: hacer clic, arrastrar, copiar y pegar. · Swing: biblioteca de clases extensión de AWT, que presenta el nuevos componentes de interfaz que se conoce por look and feel (apariencia), que es una adaptación perfecta de GUI para el desarrollo específico del sistema operativo. Es bueno destacar que Swing no pretende sustituir el AWT, mas el kit de herramientas GUI más utilizado para el desarrollo de aplicaciones visuales. El AWT continua existiendo, manteniendo la misma arquitectura creada para la versión de Java 1.1. Swing tiene muchas más características, y asegura una mayor portabilidad y en buena parte de los casos, es más fácil de usar. Esto no significa que se utilice AWT o se utilice Swing, normalmente sucede que los elementos de las bibliotecas son utilizados conjuntamente en aplicaciones. En cuanto a la creación de aplicaciones, existen muchas herramientas que ayudan en la producción de interfaces gráficas de usuario, pero no se pueden 2 comparar a las herramientas para plataformas específicas como Visual Basic y Delphi, que están diseñados exclusivamente para este fin. Gran parte de la preparación de la interfaz de la aplicación se tiene que hacer manualmente, lo que requiere bastante trabajo. 1.1 Frames (Marcos) En AWT, es una ventana de más alto nivel de una aplicación (no está contenida dentro de cualquier otro) se denomina Frame. En Swing, existe una versión llamada JFrame, que es derivada/extendida de la clase Frame, que tiene algunos métodos adicionales relacionados con la manipulación de la composición visual de los frames. Todos los otros métodos se derivan de la clase Frame. Un frame puede contener otros componentes GUI. Para establecer un frame básico basado en AWT, se debe: - Importar el paquete java.awt. *. - Extender de la clase Frame. - Contar con un método main () para crear el objeto a partir de operador new. - Y hacerlo visible. De este modo, el código siguiente resulta un frame que se muestra en la Figura 1.1. import java.awt.*; public class FrameUno extends Frame { public static void main(String[] args) { } } FrameUno fr = new FrameUno(); fr.setVisible(true); Para hacerlo visible, se puede utilizar fr.show() en lugar de fr.setVisible (true). Se dio cuenta que no se puede cerrar con el botón Cerrar. Por el momento, se debe cerrar forzando la terminación del proceso (por ejemplo, finalizar tarea en Windows, o terminar la herramienta específica en el proceso de desarrollo). Figura 1.1 Frame FrameUno El frame creado no posee tamaño, ni titulo ni la posición. Para personalizar el frame es necesario insertar un método constructor con las instrucciones necesarias. 3 Ejemplo: import java.awt.*; public class FrameDos extends Frame { public FrameDos() //Constructor { setTitle("Frame Dos"); //Titulo del frame setSize(300,200); // ancho:300 pixeles altura:200 pixeles setResizable(false); //no permite el redimensionamiento setLocation(300,100); //x:200 pixeles y: 100 pixeles } public static void main(String[] args) { FrameDos fr = new FrameDos(); fr.setVisible(true); } } La figura 1.2 muestra el resultado de la ejecución, un frame con el tamaño 300x200 píxeles (setSize() ), con un titulo "Frame Dos" ( setTitle() ), y no permite cambiar el tamaño ( setResizable() ). Figura 1.2 Frame FrameDos Además de eso, setLocation() realiza el posicionamiento del frame en la pantalla, siguiendo el sistema de coordenadas de Java (Figura 1,3), medida en pixels, conforme a la resolución actual de la pantalla. En el ejemplo, el frame se fija posicionándose en 200 pixels para x y 100 pixels para y. 4 Figura 1.3 Sistema de Coordenadas de Java Como ya se mencionó, el frame todavía no se puede cerrar. Para que esto suceda se necesita una manera de recibir una notificación cuando se cierre. A partir del manejo de este evento, que se muestra en el siguiente ejemplo, se puede cerrar el frame. Es necesario importar el paquete java.awt.event.* para manipular eventos de AWT. El modelo de eventos y los demás eventos de la ventana se verá en secciones siguientes. import java.awt.*; import java.awt.event.*; public class FrameTres extends Frame { public FrameTres() //Constructor { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setTitle("Frame Tres"); //Titulo del Frame setSize(300, 200); //ancho: 300 pixeles altura: 200 pixeles setResizable(false); //no permite redimensionamiento setLocation(200, 100); // x: 200 pixeles y: 100 pixeles } public static void main(String[] args) { FrameTres fr = new FrameTres(); fr.setVisible(true); } } Aún en relación a la posición, dependiendo de la resolución de la pantalla donde el frame sea abierto, puede tener situaciones bien desagradables, como por ejemplo, un frame sea abierto fuera de la pantalla. Es necesario colocar el frame en coordenadas que son independientes de la resolución utilizada. En el ejemplo siguiente se abrirá un frame en la mitad del tamaño de la pantalla, posicionándola en el centro, respetando la resolución. 5 import java.awt.*; import java.awt.event.*; public class FrameCuatro extends Frame { public FrameCuatro() //Constructor { addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension d = tk.getScreenSize(); setSize(d.width/2, d.height/2); setLocation(d.width/4, d.height/4); Image img = tk.getImage("icono.gif"); setIconImage(img); setTitle("Frame Cuatro"); setResizable(false); } public static void main(String[] args) { FrameCuatro fr = new FrameCuatro(); fr.setVisible(true); } } Para que sea posible esa tarea de posición de acuerdo a la resolución de vídeo, es necesario obtener información del sistema operativo, y esto se hace a través de la clase Toolkit, el método getScreenSize(), cuyos datos son arrojados a un objeto de clase Dimensión, que almacena la altura y ancho en los campos d.height y d.width. Por ejemplo, si la resolución de vídeo es de 800x600, en d.height se fija 800 y en d.width se fija 600. Teniendo esos valores, es posible utilizar métodos como setLocation() y setSize(), como se hizo en el ejemplo. Ademas, en el ejemplo también se agrega un icono en el frame, también utilizando clase Toolkit, el método de getImage() para cargar una imagen (archivo son extensión .gif) y jugar en un objeto de la clase Imagen, para después establecer el icono a través del método setIconImage(). El mismo ejemplo puede ser hecho con la biblioteca Swing, la clase JFrame, cambiando la derivación e importando el paquete javax.swing.*, así: import import import public { . . } java.awt.*; java.awt.event.*; javax.swing.*; class FrameCuatro extends JFrame . Los ejemplos presentados en las siguientes secciones se crearán basados en la clase JFrame. 1.2 Mostrando Texto y líneas en el Frame Para que sea posible mostrar texto en un frame es necesario crear un objeto basado en la clase Graphics, que será responsable de la gestión del área gráfica a ser dibujada, controlando colores, tipos de fuente, etc. La clase 6 Component tiene un método paint () que acepta un objeto Graphics como parámetro. Ese método, de clase de origen, no hace nada, por lo que debería ser sobreescrito como una llamada de métodos que realizan operaciones de escritura, pintura, dibujo, etc. Para hacer que la superposición del método paint () debe tener el encabezado: public void paint(Graphics g) A partir de esto, métodos como drawString () y drawLine () puede ser utilizado, como en el ejemplo siguiente. El resultado se muestra en la Figura 1.4. import import import public java.awt.*; java.awt.event.*; javax.swing.*; class MostrandoTextos extends JFrame { public MostrandoTextos() { addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}}); Toolkit tk = Toolkit.getDefaultToolkit(); Dimension d = tk.getScreenSize(); int screenHeight = d.height; int screenWidth = d.width; setSize(d.width/2, d.height/2); setLocation(d.width/4, d.height/4); setTitle("Escribiendo Textos"); setResizable(false); } public void paint(Graphics g){ g.drawString("Escribiendo en el frame", 40, 50); g.drawLine(40, 60, 200, 60); int i= 30; while(i<150) { g.drawString("Escribiendo en el frame", 40+i, 50+i); g.drawLine(40+i, 60+i, 200+i, 60+i); i+=30; } } public static void main(String[] args) { MostrandoTextos fr = new MostrandoTextos(); fr.setVisible(true); } } 7 Figura 1.4 Frame MostrandoTextos El método drawString (String s, int x, int y) realiza una muestra de texto en una posición definida por x y y. El método drawLine (int x1, int y1, int x2, int y2) dibuja una línea que se inicia en las coordenadas x1, y1 y termina en las coordenadas x2, y2. 1.3 Colores El método setColor() selecciona un color que se utilizará para todas las operaciones de dibujo dentro el contexto gráfico o componente. Un parámetro Color establece el color a ser usado, y los trece colores estándar se muestran en la tabla 1.1, esto se define en la clase java.awt.Color. black (negro) blue (azul) cyan (cian) darkGray(gris-obscuro) gray (gris) green (verde) lightGray (gris-claro) magenta (magenta) orange (naranja) pink (rosa) red (rojo) white (blanco) yellow (amarillo) Tabla 1.1 Colores definidos en java.awt.Color Además de los colores predefinidos, se puede crear nuevos colores basados en los colores RGB (red-rojo, green-verde, blue-azul), expresada por enteros de 0 a 255. Los ejemplos a continuación presenta la creación de objetos coloridos en un frame. Los resultados se presentan en la figura 1.5. 8 import import import public { java.awt.*; java.awt.event.*; javax.swing.*; class Colores extends JFrame public Colores() { addWindowListener(new WindowAdapter() {public void windosClosing(WindowEvent e){System.exit(0);}}); setSize(400,200); setLocation(200,100); setTitle("Colores"); } public void paint(Graphics g) { g.setColor(Color.blue); g.drawString("Color Azul", 50, 50); g.setColor(Color.green); g.drawLine(50, 60, 220, 60); g.setColor(Color.red); g.drawRect(50, 70, 100, 30); g.setColor(new Color(0,128,128)); g.fillRect(50, 110, 100, 30); } public static void main(String[] args) { Colores fr = new Colores(); fr.setVisible(true); } } Figura 1.5 Frame Colores El método drawRect (int x, int y, int width, int height) dibuja un rectángulo con un color definido por setColor(), a partir de las coordenadas x, y, que tiene una anchura de width y la altura de height. El método fillRect (int x, int y, int width, int height) hace lo mismo, pero rellena el rectángulo. 9 1.4 Fuentes El método responsable para definir el tipo de letra es setFont(), que precisa de un objeto creado, basado en la clase Font, definiendo así el nombre de la fuente, el estilo y tamaño. El nombre puede ser cualquier fuente compatible con el sistema operativo específico, el estilo puede ser: PLAIN-regular, BOLDnegrita e ITALIC - cursiva, siendo posible combinar estilos utilizando el operador +; el tamaño puede ser cualquier valor que represente el tamaño en puntos de fuente. Ejemplo: import java.awt.*; import java.awt.event.*; import javax.swing.*; public class Fuentes extends JFrame { public Fuentes() { addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(400,130); setTitle("Tipos de Fuentes"); } public void paint(Graphics g) { g.setColor(Color.blue); Font f = new Font("SansSerif", Font.ITALIC, 16); g.setFont(f); g.drawString("Fuente SansSerif italica tamaño 16", 20, 50); g.setFont(new Font("Monospaced", Font.BOLD + Font.ITALIC, 14)); g.drawString("Fuente Monospaced negrita e italica tamaño 14", 20, 80); g.setFont(f); g.drawString("Nuevamente Fuente SansSerif italica tamaño 16", 20, 110); } } public static void main(String[] args) { Fuentes fr = new Fuentes(); fr.setVisible(true); } La Figura 1.6 muestra el resultado. Se observa que no es necesario crear explícitamente un objeto de tipo Font( objeto f), puede ser posible crear su propio argumento en setFont(). Si la fuente es utiliza varias veces durante la aplicación, es útil introducir el objeto explícitamente. 10 Figura 1.6 Frame Fuentes En términos de portabilidad, se debe advertir que las fuentes no están disponibles en algunos sistemas operativos. Lo ideal es trabajar con las fuentes comunes de los diferentes sistemas operativos. El modelo de AWT define cinco fuentes disponibles en cualquier sistema operativo. Ellos son: Serif, Monospaced, SansSerif, Dialog y DialogInput. 1.5 Otras Formas geométricas Además de las formas ya presentadas, existen varios otros posibles, sobre todo con la opción de relleno o no, de la precedencia de dibujar o rellenar. Los resultados de ejemplo siguientes en el marco de muestra en la Figura 1.7. Varias formas geométricas se muestran en el frame. Funcionamiento de cada método: · drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight): Dibuja un rectángulo con esquinas redondeadas, a partir de las coordenadas x, y, teniendo una anchura width y una altura height, y está definida por las esquinas por arcWidth y arcHeight. · fillRoundRect(int x, int y, int width, int height, int arcHeight): Igual a drawRoundRect, pero llena el rectángulo arcWidth, int · draw3DRect (int x, int y, int width, int height, boolean raised): Dibuja un rectángulo 3D a partir de las coordenadas x, y, que tiene una anchura width y la altura height, y un valor lógico para indicar la aparición de 3D. · fill3DRect (int x, int y, int width, int height, boolean raised): Igual que el draw3DRect, pero llena el rectángulo. · drawOval(int x, int y, int width, int height): Dibuja un óvalo, basado en las coordenadas del rectángulo que comienza en x, y, que tiene una anchura width y una altura height. · fillOval (int x, int y, int width, int height): Igual que drawOval, pero llena forma oval. · drawArc(int x, int y, int width, int height, int startAngle, int arcAngle): Dibuja un arco, en base a las coordenadas del rectángulo que comienza en x, y, que tiene una anchura width y altura height, que muestra sólo la línea de ángulo con respecto al startAngle y un ángulo de arco arcAngle. · fillArc(int x, int y, int width, int height, int startAngle, int arcAngle): Igual que drawArc, pero llena el arco. 11 - drawPolygon (int [] xPoints, int [] yPoints, int nPoints): Dibuje un polígono basado en las matrices de coordenadas de x, y. - fillPolygon (int [] xPoints, int [] yPoints, int nPoints): Igual que drawPolygon, pero llena el arco. 1.6 Imágenes La clase Image es responsable de la carga de las imágenes almacenadas en el disco. Una vez más, es necesario utilizar un objeto de tipo ToolKit para obtener una imagen, a través del método getImage (), y luego jugar con un objeto de tipo Image. El siguiente ejemplo muestra la manera de llenar un frame con la imagen lado a lado. La Figura 1.8 muestra el resultado. La primera imagen, obtenida por getImage () y echado al objetos Image ima, es mostrada a partir de drawImage (Imagen img, int x, int y, ImageObserver observer), que se inserta la imagen img en las coordenadas x, y, para después ser copiada lado a lado, utilizando el método de copyArea (int x, int y, int width, int height, int dx, int dy), que copia el contenido del áreas que comienza en las coordenadas x, y con ancho width y altura height en un lugar en una distancia dx, dy. Para realizar esta tarea, era necesario encontrar el tamaño de la imagen a tracés de getWidth () y getHeight (). 1.7 Contenedores Contenedor de servir a los componentes de depósitos tales como botones, por ejemplo. Algunos ejemplos de recipientes: JFrame, JPanel y JApplet. Un JFrame es una ventana de más alto nivel; un JPanel es un contenedor utilizado para los componentes del grupo, por lo general dentro de un JFrame; un JApplet permite la ejecución de los navegadores web pueden dibujar algo directamente sobre el bastidor o definir un contenedor como un panel, por ejemplo, y dibujar en ella. No se considera una buena práctica de programación para dibujar directamente sobre el bastidor, ya que fue diseñado para ser contenedores de componentes específicos, tales como barras de menú, por ejemplo. Los paneles deben ser utilizados para los componentes del grupo. Ejemplo mediante la adición de un panel a un marco: El resultado se puede comprobar en la figura 1.9. Para dibujar algo en un panel, debe crear una clase derivada de JPanel y reemplazar el método paintComponent (), que se define en la clase JComponent, y recibe un parámetro de tipo Graphics. Este método es llamado automáticamente cada vez que la ventana se vuelve a dibujar, como en la creación y cambio de tamaño. Si por alguna razón, si desea volver a dibujar el panel de contenido, el 12 método que se llama es el repaint () que se encarga de volver a ejecutar el paintComponent (). El super.paintComponent (g) hace que el método de la superclase también se realiza. Esto se hace normalmente en los métodos de superposición, cuando se quiere crear algo más que el método definido en superclase. La creación de una clase derivada de JFrame se hace a continuación, y un objeto contenedor se crea y luego añadir (añadir) del panel. El método getContentPane () devuelve el área de contenido del bastidor por lo que se puede añadir al panel. 2. DISEÑO DE INTERFACES DE USUARIO CON SWING El paquete Swing es parte de la JFC (Java Foundation Classes) en la plataforma Java. La JFC provee facilidades para ayudar a construir GUIs (Graphical User Interface). Swing trabaja en base a componentes como botones, tablas, marcos, layout’s, y otros. Los componentes Swing se identifican porque pertenecen al paquete javax.swing. Swing existe desde la JDK 1.1 antes de la existencia de Swing, las interfaces gráficas de usuario se realizaban a través de AWT (Abstract Window Toolkit), de quien Swing hereda todo el manejo de eventos. Usualmente, para todo componente AWT existe un componente Swing que la reemplaza, por ejemplo, la clase Button de AWT es reemplazada por la clase JButton de Swing (el nombre de todos los componentes Swing comienza con "J"). Los componentes de Swing utilizan la infraestructura de AWT, incluyendo el modelo de eventos AWT, el cual rige cómo un componente que reacciona a eventos tales como, eventos de teclado, mouse, y otros. Es por esto, que la mayoría de los programas Swing necesitan importar dos paquetes AWT: java.awt.* y java.awt.event.*. 2.1 Estructura básica de una aplicación Swing. Una aplicación Swing se construye mezclando componentes con las siguientes reglas. · Debe existir, al menos, un contenedor de alto nivel (Top-Level Container), que provee el soporte que los componentes Swing necesitan para el pintado (dibujado) y el manejo de eventos. 13 · Otros componentes colgando del contenedor de alto nivel (éstas pueden ser contenedores o componentes simples). El siguiente ejemplo muestra una ventana que despliega el mensaje Hola Mundo: import javax.swing.*; import java.awt.*; import java.awt.event.*; public class HolaMundoSwing { public static void main(String [] args) { JFrame frame = new JFrame("Hola Mundo Swing"); JLabel label = new JLabel("Hola Mundo"); frame.getContentPane().add(label); frame.addWindowListener(new java.awt.event.WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } } ); frame.pack(); //hace que la ventana coja el tamaño más pequeño posible que permita ver todos los componentes. frame.setVisible(true); } } 2.2 Utilización de Layouts básicos Los layout managers o manejadores de composición, ayudan a adaptar los diversos componentes que se desean incorporar a un contenedor, es decir, especifican la apariencia que tendrán los Componentes a la hora de colocarlos sobre un Contenedor. Java dispone de varios, en la actual versión. Layout Manager BorderLayout BoxLayout GridLayout FlowLayout FlowLayout, es el más simple y el que se utiliza por defecto en todos los contenedores. Los Componentes añadidos a un Panel con FlowLayout se encadenan en forma de lista. La cadena es horizontal, de izquierda a derecha, y se puede seleccionar el espaciado entre cada Componente. Por ejemplo: 14 import java.awt.*; import java.awt.event.*; import javax.swing.*; class PanelFlow extends JPanel { public PanelFlow() { setLayout(new FlowLayout()); add(new JButton("Uno")); add(new JButton("Dos")); add(new JButton("Tres")); add(new JButton("Cuatro")); add(new JButton("Cinco")); } } public class AdministradorFlowLayout extends JFrame { public AdministradorFlowLayout() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(200,140); setLocation(150,150); setTitle("FlowLayout"); Container P = getContentPane(); P.add(new PanelFlow()); } public static void main(String[] args) { } } AdministradorFlowLayout fr = new AdministradorFlowLayout(); fr.setVisible(true); GridLayout, la composición GridLayout proporciona gran flexibilidad para situar Componentes. El layout se crea con un número de filas y columnas y los Componentes van dentro de las celdas de la tabla así definida. Por ejemplo: import java.awt.*; import java.awt.event.*; import javax.swing.*; class PanelGrid extends JPanel { public PanelGrid() { setLayout(new GridLayout(3,2)); add(new JButton("Uno")); add(new JButton("Dos")); add(new JButton("Tres")); add(new JButton("Cuatro")); add(new JButton("Cinco")); } } 15 public class AdministradorGridLayout extends JFrame { public AdministradorGridLayout() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(200,150); setLocation(150,150); setTitle("GridLayout"); Container P = getContentPane(); P.add(new PanelGrid()); } public static void main(String[] args) { AdministradorGridLayout fr = new AdministradorGridLayout(); fr.setVisible(true); } } BorderLayout, la composición BorderLayout (de borde) proporciona un esquema más complejo de colocación de los componentes en un contenedor. La composición utiliza cinco zonas para colocar los Componentes sobre ellas: Norte, Sur, Este, Oeste y Centro. El Norte ocupa la parte superior del panel, el Este ocupa el lado derecho, Sur la zona inferior y Oeste el lado izquierdo. Centro representa el resto que queda, una vez que se hayan rellenado las otras cuatro partes. Por ejemplo: import java.awt.*; import java.awt.event.*; import javax.swing.*; class PanelBorder extends JPanel { public PanelBorder() { setLayout(new BorderLayout()); add(new JButton("Uno"),BorderLayout.NORTH); add(new JButton("Dos"),BorderLayout.SOUTH); add(new JButton("Tres"),BorderLayout.EAST); add(new JButton("Cuatro"),BorderLayout.WEST); add(new JButton("Cinco"),BorderLayout.CENTER); } } public class OrganizadorBorderLayout extends JFrame { public OrganizadorBorderLayout() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(300,150); setLocation(150,150); setTitle("BorderLayout"); Container P = getContentPane(); 16 P.add(new PanelBorder()); } public static void main(String[] args) { OrganizadorBorderLayout fr = new OrganizadorBorderLayout(); fr.setVisible(true); } } BoxLayout: Los directores de diseño fueron creados en la versión1.0 de Java. El swing sólo posee a un director de diseño de uso general, llamado BoxLayout, siendo más utilizado para crear barra de herramientas, pudiendo insertar componentes en apenas una línea o una sola columna. En lugar de usar BoxLayout directamente, puede ser usado en otro contenedor de Swing llamado Box, como en el ejemplo siguiente: import java.awt.*; import java.awt.event.*; import javax.swing.*; class PanelBox extends JPanel { public PanelBox() { add(Box.createHorizontalGlue()); add(new JButton("Uno")); add(Box.createHorizontalGlue()); add(new JButton("Dos")); add(Box.createHorizontalGlue()); add(new JButton("Tres")); add(Box.createHorizontalGlue()); add(new JButton("Cuatro")); add(Box.createHorizontalGlue()); add(new JButton("Cinco")); add(Box.createHorizontalGlue()); } } public class OrganizadorBoxLayout extends JFrame { public OrganizadorBoxLayout() { addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(500,100); setLocation(150,150); setTitle("BoxLayout"); Container b = Box.createHorizontalBox(); getContentPane().add(b,BorderLayout.CENTER); b.add(new PanelBox()); } public static void main(String[] args) { OrganizadorBoxLayout fr = new OrganizadorBoxLayout(); fr.setVisible(true); } 17 } GridBagLayout Es bastante flexible, permitiendo la ubicación de los componentes en relación a otros. Así, es posible crear prácticamente cualquier tipo de layout. Por ser más flexible, y más difícil de ser utilizado. El constructor no posee argumentos y apariencia del layout es controlada por la clase GridBagConstraints. import java.awt.*; import java.awt.event.*; import javax.swing.*; class PanelGridBag extends JPanel { GridBagConstraints restricciones = new GridBagConstraints(); public PanelGridBag() { setLayout(new GridBagLayout()); addGridBag(new JButton("Uno"),1,0); addGridBag(new JButton("Dos"),0,1); addGridBag(new JButton("Tres"),1,1); addGridBag(new JButton("Cuatro"),2,1); addGridBag(new JButton("Cinco"),1,2); } void addGridBag(Component objeto, int x, int y ) { restricciones.gridx = x; restricciones.gridy = y; add(objeto, restricciones); } } public class OrganizadorGridBagLayout extends JFrame { } public OrganizadorGridBagLayout(){ addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e){System.exit(0);}}); setSize(270,140); setLocation(150,150); setTitle("GridBagLayout"); Container P = getContentPane(); P.add(new PanelGridBag()); } public static void main(String[] args) { OrganizadorGridBagLayout fr = new OrganizadorGridBagLayout(); fr.setVisible(true); }