Mostrando entradas con la etiqueta Swing. Mostrar todas las entradas
Mostrando entradas con la etiqueta Swing. Mostrar todas las entradas

miércoles, 10 de julio de 2013

Referencia a la clase contenedora en una clase anónima

Al programar interfaces gráficas, es muy habitual el uso de clases anónimas para definir el listener de algún componente.

JButton button = new JButton("OK");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
   System.out.println("Ok!");
}});      
 
Tampoco es raro que desde la clase anónima, queramos acceder a algún elemento de la clase contenedora. En ese caso, podemos vernos tentados de usar this; pero, obviamente, si estamos dentro de la clase anónima, this hará referencia a la instancia de esa clase, no a la de la contenedora.

En este caso podemos usar como alternativa ClaseContenedor.this, quedando algo así.

public class ClaseContenedora extends JPanel{
   int value = 0;

   public ClaseContenedora() {
      ...

      JButton button = new JButton("OK");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e)
         {
            ClaseContenedora.this.value++;
         }});    

      ...
   } 
}

miércoles, 12 de junio de 2013

Key Adapter y JPanel

El método addKeyListener de la clase Component de Swing nos permite agregar oyentes de teclado a cualquier componente. Por tanto, si estamos creando un JPanel, perfectamente podríamos intentar hacer algo así:

public class MyPanel extends JPanel {

public MyPanel() {
MyKeyAdapter keyAdapter = new MyKeyAdapter();
this.addKeyListener(keyAdapter);
}
...
}

Siendo MyKeyAdapter algo de este estilo.

public MyKeyAdapter extends KeyAdapter {

public void onKeyPressed(KeyEvent event) {
...
}

...
}

Pero si probamos este código, nos encontramos que por más que aporreemos el teclado, los eventos no se lanzan. El motivo es simple. Los eventos de teclado se lanzan siempre sobre el elemento de la interfaz que tiene el foco, y los JPanel, por defecto, no son enfocables (focusables). Así que una solución rápida al problema sería hacer el JPanel focusable de la siguiente manera.

public MyPanel() {
this.setFocusable(true);

MyKeyAdapter keyAdapter = new MyKeyAdapter();
this.addKeyListener(keyAdapter);
}
...
}

Ahora, al hacer click sobre el panel, ganará el foco. Si queremos dárselo desde algún rincón de nuestro código, también podemos hacerlo con la llamada panel.requestFocus().

martes, 30 de noviembre de 2010

Tutorial de Swing Application Framework publicado en JavaHispano

La Asociación JavaHispano ha tenido el detalle de publicar un tutorial que he realizado en el que se desarrolla una pequeña aplicación utilizando el Swing Application Framework.

Este framework, desarrollado en la JSR-296, proporciona la infraestructura necesaria para la construcción de aplicaciones de escritorio con Java, incluyendo:

- Ciclo de vida
- Gestión de recursos (mensajes, imágenes, fuentes de texto...)
- Acciones
- Sesión (permite guardar el estado de la aplicación entre ejecuciones)

Actualmente la JSR se encuentra inactiva, por lo que el framework tal cual está condenado a morir. Sin embargo, creo que en su última versión ofrece suficientes cosas como para ser una buena opción a la hora de empezar a trabajar con Swing; y, por otro lado, la idea de crear un framework para esta tecnología sí sigue viva, y seguirá desarrollándose, seguro, en nuevos proyectos que partirán de SAF. Como muestra, Better SAF o guts-gui.

En esta página de JavaHispano podéis descargar el tutorial.

Muchas gracias a JavaHispano, y en concreto a Peyrona, Leonardo, Isaac, y revisor1 por su colaboración, y por haber mejorado sustancialmente el resultado final.

jueves, 22 de julio de 2010

Cómo forzar el salto de línea (wrap) en un JLabel

Un post rápido y sencillo.

En algunas ocasiones, por el motivo que sea, utilizamos el componente JLabel para mostrar mensajes cuyo tamaño no conocemos en tiempo de desarrollo. En estos casos nos podemos encontrar con que el ancho que hemos dado al campo no es suficiente para recoger todo el texto.

Se nos puede ocurrir como solución ampliar la altura, pero si simplemente hacemos eso veremos que la línea no se rompe al llegar al final del componente, por lo que no conseguimos resolver el problema.

Pero no hay que preocuparse, porque la solución es muy simple, ya que con añadir etiquetas html al texto obtendremos el efecto que necesitamos.


miércoles, 19 de mayo de 2010

Net Beans no actualiza los ficheros de propiedades trabajando con Swing Application Framework

Hoy me he encontrado un pequeño problema al trabajar con Net Beans 6.8 realizando una aplicación de escritorio con Swing Application Framework. Un error que no es grave, pero que puede producir grandes niveles de frustración si no se da con la tecla.

Normalmente, trabajando con este entorno, tenemos nuestros paneles Swing enlazados con ficheros de propiedades en los que se definen los textos para nuestros componentes. Net Beans se encarga de ir actualizando los ficheros de propiedades, haciendo muy cómodo el trabajo.

Hasta ahí todo bien, pero, ¿qué pasa si renombramos un panel con la opción rename del IDE? En principio todo parece correcto: se cambia el nombre de la clase, se actualizan todas las referencias, el proyecto sigue compilando... Si seguimos trabajando con nuestro panel todo parecerá ser correcto. Podemos agregar nuevos controles o modificar sus textos y el editor se actualiza, pero... al ejecutar salta la sorpresa. Los nuevos controles no tienen texto, los modificados no se han actualizado... ¿qué he hecho para merecer esto?

Si nos vamos al fichero de propiedades, veremos que, efectivamente, los últimos cambios en el editor gráfico no se han visto reflejados. Lógicamente podemos modificar los que queremos directamente en este fichero, pero, por algún extraño motivo, la sincronización desde el editor gráfico hacia el .properties se ha perdido. ¿¿Por qué?? Pues la verdad es que no lo sé. He revisado todo lo que se me ha ocurrido sin encontrar una respuesta, pero sí una solución. Basta con cerrar el panel que hemos renombrado y volver a abrirlo para que todo vuelva a funcionar como siempre.

Este fallo tiene dos grandes problemas. Uno es que cuando caes en la cuenta de que los ficheros de propiedades no se están actualizando, lo más probable es que no seas capaz de encontrar la causa, ya que puede que haga mucho tiempo que renombraste el panel, y te pases un buen rato revisando tu código sin suerte. El otro es que luego hay que tener la ocurrencia de recurrir al "reset" (cerrar y abrir la clase) para que todo vuelva a la normalidad.

Un pequeño error más que anotarle a este IDE trabajando con SAF.