Ho una semplice app JavaFX 2, con 2 pulsanti, che dice Start e Stop. Quando si fa clic sul pulsante di avvio, voglio creare un thread in background che eseguirà un po 'di elaborazione e aggiornerà l'interfaccia utente (ad esempio una barra di avanzamento) mentre procede. Se si fa clic sul pulsante stop, voglio che il thread termini.Multithreading in JavaFX si blocca l'interfaccia utente
Ho provato a farlo utilizzando la classe javafx.concurrent.Task
che ho raccolto dalla documentazione funzionerebbe bene per questo. Ma ogni volta che faccio clic su Start, l'interfaccia utente si blocca/si blocca piuttosto che rimanere normale.
Il suo è il codice dalla principale Myprogram extends Application
classe per mostrare i tasti:
public void start(Stage primaryStage)
{
final Button btn = new Button();
btn.setText("Begin");
//This is the thread, extending javafx.concurrent.Task :
final MyProcessor handler = new MyProcessor();
btn.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
handler.run();
}
});
Button stop = new Button();
stop.setText("Stop");
stop.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
handler.cancel();
}
}
);
// Code for adding the UI controls to the stage here.
}
Ecco il codice di MyProcessor
classe:
import javafx.concurrent.Task;
public class MyProcessor extends Task
{
@Override
protected Integer call()
{
int i = 0;
for (String symbol : feed.getSymbols())
{
if (isCancelled())
{
Logger.log("Stopping!");
return i;
}
i++;
Logger.log("Doing # " + i);
//Processing code here which takes 2-3 seconds per iteration to execute
Logger.log("# " + i + ", DONE! ");
}
return i;
}
}
Abbastanza semplice, ma l'interfaccia utente si blocca ogni volta che si fa clic sul pulsante Start pulsante, anche se i messaggi della console continuano a essere visualizzati (Logger.log
semplicemente System.out.println
)
Cosa sto sbagliando?
Non posso ringraziarvi abbastanza amico. –
Ho ancora una domanda. Voglio aggiornare un'etichetta nell'interfaccia utente principale con lo stato del thread dell'attività. Per questo vorrei usare questo codice nel task: 'mainProg.updateStatus (i);', e nel programma principale: 'public void updateStatus (int i) {this.label.setText (i)); } '. Funzionerebbe, o dovrei usare 'platform.runLater()' da 'MainProg.updateStatus()' per aggiornare l'interfaccia utente? –
Sì, avresti bisogno di eseguirlo nel thread UI con runLater - In alternativa, puoi usare il metodo updateProgress (vedi esempio 3 nel tutorial) che verrà eseguito nel thread dell'interfaccia utente. – assylias