问题描述
我有一个简单的 JavaFX 2 应用程序,有 2 个按钮,分别是启动和停止.单击开始按钮时,我想创建一个后台线程,该线程将进行一些处理并在执行过程中更新 UI(例如进度条).如果单击停止按钮,我希望线程终止.
I have a simple JavaFX 2 app, with 2 buttons, saying Start and Stop. When the start button is clicked, I want to create a background thread which will do some processing and update the UI (e.g a progress bar) as it goes along. If the stop button is clicked, I want the thread to terminate.
我已经尝试使用从文档中收集的 javafx.concurrent.Task
类来做到这一点,它可以很好地解决这个问题.但是每当我单击开始"时,UI 都会冻结/挂起,而不是保持正常.
I've tried to do this using the javafx.concurrent.Task
class which I gathered from the documentation would work fine for this. But whenever I click Start, the UI freezes/hangs rather than staying normal.
她的代码来自主 Myprogram extends Application
类,用于显示按钮:
Her's the code from the main Myprogram extends Application
class for showing the buttons:
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
)
Pretty simple, but the UI hangs whenever I click the Start button, though the console messages continue to get displayed (Logger.log
simply does System.out.println
)
我做错了什么?
推荐答案
Task
实现了Runnable
,所以当你调用handler.run();
code> 实际上是在 UI 线程中运行 call
方法.这将挂起 UI.
Task
implements Runnable
, so when you call handler.run();
you actually run the call
method in the UI Thread. That will hang the UI.
您应该在后台线程中启动任务,通过执行程序或简单地调用new Thread(handler).start();
.
You should start the task in a background thread, either via an executor or simply by calling new Thread(handler).start();
.
这在 javadoc 中有解释(可能不是很清楚)或在 JavaFX 并发教程中.
This is explained (maybe not very clearly) in the javadoc or in the JavaFX concurrency tutorial.
这篇关于JavaFX 中的多线程挂起 UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!