JavaFX 使用 Platform.runLater 从另一个线程更新 TextArea

Posted

技术标签:

【中文标题】JavaFX 使用 Platform.runLater 从另一个线程更新 TextArea【英文标题】:JavaFX update TextArea from another thread using Platform.runLater 【发布时间】:2018-05-24 22:40:48 【问题描述】:

我正在尝试使用另一个实现Runnable 的类中的Platform.runLater 更新TextArea。 我的所有 GUI 都在一个类中(我的 TextArea 所在的位置),我正在创建一个 new server 线程并在创建 gui 时运行它。我试图使用Server 线程中的Platform.runLater 来更新我的TextAreaPlatform.runLater 无法访问我的TextArea。

public class SimulationWindow 
    public SimulationWindow instance() 
        return this;
    
    public static void DisplaySimulationWindow() throws FileNotFoundException 
        Stage SimuStage = new Stage();
        SimuStage.initModality(Modality.APPLICATION_MODAL);
        SimuStage.setTitle("Simulation Window");
        Server myServer = new Server(instance());
        Thread serverThread = new Thread(myServer);
        serverThread.start();
        TextArea serverTextArea;
         .
         .
         .


public class Server implements Runnable 
    @Override
    public void run() 
        while(true)
            whileConnected();
        .
        .
    
    private void whileConnected() throws IOException 

        sendMessage(message);

        do 
            try 
                message = (String) input.readObject();  
                showMessage(message);
                .
                .
                .
    
   private void showMessage(String x) 
    Platform.runLater(() -> serverTextArea.appendText(x));          
   

我尝试将我的 SimulationWindow 实例传递给服务器构造函数,就像他们在这里所做的那样:Modifying JavaFX gui from different thread in different class

但是 Java 不会让我的 SimulationWindow 实例作为服务器构造器的参数传递。 其他解决方案将保持 Server 和 SimulationWindow 类作为一个类,但我想让它们分开。 任何提示表示赞赏!

【问题讨论】:

在Server中,添加一个以textArea为参数的构造函数 “但是 Java 不会让我的 SimulationWindow 实例作为服务器构造器的参数传递。” SimulationWindow 实例:你的代码中没有。 displaySimulationWindow() 真的需要static 吗? 嗨@James_D 我将实例方法添加到问题中。感谢您指出了这一点。我删除了静态,现在我可以将实例发送到服务器构造函数,但我仍然无法从服务器内部访问 serverTextArea。 你希望一个类如何访问另一个类的方法本地成员?如您所见,sn-ps 相当没用;) 嗨@kleopatra 感谢您的提示,我正在尝试按照您的建议传递一个TextArea。是的,我需要学会小心使用 sn-ps。 :P 【参考方案1】:

我按照 kleopatra 的建议解决了这个问题。我将一个 TextArea 传递给了我的 Server 构造函数。我想从我的 GUI 类以及从服务器类中的客户端获取消息时更新我的​​ GUI 中的 TextArea。 (我在 SimuWindow() 中创建并启动我的服务器)

public class myGUI
    public void SimuWindow()
        //this method creates all the GUI.
        Server myServer = new Server(serverTextArea);
        Thread serverThread = new Thread(myServer);
        serverThread.start();

        sendingTest = new TextField();
        sendingTest.setPromptText("test communication here");
        sendingTest.setOnAction(event -> 
        String message = new String ("\nServer says: ");
        message = message + sendingTest.getText();
        serverTextArea.appendText(message);
        myServer.sendMessage(message);
        sendingTest.clear();
    );
    


public class Server implements Runnable
    //This is my server class that connects and listens to clients
    TextArea mytextArea;
    public Server(TextArea x) 
        this.mytextArea = x;
    
    private void whileConnected() throws IOException           
    do 
        try 
            message = (String) input.readObject();  
            showMessage(message);               
        catch(ClassNotFoundException classNotFoundException) 
            System.out.println("\n i dont know the message");
        
    while(!message.equals("Disconnected"));    

    private void showMessage(String mess) 
            Platform.runLater(() -> mytextArea.appendText(mess));           
    

我在我的客户端类上做了同样的事情。感谢您的帮助。

【讨论】:

以上是关于JavaFX 使用 Platform.runLater 从另一个线程更新 TextArea的主要内容,如果未能解决你的问题,请参考以下文章

我不能使用 JavaFX [重复]

javaFX-使用gradle+jdk14创建javafx程序

使用 JavaFX 显示 OpenCV Mat

如何将 Spring 与 JavaFX 一起使用?

使用JAVAFX和SWING有啥区别[重复]

使用 Gradle 构建 JavaFX 应用程序