No es un bug, es una característica no documentada

martes, 5 de mayo de 2015

Programación. GUIs en Java

0:25 Posted by Inazio , No comments
La API de Java tiene dos librerías para desarrollar aplicaciones con interfaz gráfica.
·         AWT (Abstract Window Toolkit). Forma parte de la JFC (Java Foundation Classes – Clases base de Java). Los componentes se encuentran en la librería Java.AWT
·         SWING. Componentes programados con código no nativo, lo cual los hace más portables. Son componentes más potentes, y se identifican con una J antes del nombre del componente. Los componentes se encuentran en la librería javax.swing y son todo subclases de la clase JComponent.Swing. Forma parte de Java2.

import javax.swing.*;
public class PruebaGUI{
   public static void main(String [] args){
     JFrame frame = new JFrame(“Ventana Hola mundo”);
     frame setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
     JLabel label = new JLabel(“Hola mundo”);
     frame.add(label);
     frame.pack();
     frame.setLocationRelativeTo(null);
     frame.setVisible(true);
   }
}

Veamos el código anterior línea por línea:

JFrame frame = new JFrame(“Ventana Hola mundo”);

Toda aplicación Java que utilice una interfaz con Swing necesita como mínimo un contenedor de alto nivel, que puede ser alguno de los siguientes:
·         JFrame. Implementa una ventana. Las ventanas principales de una aplicación deberían de ser un JFrame.
·         JDialog. Implementa una ventana de tipo diálogo. Este tipo de ventanas se utilizan como ventanas secundarias y generalmente son llamadas por ventanas padre del tipo JFrame.
·         JApplet. Un applet es una aplicación Java que se ejecuta dentro de un navegador web en la máquina del cliente. Un JApplet es una zona de la ventana del navegador donde se va a ejecutar un applet.

En nuestro ejemplo, el contenedor de alto nivel utilizad es JFrame.

frame setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

Esta línea indica lo que hará la aplicación cuando se pulse el botón cerrar. La operación EXIT_ON_CLOSE hace que el programa termine cuando el usuario cierra la ventana.

En este caso, como el programa tiene un solo frame, el cierre del mismo terminará el programa.

JLabel label = new JLabel(“Hola mundo”);
frame.add(label);

Una vez creada la ventana o frame, el siguiente paso es añadir componentes en él. En estas dos líneas se crea un componente de tipo Label y lo añadimos al frame.

frame.pack();

El método pack lo que hace es establecer el tamaño del frame.

En este caso lo que estamos haciendo es darle el tamaño más adecuado a todos los componentes.

Si quisiésemos establecer explícitamente el tamaño de la ventana, podríamos utilizar los métodos setSize y setBounds (con éste método también se puede establecer la posición de la ventana).

frame.setLocationRelativeTo(null);

Esta línea es para centrar la aplicación en pantalla. Es decir, centramos la ventana creada.

frame.setLocationRelativeTo(null);

Como último paso, necesitamos hacer visible la ventana. Otra forma sería utilizando el método show.

Componentes Swing

Los componentes Swing son clases.
Su utilización no difiere a la utilización de cualquier otro objeto.

Swing provee objetos para todos los componentes básicos que se ejecutan en interfaces gráficas.

Componente Swing más comunes


·         JButton. Botón estándar
·         JLabel. Etiqueta de texto estándar
·         JTextField. Cuadro de texto
·         JTextArea. Cuadro de texto multilínea
·         JCheckBox. Casilla de verificación
·         JRadioButton. Botón de opción
·         JComboBox. Lista desplegable
·         JScrollBar. Barra de desplazamiento

Más información y componentes: Consultar la API de Java

Contenedores Swing

Como ya hemos visto, para desarrollar una aplicación en Java necesitamos utilizar un contenedor de nivel superior, como puede ser un JFrame, un JDialog o un JApplet (este último en el caso de que queramos que la aplicación se ejecute dentro de un navegador web).

Existen otro tipo de contenedores intermedios, como son los JPanel. Cuando hay que colocar una serie de componentes en una ventana es imprescindible utilizar paneles para darle a la interfaz la disposición y el aspecto deseado.

JPanel

Los paneles son contenedores de componentes ligeros.
Pueden a su vez contener otros paneles.
Pueden tener un color de fondo (incluso ser opacos o transparentes).
Pueden cambiar la apariencia de los bordes.
Las posibilidades de JPanel son mínimas. Se pueden hacer pocas operaciones con los paneles aparte de establecer bordes o formas de organización de los componentes en ellos (con el método setLayout).

Organización de los controles en un contenedor


Para organizar los controles en un panel es necesario establecer en él un Layout Manager o Administrador de Diseño.

Un contenedor tiene establecido por defecto un Layout Manager pero es posible (e incluso deseable) cambiarlo cuando se realiza una aplicación.

