2014-11-08 78 views
1

我正在建模一個將使用JavaFX的原型。在某些外部事件後切換javafx/jrubyfx場景

該應用程序將與自助服務終端類似,用於自助服務。但是在客戶端與之交互之前,管理員應該解鎖它。管理員將能夠通過專用通道(HTTP或IPC或USB設備)發送一些遠程命令。命令的例子是:啓動,停止和重置

我應該怎麼做?

a)我可以有一個任務,運行在另一個線程積極的IPC,如果有消息,切換場景? b)讓一個反應堆在一個線程中運行,並在收到一個命令後立即將它傳遞給JavaFX線程。

都是選項有效嗎?確實存在第三個?

回答

1

您的選項(a)與Task和(b)線程無任務都是有效的。

推薦的解決方案

我會選擇選項B(線程沒有任務)。

解決方案的關鍵部分是線:

Platform.runLater(() -> MyApplication.changeScene(newData)); 

任務是好的,但可能不是最適合你的情況

任務是好的,如果你有這是由開始的東西UI或JavaFX線程。例如,用戶點擊一個按鈕,並且您希望根據該操作從服務器檢索數據,並在檢索數據時通過消息和進度條更新反饋進度報告。所以Task對於這種操作非常有用,因爲它對諸如消息反饋和進度更新之類的事情有明確的支持,並且對於任務何時開始和完成有明確的狀態模型。查看不變式代碼示例以瞭解Task如何改進此類情況:Platform.runLater and Task in JavaFX

但是,當事件的發起者脫離JavaFX應用程序線程時,使用任務與使用傳統併發實用程序相比沒有多大優勢。這是因爲您通常不需要任務提供的額外服務,如進度和消息更新API及其狀態機。此外,啓動此類事件的庫通常已經擁有自己的線程模型設置,因此您不需要任務提供的額外線程框架。

使用Platform.runLater()

所有你真正想要的是事情發生的通知。現在該通知需要在JavaFX應用程序線程上發生,因爲您無法使用另一個線程處理活動場景中的項目。要獲取傳遞給JavaFX應用程序線程的事件,請使用Platform.runLater(runnable)構造。

示例代碼

我不會寫紅寶石,因爲我實在沒辦法,但這裏是在Java中的一些代碼給你的要點 - 它實際上很簡單。

class DataReader implements Runnable { 
    private final DataSource dataSource; 

    public DataReader(String location) { 
     dataSource = new DataSource(location); 

     Thread thread = new Thread(this); 
     thread.setDaemon(false); 
     thread.start(); 
    } 

    public void run() { 
     while (dataSource.hasData()) { 
      MyImmutableObject newData = dataSource.getSomeData(); 
      Platform.runLater(() -> MyApplication.changeScene(newData)); 
     } 
    } 
} 

class MyApplication extends Application { 
    public void changeScene(MyImmutableObject newData) { 
     FXMLLoader loader = new FXMLLoader(
      getClass().getResource(
       "layout.fxml" 
      ) 
     ); 

     UIController controller = 
      loader.<UIController>getController(); 
     controller.initData(newData); 

     Scene scene = new Scene((Pane) loader.load()); 
     stage.setScene(newScene); 
    } 
} 

將上述樣品利用虛構的DataSource,MyImmutableObject和UIController類和虛構FXML模板說明概念的(所以片段是不是一個獨立的可運行的東西)。 FXML加載概念來自:Passing Parameters JavaFX FXML。示例代碼創建了自己的線程,但是如果您正在使用的庫已經創建了線程本身(很可能),則不需要創建另一個線程,只需使用Platform.runLater將適當的鉤子添加到現有庫中即可調用以獲取事件通知並在庫線程和JavaFX應用程序之間傳遞數據。

相關問題

有對工作在計算器上上Platform.runLater許多其他問題:

其他問題

就我而言,管理員在某些情況下可以向服務終端發送初始信息,就像(初始化向量)一樣,例如護照號碼。有了這些信息,Platform.runLater仍然是最好的解決方案嗎?

是的,Platform.runLater仍然是最好的解決方案。當管理員將信息發送到信息亭時(例如嵌入式http服務器上的servlet或jax-rs服務),您將獲得一些線程,並且它可以調用Platform.runLater更新基於JavaFX的信息亭UI信息。

+0

嗨,很好,很詳細。然而,我有一個問題:你說「你真正想要的只是發生了一些事情的通知」,但就我而言,管理員在某些情況下可以向信息亭發送初始信息,就像(初始化向量),例如護照號碼。有了這些信息,Platform.runLater仍然是最好的解決方案嗎? – 2014-11-12 21:48:36