【问题标题】:JavaFx and socket listenerJavaFx 和套接字监听器
【发布时间】:2016-10-12 08:31:59
【问题描述】:

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

谢谢

【问题讨论】:

    标签: java multithreading sockets user-interface javafx


    【解决方案1】:

    不在 FX 应用程序线程上

    为您提供问题的原因。

    根据Node类的Javadoc:

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

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

    【讨论】:

      【解决方案2】:

      大概是对controller.parseDialogue(dialogue); 的调用正在更新用户界面。您只能在 FX 应用程序线程上执行此操作。您可以使用Platform.runLater() 安排在 FX 应用程序线程上执行的可运行文件:

      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...
              });
          }
      }
      

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

      【讨论】:

        猜你喜欢
        • 2011-02-15
        • 2013-03-29
        • 2015-11-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2016-04-06
        • 2010-11-09
        相关资源
        最近更新 更多