JavaFX 多线程概念
JavaFX Multithreading Concept
开始之前:我是 JavaFX 的新手,我想通过这个项目学习如何正确使用这个库。
情况如下:我有一个服务器-客户端应用程序。服务器向客户端发送服务器上活动用户的列表。现在我想列出 UI 中的活跃用户。我想用 FlowPane 中的按钮来做到这一点。问题是我的客户端在外部线程中,所以不在应用程序线程中。但是由于客户端获取用户列表这一事实,我尝试直接从客户端线程更新按钮列表。
if(data.getObject() instanceof ArrayList<?>) {
ArrayList<User> activeUsers = (ArrayList<User>) data.getObject();
controller.setActiveUsers(activeUsers);
}
我的控制器中的方法执行以下操作:
public void setActiveUsers(ArrayList<User> activeUsers) {
for(User user:activeUsers) {
fpOnlineUsers.getChildren().add(new Button(user.getName()));
}
}
我得到的异常如下:java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-3
我有两个问题:
- 我该如何解决这个问题?
- 为什么阻止 JavaFX 从应用程序线程以外的线程更改?
如有任何语言错误,请见谅,我不是母语人士:)
- 您需要在应用程序线程上进行任何与 JavaFX 对象相关的调用。要从您的客户端 Thread 执行此操作,请使用
Application.runlater(Runnable)
函数。
您的代码应如下所示:
public void setActiveUsers(ArrayList<User> activeUsers) {
Platform.runLater(new Runnable() {
@Override public void run() {
for(User user:activeUsers) {
fpOnlineUsers.getChildren().add(new Button(user.getName()));
}
}
}
});
参考:
Platform.runLater and Task in JavaFX
开始之前:我是 JavaFX 的新手,我想通过这个项目学习如何正确使用这个库。
情况如下:我有一个服务器-客户端应用程序。服务器向客户端发送服务器上活动用户的列表。现在我想列出 UI 中的活跃用户。我想用 FlowPane 中的按钮来做到这一点。问题是我的客户端在外部线程中,所以不在应用程序线程中。但是由于客户端获取用户列表这一事实,我尝试直接从客户端线程更新按钮列表。
if(data.getObject() instanceof ArrayList<?>) {
ArrayList<User> activeUsers = (ArrayList<User>) data.getObject();
controller.setActiveUsers(activeUsers);
}
我的控制器中的方法执行以下操作:
public void setActiveUsers(ArrayList<User> activeUsers) {
for(User user:activeUsers) {
fpOnlineUsers.getChildren().add(new Button(user.getName()));
}
}
我得到的异常如下:java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-3
我有两个问题:
- 我该如何解决这个问题?
- 为什么阻止 JavaFX 从应用程序线程以外的线程更改?
如有任何语言错误,请见谅,我不是母语人士:)
- 您需要在应用程序线程上进行任何与 JavaFX 对象相关的调用。要从您的客户端 Thread 执行此操作,请使用
Application.runlater(Runnable)
函数。
您的代码应如下所示:
public void setActiveUsers(ArrayList<User> activeUsers) {
Platform.runLater(new Runnable() {
@Override public void run() {
for(User user:activeUsers) {
fpOnlineUsers.getChildren().add(new Button(user.getName()));
}
}
}
});
参考: Platform.runLater and Task in JavaFX