(Java) Apareciendo / desaparición JLabel en un JPanel solamente desaparece el cambio de tamaño

StackOverflow https://stackoverflow.com/questions/942883

Pregunta

Estoy trabajando en Java, y tengo un JPanel en un JFrame. En ese JPanel, entre otras cosas, tengo un JLabel que yo quiero hacer aparecer y desaparecer a voluntad. He tratado de establecer la visibilidad de verdadero / falso, agregar y quitar desde el JFrame y JPanel, y, después de haber mirado en línea, he intentado validar ing () y revalido () ing ad infinitum. Qué se puede hacer para resolver este problema?

¿Fue útil?

Solución

En general, una llamada al método setVisible es suficiente para hacer que un componente Swing para mostrar u ocultar.

Sólo para estar seguro de que funciona, he intentado lo siguiente:

public class Visibility {
  private void makeGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final JLabel l = new JLabel("Hello");
    final JButton b = new JButton("Hide Label");
    b.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        l.setVisible(false);
      }
    });

    f.getContentPane().setLayout(new BorderLayout());
    f.getContentPane().add(l, BorderLayout.CENTER);
    f.getContentPane().add(b, BorderLayout.SOUTH);
    f.setSize(200, 200);
    f.setLocation(200, 200);
    f.validate();
    f.setVisible(true);
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new Visibility().makeGUI();
      }
    }); 
  }
}

El programa anterior es capaz de afectar a la visibilidad haciendo clic en un JButton.

¿Podría ser un problema de roscar?

Mi próximo sospecha era que tal vez un Thread que no está en la hilo de distribución de eventos (EDT) no puede estar afectando la pantalla inmediatamente, por lo que añade la siguiente después de inicializar la JLabel y JButton.

Thread t = new Thread(new Runnable() {
  public void run() {
    while (true) {
      b.setVisible(!b.isVisible());

      try {
        Thread.sleep(100);
      } catch (InterruptedException e) { /* Handle exception /* }
    }
  }
});

t.start();

Con la nueva ejecución Thread, se cambió el toggled la visibilidad de la JLabel cada 100 ms, y esto también funcionó sin problemas.

Llamar a un componente Swing de la caso hilo de despacho (EDT ) es algo malo, como oscilación no es seguro para subprocesos. Me sorprendió un poco funcionó, y el hecho de que funciona sólo puede ser una casualidad .

Volver a pintar la JPanel?

Si la visibilidad del JLabel solamente está siendo afectada por el cambio de tamaño, probablemente significa que el JLabel se está elaborando sólo cuando se repintó la JPanel.

Una cosa a intentar es la llamada del JPanel repaint método para ver si la visibilidad de la JLabel va a cambiar.

Sin embargo, este método parece ser sólo una tirita a una situación, si la causa principal se debe a un hilo del EDT está tratando de hacer cambios en la interfaz gráfica de usuario. (Así como una nota, el método repaint es thread-safe, por lo que puede ser llamado por hilos fuera de EDT, pero confiando en repaint es una solución de una solución.)

Trate de usar SwingUtilities.invokeLater

Por último, probablemente la cosa me gustaría tratar es la método SwingUtilities.invokeLater , que puede ser llamado (y sólo debería ser llamada) desde un hilo conductor separado de la EDT, si quiere afectar a la GUI.

Así, el ejemplo anterior Thread debe ser escrita como:

Thread t = new Thread(new Runnable() {
  public void run() {
    while (true) {
      try {
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            b.setVisible(!b.isVisible());
          }
        });
      } catch (Exception e1) { /* Handle exception */ }

      try  {
        Thread.sleep(100);
      } catch (InterruptedException e) { /* Handle exception */ }
    }
  }
});

t.start();

Si el cambio a la interfaz gráfica de usuario está ocurriendo de hecho en un hilo separado, entonces recomendaría la lectura Lección: concurrencia de oscilación de Los Tutoriales de Java con el fin de obtener más información sobre cómo escribir bien comportarse multihilo código usando swing.

Otros consejos

setVisible () o la eliminación que debería funcionar bien, asegúrese de que está haciendo desde el thread de despacho de eventos sin embargo. Hay métodos de utilidad en EventQueue para ejecutar bloques en ese hilo.

http: / /helpdesk.objects.com.au/java/how-do-i-update-my-gui-from-any-thread

Usted tendría que llamar revalidate () en las JPanel padres si necesita sus componentes para ser re-trazado.

Si se puede publicar un ejemplo que demuestra el problema que puede tener una mirada en ella para usted.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top