JavaFx和套接字侦听器

时间:2016-06-11 13:02:40

标签: java multithreading sockets user-interface javafx

我们正在开发一个客户端 - 服务器应用程序,它必须同时使用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由控制器实例化,控制器执行who"执行"收到的对象,更新界面(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作为控制器的类,但没有任何(正面)结果。 我们如何实例化一个线程,以便它可以使用JavaFX并调用显示我们需要的屏幕的方法?

谢谢

2 个答案:

答案 0 :(得分:2)

  

不在FX应用程序线程

告诉您问题的原因。

根据Node类的Javadoc:

  

可以在任何线程上构建和修改节点对象   它们尚未附加到正在显示的窗口中的场景。一个   应用程序必须将节点附加到此类场景或在其上修改它们   JavaFX应用程序线程。

使用Platform.runLater在FX应用程序线程上执行代码,并查看javafx.concurrent包以获取更多实用程序类。

答案 1 :(得分:1)

大概是对controller.parseDialogue(dialogue);的调用正在更新UI。您只能在FX应用程序线程上执行此操作。您可以使用Platform.runLater()

计划在FX应用程序线程上执行runnable
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...
        });
    }
}

并恢复到套接字侦听器类中的原始代码。

相关问题