Ich habe eine einfache JavaFX 2 App, mit 2 Tasten, sagen Start und Stop. Wenn der Startknopf angeklickt wird, möchte ich einen Hintergrundthread erstellen, der einige Verarbeitungsschritte ausführt und die Benutzeroberfläche (z. B. einen Fortschrittsbalken) aktualisiert, während sie weiterläuft. Wenn der Stop-Button angeklickt wird, möchte ich den Thread beenden.Multithreading in JavaFX hängt die UI
Ich habe versucht, dies zu tun mit der javafx.concurrent.Task
Klasse, die ich aus der Dokumentation gesammelt würde funktionieren gut für diese. Aber immer, wenn ich auf Start klicke, bleibt die Benutzeroberfläche hängen, anstatt normal zu bleiben.
ist ihr der Code von der Haupt Myprogram extends Application
Klasse für die Tasten zeigt:
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.
}
Hier ist der Code von MyProcessor
Klasse:
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;
}
}
Ziemlich einfach, aber die UI hängt, wenn ich den Start klicken Taste, obwohl die Konsolenmeldungen weiterhin angezeigt werden (Logger.log
tut einfach System.out.println
)
Was mache ich falsch?
Ich kann dir nicht genug Kumpel danken. –
Ich habe noch eine Frage. Ich möchte ein Label in der Hauptbenutzeroberfläche mit dem Fortschritt des Task-Threads aktualisieren. Dazu würde ich diesen Code in der Task 'mainProg.updateStatus (i);' verwenden und im Hauptprogramm 'public void updateStatus (int i) {this.label.setText (i)); } '. Würde das funktionieren, oder sollte ich 'platform.runLater()' von 'MainProg.updateStatus()' zum Aktualisieren der UI verwenden? –
Ja, Sie müssten es im UI-Thread mit runLater ausführen - Alternativ können Sie die updateProgress-Methode verwenden (siehe Beispiel 3 im Lernprogramm), die im UI-Thread ausgeführt wird. – assylias