El día de hoy hablaremos sobre la programación conducida por eventos
Los programas tradicionales (basados en texto) tienen dos características primordiales. La primera es que el software controla el flujo de la ejecución, y la segunda es que el programa controla la secuencia de los datos e instrucciones que entran.
En escenarios para usuarios experimentados, este tipo de programas son útiles en el sentido de que le dan más opciones al usuario. Desafortunadamente, la mayoría de los usuarios se sienten intimidados por los programas basados en texto, dificultando así la operación de los programas y el cumplimiento de las tareas que deben realizar. Es por esto que existen los programas con GUI.
El software desarrollado con con GUI tiene una característica importante: es “event-driven”, es decir, está conducido por eventos.
En otras palabras:
- La secuencia de las entradas que el usuario realice controlarán el flujo de la ejecución del software
- El sistema, teniendo ya las entradas, correrá código del usuario.
La generación de los eventos es clave en este tipo de sistemas, y es algo que debe estar controlado para evitar problemas durante la ejecución del software, sea una aplicación o un sitio web. La primer pregunta que nos debemos hacer es ¿Como se pueden generar dichos eventos?
- Acciones como presionar un botón, mover el mouse a través de la pantalla o hasta dictar un comando (Como en la búsqueda de Google). son reconocidas e identificadas por los sistemas operativos (OS) o la JVM.
- Por cada acción que el usuario realice, el sistema operativo, junto con la JVM, determinarán cuál de los programas que se están ejecutando recibirán la entrada del usuario.
- Las señales que la aplicaciones reciben del SO/JVM como resultado de una acción es lo que nosotros llamamos un evento.
Ahora bien, una vez que tenemos esos eventos registrados ¿Como los manejamos?
- Una aplicación responde a las entradas del usuario ejecutando código adecuado para cada tipo particular de eventos.
- No todos los eventos necesitan ser tenidos en cuenta por una aplicación. Por ejemplo: Una aplicación para crear dibujos puede estar interesada sólo en movimientos del mouse.
- Como diseñador de una aplicación administrada por eventos, deberá escribir clases/métodos para manejar los eventos relevantes.
He aquí la importancia de la Java GUI ¿Por qué? Sencillo: Java provee por de facto dos librerías para diseñar GUIs:
- Java AWT (Abstract Window Toolkit)
- Java Foundation Classes (JFC/Swing), a partir de Java 2.0
Hablemos de Swing.
- Esta librería es implementada sin usar código nativo (100% Java), con lo cual la GUI se verá de la misma forma en distintas plataformas.
- Está basada en la arquitectura MVC.
- Ofrece una amplia variedad de colores y diseños, lo que permite diseñar GUI’s muy diversas. Con esto, el diseñador puede crear GUI’s únicas, con diseños atractivos.
- Los componentes de Swing continuarán siendo mejorados en el futuro.
AWT y Swing: ¿Cuáles son sus caracteristicas básicas?
- Los componentes de Swing tienen nombres que comienzan con J.:
Ejemplo de ello es Button en AWT, y JButton en Swing - Los componentes de AWT están en el paquete java.awt, mientras que los de Swing los encontramos en javax.swing.
123import javax.swing.*;import java.awt.*;import java.awt.event.*;
Aplicaciones basadas en GUI ¿Qué debemos saber para crear una?
El desarrollo de una aplicación que esté basada en GUI requiere la comprensión de los siguientes temas:
- La estructura que sostiene la jerarquía de herencia, la cual define el comportamiento y atributos de los componentes en la GUI de la aplicación.
- La estructura que contiene la jerarquía de contenedores, la define cómo se disponen todos los componentes en la GUI de la aplicación.
- Manejo de eventos.
¿Cuáles son los componentes de Swing?
- La clase Component (y sus subclases) proveen soporte para manejo de eventos, cambio del tamaño de un componente, control de color y fuentes, pintado.
- Un componente siempre es un objeto de una subclase concreta.
Se distinguen dos clases de componentes:
- Componentes de control de la GUI: la interacción de la GUI con el usuario se realiza a través de ellos.
- Contenedores: contienen otros componentes (u otros contenedores).
Contenedores
- Anidamiento de componentes (Jerarquía de contenedores en contraste con la Jerarquía de herencia). Cada programa Swing contiene al menos una.
- Swing provee 4 contenedores de alto nivel (ventana base de la GUI):
JFrame, JApplet, JDialog y JWindow.
- La jerarquía está compuesta de diversascapas.
Cada contenedor de alto nivel contiene un contenedor intermedio conocido como “content pane ”. En la gran mayoría de los programas no es necesario conocer qué hay entre el contenedor de alto nivel y el content pane.
Jerarquía de contenedores
La apariencia que tendrá una GUI está determinada por los siguientes elementos:
- La jerarquía de contenedores
- El Layout Manager que conforma a cada contenedor
- Las propiedades que integran cada uno de los componentes individuales
Todos estos ítems trabajan en conjunto para determinar el efecto visual final.
Veamos un ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.Container; import java.awt.Color; public class Ejemplo { public static void main(String args[]){ //Se crea un objeto JPAnel de 300X300 y color rojo JPanel panelRojo =new JPanel(); panelRojo.setBackground(Color.RED); panelRojo.setSize(300,300); //Se crea una ventana de 300X300 JFrame ventana=new JFrame("Prueba en rojo"); ventana.setLocation(100,100); ventana.setSize(300,300); ventana.setVisible(true); //Se coloca el JPanel en el content pane Container contentPane=ventana.getContentPane(); contentPane.add(panelRojo); } } |
Content Panes
- Usualmente es un JPanel.
- En la mayoría de las aplicaciones de Java, Swing contiene casi todo, excepto la barra de menú.
- Debe ser creado explícitamente.
Veamos un ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
import javax.swing.*; import java.awt.event.*; public class HolaMundo { public static void main(String[] args) { JFrame frame = new JFrame("HolaMundoSwing"); final JLabel label = new JLabel("Hola Mundo"); frame.getContentPane().add(label); //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.addWindowListener(new java.awt.event.WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } } ); frame.pack(); frame.setVisible(true); } } |
Componentes de una GUI
- Crear una instancia del objeto
1b = new JButton(“press me”); - Configurar los siguientes elementos
* Propiedades
1b.text = “press me”; //evitar el acceso directo a propiedades
* Métodos:
12345b2 = new JButton("Middle button", middleButtonIcon);b2.setVerticalTextPosition(AbstractButton.BOTTOM);b2.setHorizontalTextPosition(AbstractButton.CENTER);b2.setMnemonic(KeyEvent.VK_M);b2.setToolTipText("This middle button does nothing “ + "when you click it."); - Añadir
1panel.add(b); - Manejar eventos
Características especiales
Los componentes de Swing ofrecen ciertas características especiales que ayudan al desarrollo del programa:
Tool tip | Cuando el cursor del mouse se posiciona sobre un componente se muestra una línea de texto. |
Mnemonic | Se ejecuta una tarea ó acción como consecuencia del pulsado de una combinación de teclas. |
Disable | Permite que un componente sea explícitamente habilitado o deshabilitado. |
Border | Rodea un componente con un borde. |
- Tool tips
12JButton button = new JButton ("Compute");button.setToolTipText ("Calculate size."); - Mnemonic
1button.setMnemonic ("C"); - Disable
12JButton button = new JButton (“Do It”);button.setEnabled (false);
Veamos un ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class UnJBoton { public static void main(String args[]) { Frame f = new Frame(); JButton b = new JButton("Pulsame"); f.add(b); f.pack(); f.setVisible(true); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("HOLA"); } } ); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
import javax.swing.*; import java.awt.*; public class Botones extends JButton { public static void main(String[] args) { JFrame f = new JFrame(); Icon icon = new ImageIcon("b1.gif"); Icon iconp = new ImageIcon("b2.gif"); Icon iconr = new ImageIcon("b3.gif"); Icon icond = new ImageIcon("b4.gif"); JButton b1 = new JButton("Pulsame",icon); JButton b2 = new JButton("Pulsame",iconp); JButton b3 = new JButton("Pulsame",iconr); JButton b4 = new JButton("Pulsame",icon); b1.setEnabled(false); b1.setDisabledIcon(icond); b1.setRolloverIcon(iconr); b1.setPressedIcon(iconp); Container c = f.getContentPane(); c.setLayout(new FlowLayout()); c.add(b1); c.add(b2); c.add(b3); c.add(b4); f.pack(); f.setVisible(true); } } |
- Bordes
123JPanel myPanel = new JPanel();Border myBorder = BorderFactory.createEtchedBorder();myPanel.setBorder(myBorder);
* Empty * Titled
* Line * Matte
* Etched * Compound
* Bevel
Uso de un componente GUI
- Crearlo
- Configurarlo
- Añadir hijo (si es contenedor)
- Añadir al padre (si no es JFrame)
- Manejar los eventos
Window Layout
- Cada contenedor administrala disposición de sus componentes.
- La única tarea del desarrollador es añadir los componentes, el contenedor se encarga de la disposición de los mismos.
- El contenedor utiliza un Layout Manager para manejar la disposición de los componentes en el mismo.
- Para darle más poder al creador, existen diferentes Layout Managers.
- El layout a usar puede ser determinado especificando Layout Managers para los contenedores.
Layout Managers
- Existen muchos Layout Managers predefinidos en:
* FlowLayout (en java.awt)
* BorderLayout (en java.awt)
* CardLayout (en java.awt)
* GridLayout (en java.awt)
* GridBagLayout (en java.awt)
* BoxLayout (en javax.swing)
* OverlayLayout (en javax.swing)
Layout Managers (LM)
- Cada contenedor tiene un Layout Manager por defecto, aunque se puede establecer otro LM para el mismo, de forma explícita. Para anular el LM por defecto se usa el método setLayout (para contenedores de alto nivel se usa getContentPane().setLayout().
- El Layout Manager intenta ajustar la disposición de los componentes en el contenedor cuando se añade un nuevo componente o cuando el contenedor cambia de tamaño.
- Puede crear su propio LM.
Filechooser
La clase JFileChooser proporciona un UI para elegir un archivo de una lista. Un selector de archivos es un componente que podemos situar en cualquier lugar del GUI de nuestro programa.
Los selectores de archivos se utilizan comúnmente para dos propósitos:
- Para presentar una lista de ficheros que pueden ser abiertos por la aplicación.
- Para permitir que el usuario seleccione o introduzca el nombre de un fichero a grabar.
Existen tres métodos los cuales retornan lo siguiente:
- JFileChooser.CANCEL_OPTION, si el usuario hace clic en Cancelar.
- JFileChooser.APPROVE_OPTION, si el usuario pulsa en OK / Abrir / Guardar
- JFileChooser.ERROR_OPTION, si el usuario cierra el cuadro de diálogo
Ejemplo
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import javax.swing.JFileChooser; public class Ejemplo { public static void main(String s[]) { //Creamos selector de apertura JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new java.io.File(".")); //Titulo que llevara la ventana chooser.setDialogTitle("Titulo"); //Elegiremos archivos del directorio chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setAcceptAllFileFilterUsed(false); //Si seleccionamos algún archivo retornaremos su directorio if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { System.out.println("Directorio: " + chooser.getCurrentDirectory()); //Si no seleccionamos nada retornaremos No seleccion } else { System.out.println("No seleccion "); } } } |
Filtrar la lista de ficheros
Por defecto, un selector de ficheros muestra todos los ficheros y directorios que se han detectado. Un programa puede aplicar uno o varios filtros de ficheros a un selector de ficheros para que el selector sólo muestre algunos de los existentes. Una vez hecho esto, el selector llama al método accept del filtro con cada fichero para determinar si debería ser mostrado. El trabajo de un filtro de ficheros consiste en aceptar o rechazar un fichero basándose en algún criterio como el tamaño, el tipo, su propietario, o cualquier otra característica elegida.
JFileChooser soporta tres clases de filtrado. Los filtros se eligen en el orden aquí listado. Por eso un filtro del segundo tipo solo puede filtrar los ficheros aceptados por el primero, etc.
- Filtrado interno
El filtrado se configura a través de llamadas a métodos específicos de un selector de ficheros. Actualmente el único filtro interno disponible es para los ficheros ocultos. Se llama a setFileHidingEnabled(true) para desactivar la selección de ficheros ocultos (como aquellos que empiezan con ‘.’ en sistemas UNIX). - Filtrado controlado por la aplicación
La aplicación determina los ficheros a mostrar. Se crea una subclase de FileFilter, se ejemplariza, y se utiliza el ejemplar como un argumento para setFileFilter. El selector de fiheros sólo mostrará los ficheros que acepte el filtro. - Filtrado seleccionable por el usuario
El GUI selector de ficheros proporciona una lista de filtros de la que el usuario puede elegir uno. Cuando el usuario elige un filtro, el selector de ficheros muestra sólo aquellos ficheros que acepte el filtro.
¿Te gustó este artículo?
Si te gustó este artículo, te ha servido o aprendiste algo nuevo; compártelo en tus redes sociales o invítame un cafe.
Fabián Vera liked this on Facebook.
Rodrigo Solís liked this on Facebook.
Eze Kiel liked this on Facebook.
Julio Cesar Hernández Ramírez liked this on Facebook.
Orlando Berrones liked this on Facebook.
Esteban Misael liked this on Facebook.
Luis Merlin liked this on Facebook.
Alejandro Vergara liked this on Facebook.
Ricardo Vinicio Castelo Mosquera liked this on Facebook.
Javier Alvarez liked this on Facebook.
Daniel Sepulveda liked this on Facebook.
De pura casualidad tiene información sobre como puedo modificar los valores de una jtable dinámicamente usando hilos?
no mame joveno eso es imposible!!! XD
-_- tu no eres michelle torres…
No tengo información, pero seguro ya has intentando el TableModel.fireTableDataChanged()
Leí sobre el método pero aún no lo utilizo en la implementación. Gracias por el consejo (y)