public void ejecutaDespues() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Hacer algo.
}
});
}
Mostrando entradas con la etiqueta Swing. Mostrar todas las entradas
Mostrando entradas con la etiqueta Swing. Mostrar todas las entradas
jueves, 6 de marzo de 2008
Tareas en Segundo Plano (Swing)
Algunas ocasiones necesitas poner una tarea en especial a ajecutarse cuando halla tiempo, es decir, no en este momento o simplemente que espere a que los recursos esten disponibles para poder dar a otra tarea más importante algo de tiempo. Realizar esto en entornos Swing es bastante simple con la clase SwingUtils. El código es sencillo:
martes, 7 de agosto de 2007
Algo de JTables pa' variar
Bueno, los JTables pueden llegar a se un poco enigmaticos, y hacer que las cosas pasen con ellos a veces resulta un poco díficil, pero con un poco de práctica podemos hacer un buen de cosas con el. Para empezar vamos a ver una manera sencilla de crear un mapeo entre una clase POJO (Plan Old Java Object, Objeto Java Sencillo y Jodido), y lo utilizamos para mostrarlo desde una base de datos a un JTable. Es algo sencillo en realidad. Pero para lograrlo necesitamos una nuevla clase del conjunto Swing, esta clase se llama TableModel y es una interfaz que permite decirle a un JTable que presentar en una tabla. Vamos por ejemplo.
Una vez que tenemos un TableModel podemos crear una Tabla con los datos que tiene el modelo mismo.
Ahora, un TableModel puede servir para hacer muchas cosas, por ejemplo, podemos filtrar los datos de uno de ellos por medio de otro, a esto se le conoce como Decorator.
Una forma sencilla de hacer las cosas.
Chaito sres...
//AbstractTableModel implementa TableModel y la mayoría de sus métodos
class TModelo extends AbstractTableModel {
private ArrayList lista;
//Cargamos los datos a una lista de POJO's
public TModelo(ResultSet rs) {
try {
rs.first();
do {
POJO pojo = new POJO();
pojo.campo1 = rs.getString(1);
pojo.campo2 = rs.getInteger(2);
pojo.campo3 = rs.getString(3);
lista.add(pojo);
} while(rs.next());
} catch(Exception e) { ; }
}
//Indicar cuantas filas va a tener la tabla
public int getRowCount() { return lista.size(); }
//Indicar cuantas columnas va a tener la tabla. El numero de campos en este caso
public int getColumnCount() { return 3; }
//Objeto en cada celda
public Object getValueAt(int fila, int columna) {
try {
POJO pojo = (POJO) lista.get(fila);
if(columna == 0)
return pojo.campo1;
if(columna == 1)
return new Integer(pojo.campo2);
if(columna == 2)
return pojo.campo3;
} catch(Exception e) {
//Regresamos un valor vacio por si las moscas
return "";
}
}
//nombre de las columnas
public String getColumnName(int col) {
if(columna == 0) return "Campo 1";
if(columna == 1) return "Campo 2";
if(columna == 2) return "Campo 3";
}
//Indicamos si determinada celda es editable
public boolean isCellEditable(int f, int c) {
return false;
}
}
//Una clase POJO muy sencilla
//Esto no deberia hacerse, deberiamos usar geters y seters
class POJO {
public String campo1;
public int campo2;
public String campo3;
}
Una vez que tenemos un TableModel podemos crear una Tabla con los datos que tiene el modelo mismo.
JTable tabla = new JTable(new TModelo(rs));
JFrame fra = new JFrame();
//Si se agrega la tabla de manera directa entonces no se muestran los encabezados
fra.add(new JScrollPane(tabla));
Ahora, un TableModel puede servir para hacer muchas cosas, por ejemplo, podemos filtrar los datos de uno de ellos por medio de otro, a esto se le conoce como Decorator.
class FilterModel extends AbstractModel {
private TableModel original;
private ArrayList pasan = new ArrayList();
public FilterModel(TableModel tm) {
original = tm;
}
//Implementamos un filtro sencillo para un solo campo sobre el modelo anterior
public void filtra(String valor) {
//Quitamos todo
pasan.clear();
//Filtramos cada valor y ponemos los que coinciden con el valor
for(int i = 0; i < original.getRowCount(); i++)
if(("" + original.getValueAt(i, 1)).indexOf(valor) != -1)
pasan.add(new Integer(i));
}
public String getColumnName(int c) { return original.getColumnName(c); }
public int getColumnCount() { return original.getColumnCount(); }
public int getRowCount() { return pasan.size(); }
public Object getValueAt(int f, int c) {
int real = ((Integer) pasan.get(f)).intValue();
return original.getValueAt(real, c);
}
}
Una forma sencilla de hacer las cosas.
Chaito sres...
miércoles, 1 de agosto de 2007
Haciendo Frames Internos
En Java lo más parecido que hay a un formulario MDI son los Frames Internos, estos son miniventanas que se pegan a una ventana marcada como JDesktopPane como contenedor principal, y deben agregarse a estos.
Vamos a ver como funcionan de manera general estas cosas raras:
Ahora, algunas veces puedes querer que un InternalFrame no pueda cerrarse o dejarse mientras estemos usandolo. Esto en realidad no se puede hacer de manera sencilla; pero usando listeners podemos equilibrar las cosas. Vamos a ver como crear un JInternalFrame que funciona de cierta manera como una ventan modal:
Esa es una forma rápida de hacer que las cosas funcionen de la manera que no deberían hacerlo. Si lo que estan buscando es una forma de mostrar dialogos Internos no hay más que reemplazar los métodos showXXXXDialog de JOptionPane por showInternalXXXXDialog.
Vamos a ver como funcionan de manera general estas cosas raras:
JFrame padre = new JFrame("Varios Frames internos");
JDesktopPane jdp = new JDesktopPane();
padre.setContentPane(jdp);
//Crea un Frame interno que no puede cambiar su tamaño, puede cerrarse, no puede
//maximizarse y puede minimizarse. Los parametros son aleatorios y en ese orden.
JInternalFrame jif = new JInternalFrame("Titulo", false, true, false, true);
jif.pack();
jif.setVisible();
//Después ponemos el elemento en el frame
jdp.add(jif);
Ahora, algunas veces puedes querer que un InternalFrame no pueda cerrarse o dejarse mientras estemos usandolo. Esto en realidad no se puede hacer de manera sencilla; pero usando listeners podemos equilibrar las cosas. Vamos a ver como crear un JInternalFrame que funciona de cierta manera como una ventan modal:
JInternalFrame jif = new JInternalFrame();
jif.addInternalFrameListener(new InternalFrameAdapter() {
public void internalFrameIconified(InternalFrameEvent e) {
((JInternalFrame) e.getSource()).setVisible(true);
}
public void internalFrameDeactivated(InternalFrameEvent e) {
((JInternalFrame) e.getSource()).setVisible(true);
}
});
Esa es una forma rápida de hacer que las cosas funcionen de la manera que no deberían hacerlo. Si lo que estan buscando es una forma de mostrar dialogos Internos no hay más que reemplazar los métodos showXXXXDialog de JOptionPane por showInternalXXXXDialog.
martes, 31 de julio de 2007
Listeners
La plataforma Swing se basa primordialmente para el manejo de eventos en el concepto de escucha o Listener; la teoría general establece que existe un objeto al que llamaremos disparador que realiza alguna acción sobre otro objeto reactivo. El objeto entonces informa a varios Listener de que algo ha ocurrido en el disparador. Entonces cada uno de los listeners puede realizar alguna acción en base al evento que ocurrió.
La metáfora que utilizaremos para comprender el concepto es mas o menos el siguiente: Imagina que tenemos un sistema que mide la temperatura del ambiente, este sistema puede conectarse con multiples sistemas independientes; imaginemos entonces que podemos conectar un aparato que pite cada que la temperatura rebase cierto limite, además podemos conectar otro aparato que actualize la temperatura en un sitio Web cada que esta cambie, y podemos conectar más aparatos que realizen funciones diferentes, siempre y cuando sean capaces de saber cuando la temperatura cambia.
Entre los componentes Swing hay una amplia gama de Listener's que se implementan como Interfaces, si queremos que determinada clase responda a los eventos de un objeto es necesario que este implemente la interface Listener adecuada y que se registre con el objeto que genera los reportes de evento. El ejemplo más sencillo es el de los botones comunes y la interfaz ActionListener.
Algunos elementos pueden llegar a tener multiples interfaces para utilizar Listeners, como el caso de los JFrame's, que permiten recibir WindowListener, FrameListener, PropertyChangeListener, MouseListener, MouseMotionListener entre otros. En la documentación de Java pueden encontrarse bastantes referencias a los listeners que acepta cada uno de los componente Swing.
Existen casos de Listeners que declaran muchos métodos, como el caso del WindowListener que implementa windowClosed, windowClosing, windowIconofied, y otros muchos, estos métodos deben cubrirse completamente en cualquier clase que implemente la interfaz, pero para facilitar las cosas por cada una de estas clases existe una clase Adapter que implementa una funcionalidad vacia en todos estos métodos.
La metáfora que utilizaremos para comprender el concepto es mas o menos el siguiente: Imagina que tenemos un sistema que mide la temperatura del ambiente, este sistema puede conectarse con multiples sistemas independientes; imaginemos entonces que podemos conectar un aparato que pite cada que la temperatura rebase cierto limite, además podemos conectar otro aparato que actualize la temperatura en un sitio Web cada que esta cambie, y podemos conectar más aparatos que realizen funciones diferentes, siempre y cuando sean capaces de saber cuando la temperatura cambia.
Entre los componentes Swing hay una amplia gama de Listener's que se implementan como Interfaces, si queremos que determinada clase responda a los eventos de un objeto es necesario que este implemente la interface Listener adecuada y que se registre con el objeto que genera los reportes de evento. El ejemplo más sencillo es el de los botones comunes y la interfaz ActionListener.
JButton boton = new JButton("El boton");
//ActionListener es la clase encargada de escuchar eventos de acción
ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.out.println("Se ha hecho click en el botón");
}
}
boton.addActionListener(al);
//Registramos el nuevo objeto como escucha del botón
JButton boton2 = new JButton("Otro boton");
//Podemos agregar un Listener a varios elementos
boton2.addActionListener(al);
//E igualmente podemos registrar mas de un listener por objeto
boton.addActionListener(otro_listener);
//Borramos el registro de escucha cuando deja de interesarnos
boton.removeActionListener(al);
Algunos elementos pueden llegar a tener multiples interfaces para utilizar Listeners, como el caso de los JFrame's, que permiten recibir WindowListener, FrameListener, PropertyChangeListener, MouseListener, MouseMotionListener entre otros. En la documentación de Java pueden encontrarse bastantes referencias a los listeners que acepta cada uno de los componente Swing.
Existen casos de Listeners que declaran muchos métodos, como el caso del WindowListener que implementa windowClosed, windowClosing, windowIconofied, y otros muchos, estos métodos deben cubrirse completamente en cualquier clase que implemente la interfaz, pero para facilitar las cosas por cada una de estas clases existe una clase Adapter que implementa una funcionalidad vacia en todos estos métodos.
//Usando el adapter nos evitamos escribir todos los métodos
WindowListener wl = new WindowAdapter() {
public void windowClosed(WindowEvent we) {
System.out.println("Se cerro la ventana");
}
}
lunes, 30 de julio de 2007
Look And Feel
Java ofrece funcionalidades para cambiar la forma en la que se muestran las ventanas que conforman un sistema, cada parte del sistema completo puede verse como si se encontrara en otro sistema operativo o bien con un esquema gráfico diferente. Por medio de esta herramienta podemos hacer que los desarrollos Java luzcan visualmente como si se hubieran realizado en un lenguaje común, como VB; o ejecutado desde un sistema operativo cualquiera y verse como un Mac o un Windows.
Para establecer el LookAndFeel de un sistema de ventanas se usa código como el siguiente:
Los LookAndFeel más comunes en Java son los siguientes:
Pueden encontrarse en Internet varios LookAndFeel que pueden mejorar en gran medida nuestra aplicación de manera muy sencilla.
Una nota final: el LookAndFeel se aplica de manera general a las ventanas existentes y las futuras ventanas, y todas las ventanas que existan hasta que se cambie el LookAndFeel.
Para establecer el LookAndFeel de un sistema de ventanas se usa código como el siguiente:
try {
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} cactch(Exception e) {
//No es posible cambiar el Look and Feel;
}
Los LookAndFeel más comunes en Java son los siguientes:
| Clase | LookAndFeel |
|---|---|
| javax.swing.plaf.metal.MetalLookAndFeel | LookAndFeel de Java |
| com.sun.java.swing.plaf.gtk.GTKLookAndFeel | GTK+ (Solaris normal) |
| com.sun.java.swing.plaf.motif.MotifLookAndFeel | Motif (Linux viejitos) |
| com.sun.java.swing.plaf.windows.WindowsLookAndFeel | LookAndFeel normal de Windows (No lo recomiendo) |
Pueden encontrarse en Internet varios LookAndFeel que pueden mejorar en gran medida nuestra aplicación de manera muy sencilla.
Una nota final: el LookAndFeel se aplica de manera general a las ventanas existentes y las futuras ventanas, y todas las ventanas que existan hasta que se cambie el LookAndFeel.
viernes, 27 de julio de 2007
Menús
El manejo de los menús en Swing se realiza por medio de las clases JMenu, JMenuBar, JCheckBoxMenuItem, JMenuItem, JRadioMenuItem y JPopupMenu. De la misma forma es necesario iniciar con el manejo de los Actions para poder reutilizar eventos a travez del sistema.
Para crear un menú regular necesitamos un objeto JFrame o JInternalFrame para poner en el el menú. Primeramente agregamos un elemento JMenuBar para poder pegar ahi el menú y dentro de el elementos JMenu, y JMenuItem o una de sus subclases en el interior.
Bueno, esta es la teoría general de los menús, cada uno de los menús puede personalizarse en base a Actions, los actions son elementos que definen como se realiza un determinado proceso, le asignan un nombre y una imagen, lo que lo hace facilmente reutilizable en otros entornos; en este caso hablamos de un patron conocido como Comand, donde el elemento action define como se realiza una operación y puede ser establecido en multiples elementos sin problemas, por ejemplo un botón, un elémento de menú, un espacio de una barra de herramientas etc.
Para crear Actions generalmente se extiende la clase AbstractAction de una manera mas o menos así:
Con este modelo tanto el boton como el menu comparten el mismo texto y el mismo funcionamiento, lo que hace más fácil reutilizar esta funcionalidad en el sistema. Pero la reutilización de un Action va un poco mas alla, cuando utilizamos un action este establece más propiedades que puden visualizarse en otro elementos. Esto suele establecerse en el constructor de la clase Action por medio del método putValue(clave, valor).
Dependiendo del tipo de control del que se este hablando podemos reutilizar las funcionalidades de las claves anteriores.
Para crear un menú regular necesitamos un objeto JFrame o JInternalFrame para poner en el el menú. Primeramente agregamos un elemento JMenuBar para poder pegar ahi el menú y dentro de el elementos JMenu, y JMenuItem o una de sus subclases en el interior.
JFrame ventana = new JFrame("Ejemplo de menus");
JMenuBar barra = new JMenuBar();
//Ponemos el menu en Vertical
barra.add(Box.createVerticalGlue());
JMenu archivo = new JMenu("Archivo");
JMenuItem guardar = new JMenuItem("Guardar");
archivo.add(archivo);
archivo.addSeparator();
ventana.setMenuBar(barra);
Bueno, esta es la teoría general de los menús, cada uno de los menús puede personalizarse en base a Actions, los actions son elementos que definen como se realiza un determinado proceso, le asignan un nombre y una imagen, lo que lo hace facilmente reutilizable en otros entornos; en este caso hablamos de un patron conocido como Comand, donde el elemento action define como se realiza una operación y puede ser establecido en multiples elementos sin problemas, por ejemplo un botón, un elémento de menú, un espacio de una barra de herramientas etc.
Para crear Actions generalmente se extiende la clase AbstractAction de una manera mas o menos así:
class SalirAction extends AbstractAtion {
public SalirAction(ImageIcon imagen) {
super("Texto", imagen);
}
public static void actionPerformed(ActionEvent ae) {
System.exit(0);
}
}
Action salir = new SalirAction(imagen);
JButton btnSalir = new JButton(salir);
JMenuItem mnuSalir = new JMenuItem(salir);
Con este modelo tanto el boton como el menu comparten el mismo texto y el mismo funcionamiento, lo que hace más fácil reutilizar esta funcionalidad en el sistema. Pero la reutilización de un Action va un poco mas alla, cuando utilizamos un action este establece más propiedades que puden visualizarse en otro elementos. Esto suele establecerse en el constructor de la clase Action por medio del método putValue(clave, valor).
public SalirAction(ImageIcon imagen) {
super("Texto", imagen);
putValue(SHORT_DESCRIPTION, "Tool Tip Text del control que contenga al action");
putValue(NAME, "Nombre del Action");
//Estableces la acción en respuesta a CTRL + A
putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
putValue(LONG_DESCRIPTION_KEY, "Descripción larga");
putValue(LARGE_ICON_KEY, imagenGrande);
putValue(SMALL_ICON, imagenChica);
//Establece el nemonico del action a N
putValue(MNEMONIC_KEY, new Integer(KeyEvent.VK_N));
//Se establece el estado seleccionado del action
putValue(SELECTED_KEY, Boolean.TRUE);
}
Dependiendo del tipo de control del que se este hablando podemos reutilizar las funcionalidades de las claves anteriores.
jueves, 26 de julio de 2007
Introducción a Swing
El paquete más comunmente utilizado en Java para crear interfaces gráficas es el paquete Swing, este contiene una serie de controles que se puede utilizar pero Swing ws un poco más que solamente controles:
- Controles GUI para presentación en pantalla.
- La interfaz Java2D para dibujo en formularios.
- Look & Feel's intercambiables.
- Control de operaciones de transferencia (Copiar, Pegar)
- Registro de acciones deshacibles.
- Soporte UNICODE.
- Accesibilidad.
- Action. Action es una clase que engloba cualquier acción que se pueda realizar en el sistema, lo que debería pasar cuando ocurre un evento. Un elémento Action se comporta de manera completamente independiente de sus contenedores, así que podemos hacer que un mismo Actión se corresponda con muchos controles.
- Listener. El control de eventos en Java se basa en el concepto de escucha o Listener, un escucha es una clase que implementa determinada interfaz de eventos, cuando un objeto dispara un evento utiliza esta interfaz para comunicar a todos los objetos escuchas de que algo ha ocurrido en el. Utilizando los Listeners podemos crear clases de control de multiples elementos o bien tener más de un controlador de evento para un solo control.
- Model. Un Model define la manera en la que se van a presentar los datos dentro de un control determinado. La mayoría de las funcionalidades de un Model permiten que los datos sean alterados en la manera que se visualizan sin, necesariamente, modificar los datos mismos.
Suscribirse a:
Entradas (Atom)