2017-08-16 41 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

相關問題