我正在建模一个使用JavaFX的原型。
该应用程序将类似于一个自助式服务亭。但是,在客户端与其交互之前,管理员应该将其解锁。管理员将能够通过专用通道(HTTP或IPC或USB设备)发送一些远程命令。命令的示例如下:启动、停止和重置
我怎么发动汽车呢?
我可以有一个任务,在另一个线程池中运行一个IPC,如果有消息,切换场景?
( b)要让反应堆在线程中运行,并且一旦收到命令,它就将其传递给JavaFX线程。
这两种选择都有效吗?还有第三种吗?
发布于 2014-11-10 23:50:12
您的选项(a)带有任务的线程和(b)没有任务的线程都是有效的。
推荐解决方案
我选择选项b(没有任务的线程)。
解决方案的关键部分是以下内容:
Platform.runLater(() -> MyApplication.changeScene(newData));任务是好的,但对你的情况可能不是最好的。
如果有由UI或JavaFX线程启动的内容,则任务是好的。例如,用户单击一个按钮,您希望根据该操作从服务器检索数据,在检索数据时通过消息和进度条更新反馈进度报告。因此,Task非常适合这种操作,因为它对消息反馈和进度更新等内容有明确的支持,并为任务的启动和完成提供了一个定义良好的状态模型。请参阅不变量代码示例,以了解任务如何改进此类情况:Platform.runLater与JavaFX中的任务。
但是,当事件的发起者离开JavaFX应用程序线程时,使用任务与仅仅使用传统的并发实用程序相比并没有太大的优势。这是因为您通常不需要任务提供的额外服务,例如进度和消息更新API及其状态机。另外,发起此类事件的库通常已经有了自己的线程模型设置,因此您不需要任务提供的额外线程框架。
使用Platform.runLater()
你真正想要的就是通知发生了什么事。现在,通知需要发生在JavaFX应用程序线程上,因为您不能使用另一个线程操作活动场景中的项。要获得传递给JavaFX应用程序线程的事件,可以使用Platform.runLater(可运行)构造。
样本码
我不会编写Ruby,因为我真的不能写,但是这里有一些Java代码给您提供了要点--它实际上非常简单。
class DataReader implements Runnable {
private final DataSource dataSource;
public DataReader(String location) {
dataSource = new DataSource(location);
Thread thread = new Thread(this);
thread.setDaemon(false);
thread.start();
}
public void run() {
while (dataSource.hasData()) {
MyImmutableObject newData = dataSource.getSomeData();
Platform.runLater(() -> MyApplication.changeScene(newData));
}
}
}
class MyApplication extends Application {
public void changeScene(MyImmutableObject newData) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"layout.fxml"
)
);
UIController controller =
loader.<UIController>getController();
controller.initData(newData);
Scene scene = new Scene((Pane) loader.load());
stage.setScene(newScene);
}
}上面的示例使用虚构的DataSource、MyImmutableObject和UIController类以及一个虚构的FXML模板来演示这个概念(所以这个片段不是一个独立运行的东西)。FXML加载概念来自:传递参数JavaFX FXML。示例代码会创建自己的线程,但是如果您正在使用的库本身已经创建了线程本身(很可能),您就不需要创建另一个线程了,您可以使用Platform.runLater调用向现有库中添加适当的钩子,以获取事件通知并在库线程和JavaFX应用程序之间传递数据。
相关问题
关于Platform.runLater和StackOverflow上的任务还有许多其他问题:
附加问题
在我的示例中,管理员将能够在某些情况下向信息亭发送初始信息,几乎就像(初始化向量),例如护照号码。有了这些信息,Platform.runLater还是最好的解决方案吗?
是的,Platform.runLater仍然是最好的解决方案。当管理员将信息发送到kiosk (例如嵌入式http服务器上的servlet或jax-rs服务)时,您将得到一些线程的警告,并且它可以根据这些信息调用Platform.runLater来更新基于JavaFX的kiosk。
https://stackoverflow.com/questions/26823040
复制相似问题