2015-01-26 44 views
3

我想在不使用方法本身的情況下實現Stage.showAndWait()的功能。重新實現JavaFX showAndWait

我有一個應用程序,我需要一種方式顯示在同一階段的東西,並阻止線程顯示的內容,直到按下按鈕。

顯示內容的線程自然需要是JavaFX應用程序線程 - 只要它被阻塞,當然不會處理這些按鈕。

Stage.showAndWait描述了它的內部運作爲「當前事件的這種方法暫時塊的處理,並啓動其嵌套事件循環處理其它事件。」我看到,該方法稱爲「Toolkit.getToolkit()。enterNestedEventLoop(這個)「,這是相當具體的實現。還有其他選擇嗎?像這樣的功能暴露在API的任何地方?

編輯:
因爲我的問題是誤導性的,我嘗試從我目前的角度來看更重要的是改換:
是否有Toolkit.getToolkit()的公共API enterNestedEventLoop()和工具包.getToolkit()。exitNestedEventLoop()?

+0

你的問題不是很清楚(至少不是我)。像幾乎所有的UI工具包一樣,JavaFX是單線程的:所以「顯示內容的線程」必須與處理按鈕的線程相同。我不明白爲什麼你不能只顯示內容,然後在按鈕的事件處理程序中更新它或刪除它(無論你需要做什麼)。 – 2015-01-26 23:36:43

+1

不,沒有公共API來解決這個問題,您需要使用私有API Toolkit.getToolkit() – tomsontom 2015-01-27 13:58:16

回答

0

這是不是很清楚你想要做什麼,但它聽起來像你有一個長期運行的過程,建立某種類型的數據,然後你想讓用戶來控制如何建立數據被傳送到屏幕。在這種情況下,您需要運行後臺任務來構建數據,將數據傳輸到FXAT可用的某個元素,然後使用按鈕的操作事件將數據移動到屏幕上。事情是這樣的:

public class LongTask extends Application { 

StringProperty results = new SimpleStringProperty(""); 

public static void main(String[] args) { 
    launch(args); 
} 

@Override 
public void start(Stage primaryStage) { 
    primaryStage.setTitle("Hello World!"); 
    TextArea textArea = new TextArea(); 

    BorderPane root = new BorderPane(); 
    root.setCenter(textArea); 
    Button button = new Button("More Data"); 
    root.setBottom(button); 
    button.setOnAction(evt -> textArea.setText(results.get())); 
    primaryStage.setScene(new Scene(root, 300, 250)); 
    primaryStage.show(); 

    Task<Void> sleeper = new Task<Void>() { 
     @Override 
     protected Void call() throws Exception { 
      for (int iteration = 0; iteration < 1000; iteration++) { 
       try { 
        Thread.sleep(5000); 
        int i = iteration; 
        Platform.runLater(() -> results.set(results.get() + "\nIteration " + i)); 
       } catch (InterruptedException e) { 
       } 
      } 
      return null; 
     } 
    }; 
    new Thread(sleeper).start(); 
} 

}

從技術上講,你不需要做「結果」的屬性,也不需要通過Platform.runlater更新它()。使用Platform.runlater()可以保證您不會遇到併發問題。另外,如果你將「結果」綁定到任何東西,那麼你需要使用Platform.runlater()來修改它。

+0

感謝您的回覆。我不是在談論一個漫長的過程。它更像是一個我想要展示的模式對話框(通常Stage.showAndWait會很好),但是沒有授予它是自己的窗口,所以關閉對話框的通常機制不適用。 考慮到我現在知道的,我正在尋找Toolkit.getToolkit()的公共API。enterNestedEventLoop()和exitNestedEventLoop() – taranion 2016-05-20 07:39:56

+0

試圖以這種方式控制FXAT通常是一種氣味。如果你有一個進程需要暫停和啓動,然後把它放在後臺線程中。當該線程需要實際與GUI交互時使用Platform.runLater()或其中一個任務功能。 – DaveB 2016-05-21 11:43:30