El Layout Manager por defecto es FlowLayout, que coloca los componentes en el contenedor de izquierda a derecha.

Otros posibles Layout Managers son:
·         BorderLayout. Divide el contenedor en cinco partes (norte, sur, este, oeste y centro)
·         CardLayout. Permite colocar grupos de componentes diferentes en momentos diferentes de la ejecución de programa.
·         GridLayout. Coloca los componentes en filas y columnas.
·         GridBagLayout. Coloca los componentes en filas y columnas, pero un componente puede ocupar más de una fila.
·         BoxLayout. Coloca los componentes en una fila o columna ajustándose.

Uso de Layout Manager


Añadir esta línea al comienzo:

import java.awt.*;

Los Layout Manager se pueden establecer al crear el objeto

JPanel panel = new JPanel(new FlowLayout());

O bien una vez que el objeto ha sido creado con el método setLayout

JPanel panel = new JPanel();
Panel.setLayout(new FlowLayout());

En ocasiones, cuando se añade un componente al contenedor hay que especificar la posición que queremos que ocupe en el mismo. El como hacerlo depende del Layout Manager elegido.

Ejemplo FlowLayout

import java.awt.*; // Necesario para los layout
import javax.swing.*;
public class PruebaGUI{
   public static void main(String[] args){
     JFrame frame = new JFrame(“Ventana”);
     JPanel panel = new JPanel(new FlowLayout());      frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
     JLabel label1 = new JLabel(“Etiqueta 1”);
     JLabel label2 = new JLabel(“Etiqueta 2”);
     JLabel label3 = new JLabel(“Etiqueta 3”);
     panel.add(label1);
     panel.add(label2);
     panel.add(label3);
     frame.add(panel);
     frame.pack();
     frame.setLocationRelativeTo(null);
     frame.setVisible(true);
   }
}

Ejemplo BorderLayout

import java.awt.*; // Necesario para los layout
import javax.swing.*;
public class PruebaGUI{
   public static void main(String[] args){
     JFrame frame = new JFrame(“Ventana”);
     JPanel panel = new JPanel(new BorderLayout());    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
     JLabel label1 = new JLabel(“Etiqueta 1”);
     JLabel label2 = new JLabel(“Etiqueta 2”);
     JLabel label3 = new JLabel(“Etiqueta 3”);
     panel.add(“South”, label1);
     panel.add(“North”, label2);
     panel.add(“East”, label3);
     frame.add(panel);
     frame.pack();
     frame.setLocationRelativeTo(null);
     frame.setVisible(true);
   }
}

Organización de los elementos en una ventana

Para organizar los elementos en una ventana también se puede utilizar el Layout Manager que queramos.

Podemos organizar los elementos en paneles y los paneles en la ventana, por ejemplo.

Ejemplo.

import.java.awt.*;
import javax.swing.*;
public class PruebaGUI{
   public static void main(String[] args){
     JFrame frame = new JFrame(“Ventana”);
     JPanel panel = new JPanel(new GridLayout());
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
     JLabel label1 = new JLabel(“Etiqueta 1”);
     JLabel label2 = new JLabel(“Etiqueta 2”);
     JLabel label3 = new JLabel(“Etiqueta 3”);
     JLabel label4 = new JLabel(“Etiqueta 4”);
     panel.add(“South”, label1);
     panel.add(“North”, label2);
     panel.add(“East”, label3);
     frame.add(panel);
     frame.add(label4);
     frame.pack();
     frame.setLocationRelativeTo(null);
     frame.setVisible(true);
   }
}

Apariencia de las ventanas

La apariencia (look and feel) genérica de las ventanas es algo que puede ser modificado según diferentes estilos.

Java tiene un gestor de la interfaz de usuario UIManager que controla la apariencia genérica de las ventanas y de los comportamientos que tienen.

La clase que controla todo esto es javax.swing.UIManager.

Para recuperar el estiulo del sistema utilizar

UIManager.setSystemLookAndFeelClassName();

Dependiendo del sistema que tengamos devolverá una apariencia (predefinida para ese sistema) u otra:

·         Multiplataforma. “javax.swing.plaf.meta.MetalLookAndFeel”
·         Windows. “com.sun.java.swing.plaf.windows.WindowsLookAndFeel”
·         Solaris. “com.sun.java.swing.plaf.motif.MotifLookAndFeel”
·         Mac. “javax.swing.plaf.mac.MacLookAndFeel”
·         Unix / Linux. “com.sun.java.swing.plaf.gtk.GTKLookAndFeel”

Diferentes apariencias

En un sistema Windows, no pongo nada, establezco que el look and feel sea el Multiplataforma(2) (o el Metal(3), lo mismo llamado de otra manera).

Establezco el look and feel por defecto (1). En este caso como estoy bajo Windows se aplica la apariencia Windows.

