Domanda

sto lavorando in Java, e ho un JPanel in un JFrame. In quel JPanel, tra le altre cose, ho un JLabel che voglio fare apparire e scomparire a suo piacimento. Ho provato a installare visibilità al vero / falso, aggiunta e la rimozione dalla JFrame e JPanel, e, dopo aver guardato online, ho provato validate) ING (e prorogare () ing all'infinito. Cosa si può fare qui per risolvere questo problema?

È stato utile?

Soluzione

In generale, chiamando il metodo setVisible è sufficiente per rendere un componente Swing per essere mostrato o nascosto.

Giusto per essere sicuri che funziona, ho provato quanto segue:

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();
      }
    }); 
  }
}

Il programma di cui sopra è in grado di influenzare la visibilità facendo clic su un JButton.

Potrebbe essere un problema di threading?

Il mio prossimo sospetto era che forse un Thread che non è sulla filo evento dispatch (EDT) non possono essere colpendo immediatamente il display, così ho aggiunto il seguente dopo l'inizializzazione del JLabel e 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 nuova Thread in esecuzione, è cambiato il commutato la visibilità della JLabel ogni 100 ms, e anche questo ha funzionato senza problemi.

Chiamare un componente Swing al largo della evento filo spedizione (EDT ) è una brutta cosa, come swing non è thread-safe. Sono rimasto un po 'sorpreso ha funzionato, e il fatto che funziona può essere solo un colpo di fortuna .

ridipingere il JPanel?

Se la visibilità del JLabel è solo essere colpiti sul ridimensionamento, probabilmente significa che il JLabel è in corso di elaborazione solo quando il JPanel verrà ridipinto.

Una cosa da provare è alla chiamata del JPanel repaint metodo per vedere se la visibilità del JLabel cambierà.

Ma questo metodo sembra essere solo un cerotto ad una situazione, se la causa principale è dovuta ad una discussione fuori dal EDT sta tentando di modificare l'interfaccia grafica. (Proprio come una nota, il metodo repaint è thread-safe, in modo che possa essere chiamato da fili off-EDT, ma basandosi su repaint è una soluzione di una soluzione.)

Provare a utilizzare SwingUtilities.invokeLater

Infine, probabilmente la cosa che vorrei provare è il metodo SwingUtilities.invokeLater , che può essere chiamato (e dovrebbe essere chiamato solo) da un filo conduttore separato dal EDT, se vuole influenzare l'interfaccia grafica.

Quindi, l'esempio Thread in precedenza dovrebbe essere scritto come:

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();

Se la modifica alla GUI è infatti in corso su un thread separato, quindi mi sento di raccomandare la lettura di Lezione: Concurrency in swing da Java Tutorial al fine di trovare ulteriori informazioni su come scrivere ben comportarsi multi-threaded codice utilizzando swing.

Altri suggerimenti

setVisible () o la rimozione dovrebbe funzionare bene, assicurarsi che si sta facendo dal thread spedizione evento però. Ci sono metodi di utilità in EventQueue per l'esecuzione di blocchi in questo thread.

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

Si avrebbe bisogno di chiamare revalidate () sulle JPanel genitore se è necessario i suoi componenti di essere ri-definito.

Se è possibile postare un esempio che illustra il problema che può avere uno sguardo esso per voi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top