Oscillazione: Non può ottenere JButton per l'aggiornamento - repaint () non funziona
-
13-09-2019 - |
Domanda
Sto usando swing per la prima volta per creare una semplice interfaccia grafica. Si compone di un JFrame
su cui ho messo un singolo JButton
che, una volta cliccato, chiama qualche altro codice che dura circa. 3 secondi per tornare.
Proprio prima della chiamata a questo codice, in actionPerformed()
, voglio aggiornare il testo sul pulsante per informare l'utente che è in corso di elaborazione. Il mio problema è che il testo sul pulsante non aggiorna fino a dopo la 3-seconda chiamata è tornato. Voglio che il testo aggiornato di essere presenti durante la chiamata, poi cambierò di nuovo in seguito.
Calling repaint()
sul JButton
non fa nulla e chiamandolo sui risultati JFrame
in "Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
" essere gettato quando si fa clic sul pulsante.
Soluzione
Quello che sta succedendo è che il codice di 3 secondi viene eseguito nel thread GUI, in modo che il pulsante non hanno la possibilità di aggiornare finché non è finito.
Per risolvere questo problema, avviare una SwingWorker
per fare l'operazione di lunga durata; allora sarete ancora libero di fare le cose nella GUI mentre siete in attesa per esso.
Qui ci sono un paio di tutorial sull'argomento, e le Javadocs SwingWorker
fa riferimento sopra avere un po 'di codice anche .
Codice di esempio
public void actionPerformed(ActionEvent e) {
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
@Override
public Void doInBackground() {
// Call complicated code here
return null;
// If you want to return something other than null, change
// the generic type to something other than Void.
// This method's return value will be available via get() once the
// operation has completed.
}
@Override
protected void done() {
// get() would be available here if you want to use it
myButton.setText("Done working");
}
};
myButton.setText("Working...");
worker.execute();
}
Altri suggerimenti
Il problema qui è che il vostro compito lungo in esecuzione sta bloccando il filo che normalmente dipingere la GUI.
Il solito modo intorno a questo è quello di gettare il compito duri più a lungo fuori in un altro thread.
Questo può essere fatto abbastanza facilmente utilizzando un SwingWorker
.
Questa domanda può fornire alcune informazioni utili come bene.