[英]JavaFx and socket listener
我们正在开发一个必须同时使用GUI和CLI的客户端服务器应用程序。 CLI没问题,但是我们努力用JavaFX来实现它:
我们的服务器(通过套接字)向客户端发送一些对象,这些对象必须进行处理。
这是我们的SocketServerListener(和编写器):
public class SockeServerListener extends Thread implements ServerListener{
private CliController controller;
private ObjectInputStream in;
private ObjectOutputStream out;
public SocketServerListener(Socket server, CliController controller) throws UnknownHostException, IOException {
this.controller = controller;
this.out = new ObjectOutputStream(server.getOutputStream());
this.in = new ObjectInputStream(server.getInputStream());
}
public void publishMessage(String message) throws IOException, RemoteException {
out.writeObject(message);
out.flush();
}
public void run() {
try {
while (true) {
Dialogue dialogue = (Dialogue) in.readObject();
controller.parseDialogue(dialogue);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SocketServerListener由控制器实例化,该控制器是执行“执行”所接收对象,更新接口(Cli / GUI)的控制器。
public void parseDialogue(Dialogue dialog) {
dialog.execute(view); //view is an interface extended by both the Cli and GUI
this.canWrite = true;
}
就像我说的那样,这在CLI上很好用,但是JavaFX引发了异常
Exception in thread "Thread-7" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread-7
我们尝试使用用于生成所有GUI的Class作为控制器,但是没有任何(肯定的)结果。 我们如何实例化一个线程,使其可以与JavaFX一起使用,并调用显示所需屏幕的方法?
谢谢
不在FX应用程序线程上
给您问题的原因。
根据Node类的Javadoc:
节点对象可以在任何线程上构造和修改,只要它们尚未附加到正在显示的窗口中的场景上即可。 应用程序必须将节点附加到此类场景,或在JavaFX应用程序线程上对其进行修改。
使用Platform.runLater在FX应用程序线程上执行代码,还可以查看javafx.concurrent包中的更多实用程序类。
大概是对controller.parseDialogue(dialogue);
的调用controller.parseDialogue(dialogue);
正在更新用户界面。 您只能在FX Application Thread上执行此操作。 您可以使用Platform.runLater()
安排可运行的程序在FX Application线程上执行:
Platform.runLater( () -> controller.parseDialogue(dialogue) );
请注意,如果您不知道要在已启动FX工具包的上下文中执行此代码,则应改为在控制器中调用Platform.runLater(...)
,例如
public class NonGuiController implements CliController {
@Override
public void parseDialog(Dialogue dialogue) {
// regular code here...
}
}
和
public class GuiController implements CliController {
@Override
public void parseDialogue(Dialogue dialogue) {
// some preliminary work (still on background thread here) if necessary...
Platform.runLater(() -> {
// code that updates UI here...
});
}
}
并还原为套接字侦听器类中的原始代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.