2010-01-01 23 views
5

Tengo un montón de botones en mi JToolBar, y configuré algunos de ellos para ser deshabilitados o habilitados dependiendo del estado de mi aplicación. Cuando actualizo varios botones a la vez, descubro que no están repintados al mismo tiempo. Quiero asegurarme de que cuando configure un número de botones para que sean deshabilitados/habilitados, todos cambien de estado al mismo tiempo.¿Puedo agregar algunas actualizaciones de componentes de Swing para que las reparaciones se hagan todas a la vez?

A continuación se muestra una pequeña prueba que demuestra el problema. (Necesita un archivo a.png en el directorio actual para usar como un ícono de botón.) Cuando lo ejecuta, se muestra una barra de herramientas con 10 botones. Presionar Enter en la terminal alternará el estado desactivado de todos los botones. En mi máquina al menos, cada vez que hago esto, los botones se repintan en un orden aparentemente aleatorio, y no todos a la vez.

Parece que el doble buffer podría resolver el problema, aunque lo primero que intenté (configurar doble buffering en el JToolBar) no pareció afectar nada.

Gracias,

Cameron

import java.awt.*; 
import javax.swing.*; 
import java.io.*; 
import java.util.*; 

public class Test { 
    public static void main(String[] args) throws IOException { 
     final JButton[] bs = new JButton[10]; 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       JFrame f = new JFrame("test"); 
       JToolBar t = new JToolBar(); 
       f.getContentPane().add(t); 
       for (int i = 0; i < bs.length; i++) { 
        bs[i] = new JButton(new ImageIcon("a.png")); 
        t.add(bs[i]); 
       } 
       f.pack(); 
       f.setVisible(true); 
      } 
     }); 
     BufferedReader r = new BufferedReader(new InputStreamReader(System.in)); 
     for (;;) { 
      r.readLine(); 
      EventQueue.invokeLater(new Runnable() { 
       public void run() { 
        for (JButton b : bs) { 
         b.setEnabled(!b.isEnabled()); 
        } 
       } 
      }); 
     } 
    } 
} 

Respuesta

2

Siempre que los cambios de estado de habilitación se produzcan en una ejecución de subproceso de evento, suceden de modo que nada puede ir allí en un estado no válido. ¿Entonces supongo que esto es solo un problema de pintura? ¿Se ve mal?

Una forma posible de cambiar el comportamiento es agregar una llamada de nuevo para el contenedor (la barra de herramientas por ejemplo) para que se repinte una mayor área a la vez en lugar de volver a pintar cada botón por separado.

1

me da buenos resultados usando JDK6 en XP.

No veo ningún problema con su código. He habilitado/deshabilitado más componentes que eso a la vez sin ningún problema.

¿Es el problema porque está aceptando la entrada del terminal? Intente agregar un botón separado a su marco de modo que al hacer clic en él se modifique el estado de los botones.

0

@camickr Estoy en JDK6 en Windows 7. Inicié los cambios con EventQueue.invokeLater() porque en mi aplicación, lo que causa que los botones de la barra de herramientas necesiten actualizar el estado ocurre en otro hilo, entonces uso EventQueue .invokeLater() allí. Traté de hacer todo desde el EDT (es decir, haciendo las llamadas a setEnabled() desde un ActionListener en uno de los botones) pero todavía tenía el mismo repinte extraño.

@iny Correcto, simplemente se ve mal. De hecho, pensé que debido a que todos los cambios de estado ocurren dentro de un EventQueue Runnable, toda la pintura ocurriría una vez que finalizara, pero supongo que no. Su sugerencia de llamar a repaint() en JToolBar fusionó toda la pintura de los botones, ¡gracias! (Una vez que se fusionen mi cuenta no registrada (a la que no puedo volver) y mi cuenta recientemente registrada, aceptaré su respuesta.)

Cuestiones relacionadas