2017-08-16 57 views
0

在我了解后台线程上的运行任务之前,我学会了如何通过带有接口的控制器将消息发布到我的用户界面。该接口允许我在任何控制器中都有系统消息。但我不知道如何将它绑定到任务的updateMessage。JavaFX并发性:如何使用接口将updateMessage()更新到控制器?

我的界面:

public interface SystemMessage { 
    void postMessage(String outText); 
} 

我的控制器:

public class MainController implements SystemMessage { 
    @FXML 
    public DialogPane systemMessage; 

    @Override 
    public void postMessage(String outText) { 
     systemMessage.setContentText(outText); 
    } 

    //***I have tried the following to bind the dialog pane to the updateMessage 

    systemMessage.contentTextProperty().bind(task.messageProperty()); 

    //***InteliJ tells me that it can not resolve contetTextProperty or task. 
} 

我的主要一个新的线程与任务类。

private SystemMessage mainController; 

FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/entry.fxml")); 
Parent root = loader.load(); 
this.mainController = (SystemMessage) loader.getController(); 

api = new Api(); 
machineId = new Identity(); 
    db = new SqLite(); 
    //mainController.postMessage(task.messageProperty()).bind(); 
    Thread th = new Thread(task); 
    th.setDaemon(true); 
    th.start(); 

Task<String> task = new Task<String>() { 
    @Override protected String call() throws Exception { 
     checkAsiServer(); 
     updateMessage("API Checked."); 

     checkMachineId(); 
     updateMessage("Machine Id Checked."); 

     checkDb(); 
     updateMessage("Server Checked."); 

     return "done"; 
    } 
}; 

我试图通过我的DialogPane绑定在cotroller:

systemMessage.contentTextProperty().bind(task.messageProperty()); 

但它无法解决contentTextProperty,我不知道如何可以告诉任务对象的控制器。

+0

我很困惑最后的代码块来自哪里?这是在控制器内?如果是这样,我不明白是什么问题。 –

+0

@James_D没有最后的代码块在Main中,这也是任务运行的地方。你帮我弄清楚了Task组件!事实上,我可以使用RunLater()进行这项工作,但我认为updateMessage到我的界面会更加优雅。 – silversunhunter

+0

@James_D ..如果您指的是控制器中的systemMessage ...代码块。但它无法解析contentTextProprty或任务。 – silversunhunter

回答

1

不知道我明白这个问题。你为什么不直接暴露控制器的属性?你可以做

public class MainController implements SystemMessage { 
    @FXML 
    private DialogPane systemMessage; 

    public StringProperty messageProperty() { 
     return systemMessage.contentTextProperty(); 
    } 

    // ... 
} 

然后

FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/entry.fxml")); 
Parent root = loader.load(); 
MainController mainController = loader.getController(); 

Task<String> task = new Task<String>() { /* existing code... */}; 

mainController.messageProperty().bind(task.messageProperty()); 

Thread thread = new Thread(task); 
thread.setDaemon(true); 
thread.start(); 

如果你想保持控制器SystemMessage的类型,只能依靠postMessage方法,那么显然你不能用绑定做到这一点(因为你没有办法访问这个属性);你需要使用一个监听器来代替:

FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/entry.fxml")); 
Parent root = loader.load(); 
SystemMessage mainController = loader.getController(); 

Task<String> task = new Task<String>() { /* existing code... */}; 

task.messageProperty().addListener((obs, oldMessage, newMessage) -> 
    mainController.postMessage(newMessage));  

Thread thread = new Thread(task); 
thread.setDaemon(true); 
thread.start(); 
+0

当我尝试第一个解决方案时,InteliJ说messageProperty无法解析。 – silversunhunter

+1

@silversunhunter你做了我所建议的一切吗?将'messageProperty()'方法添加到控制器并将'mainController'的类型更改为'MainController'? –

+0

啊。抱歉,我没有将类型改回MainController。我现在已经完成了这一步,并且我一起删除了界面。我在我们创建的stringProperty的return语句处得到由NullPointerException引发的InvocationException。 – silversunhunter

相关问题