我有一个简单的JavaFX 2应用程序,带有2个按钮,表示启动和停止。当单击开始按钮时,我想要创建一个后台线程,它将执行一些处理并更新UI(例如进度条)。如果点击了停止按钮,我希望线程终止。JavaFX中的多线程挂起UI
我试图做到这一点,使用javafx.concurrent.Task
类,我从文档中收集的工作将很好。但是,每当我点击开始,用户界面冻结/挂起,而不是保持正常。
她是从主Myprogram extends Application
类的代码显示的按钮:
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.
}
这里的MyProcessor
类的代码:
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;
}
}
很简单,但每当我点击启动UI挂起按钮,尽管控制台消息继续显示(Logger.log
只是做System.out.println
)
我在做什么错?
我不能感谢你足够的队友。 –
我还有一个问题。我想用任务线程的进度更新主UI中的标签。为此,我将在任务中使用此代码:'mainProg.updateStatus(i);',并在主程序中:'public void updateStatus(int i){this.label.setText(i)); }'。这会工作吗,还是应该使用'MainProg.updateStatus()'中的'platform.runLater()'来更新UI? –
是的,您需要在UI线程中使用runLater运行它 - 或者,您可以使用updateProgress方法(请参阅教程中的示例3),它将在UI线程中运行。 – assylias