El Motif(4). Apariencia Solaris. Utilizable en cualquier plataforma.

Si intento apariencia Mac o Linx al estar bajo Windows, ERROR.

¿Cómo lo hago?

1.      Establezco el look and feel por defecto.

try{
   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClaseName());
}
catch(Exception e){
   e.printStackTrace();
}

2.      El multiplataforma

try{
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClaseName());
}
catch(Exception e){
   e.printStackTrace();
}


3.      El Metal

try{
   UIManager.setLookAndFeel(“javax.swing.plaf.metal.MetalLookAndFeel”);
}
catch(Exception e){
   e.printStackTrace();
}


4.      El Motif

try{
UIManager.setLookAndFeel(“com.sun.java.swing.plaf.motif.MotifLookAndFeel”);
}
catch(Exception e){
   e.printStackTrace();
}

Eventos

En todas las aplicaciones, cuando el usuario interactúa con las mismas, suceden cosas (pulsa un botón, cierra una ventana, mueve una barra de desplazamiento, etc.).

Ante estas situaciones, el programa deberá realizar algunas acciones, que lógicamente deberán estar programadas.

Existen una serie de manejadores / controladores de eventos (o listeners) los cuales deberán de ser asociados al componente para que éste ejecute la respuesta necesaria.

Los listeners están especializados dependiendo del evento ocurrido, y sólo tienen sentido para componentes determinados

Listeners asociados a componentes


A continuación tratamos los listeners más comunes, siguiendo el siguiente esquema:

Listener (componentes a los que es aplicable): Acción a la que corresponden

·         ActionListener(JButton, JTextField, JComboBox…): Presinoar el botón, pulsar Intro, elegir una opción
·         AdjustmentListener(JScrollBar…): Mover la barra de desplazamiento…
·         FocusListener(JButton, JTextField, JComboBox, …):  Las acciones de este listener son obtener y perder el foco (colocarnos en el componente e irnos del mismo cuando esté activo).
·         ItemListener(JCheckBox, …): Seleccionar y deseleccionar la opción
·         KeyListener(JTextField, JTextArea, …): Pulsar una tecla cuando el componente tiene el foco
·         MouseListener(Multiples componentes): Acciones como pulsar el botón del ratón
·         MouseMotionListener(Multiples componentes): Acciones como arrastrar o pasar por encima del objeto
·         WindowListener(JFrame): Acciones relativas a la ventana, como por ejemplo, cerrarla.

Para más información sobre Listeners, consultar la API de Java, concretamente el paquete java.awt.event (que casualmente es el que tenemos que importar cuando queremos utilizar eventos).

Ejemplo 1 de Listener

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class PruebaGUI1{
   private static JLabel label = new JLabel(“--”);
   private static JButton btnlimpia = new JButton(“Limpia”);
   private static JButton btnescribe = new JButton(“Escribe”);

   public static void acciones(ActionEvent e){
     Object obj = e.getSource(); // Permite saber que objeto generó el evento
     if (obj == btnlimpia)
         label.setText(“”);
     if (obj == btnescribe)
         label.setText(“Hola mundo”);
   }
}

La función escribe una cosa u otra en la etiqueta de la aplicación en función del botón que generó el evento.

public class principal{
   public static void main(String[] args){
     JFrame frame = new JFrame(“Controlador de eventos”);
    
     btnlimpia.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
              acciones(e);
         }
     });

     btnescribe.addActionListener(new ActionListener(){
         public void actionPerformed(ActionEvent e){
              acciones(e);
         }
     });

     frame.add(label);
     frame.add(btnlimpia);
     frame.add(btnescribe);

     frame.addWindowListener(new WindowsAdaper(){
         public void windowClosing(WindowEvent e){
              System.exit(0);
         }
     }

     frame.setLayout(new GridLayout(0,1));
     frame.pack();
     frame.setVisible(true);
   }
}

Se crea un listener para cada botón de la aplicación.

Los dos ejecutarán el método acciones que se ocupará de distinguir cuál ha generado el evento y hacer lo que corresponde.

El listener ActionListener tiene como único método a implementar actionPerformed (que es obligatorio implementar, al ser ActionListener una interface).

El listener WindowAdaptar, en cambio, es una clase.

Crear aplicaciones independientes

¿Necesito Eclipse / NetBeans para ejecutar aplicaciones? NO

Puedo exportar mis aplicaciones (gráficas) a ficheros .jar ejecutables directamente con un simple doble clic.

Para ello, en Eclipse, File à Export, indicar que quiero exportar como “Runnable jar file”, indicar lo que quiero exportar a incluir en el fichero jar (clases y librerías), el nombre del fichero a crear y se generará.


Ese fichero .jar es directamente ejecutable bajo cualquier sistema operativo que disponga de máquina virtual de Java.

0 comentarios:

Publicar un comentario