繁体   English   中英

JavaFx和套接字侦听器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM