重新实现JavaFX showAndWait

时间:2015-01-26 21:25:38

标签: multithreading javafx javafx-8

我希望在不使用方法本身的情况下实现Stage.showAndWait()的功能。

我有一个应用程序,我需要一种在同一个阶段显示内容的方法,并阻止显示内容的线程,直到按下按钮。

显示内容的线程自然需要是JavaFX应用程序线程 - 只要它被阻止,它当然不会处理按钮。

Stage.showAndWait将其内部工作描述为“此方法暂时阻止当前事件的处理,并启动嵌套事件循环以处理其他事件。”我看到方法调用“ Toolkit.getToolkit()。enterNestedEventLoop(this)“,这是非常具体的实现。还有其他选择吗?这样的功能是否暴露在API的任何地方?

修改
由于我的问题具有误导性,我试图从目前的角度对其进行更多的改写:
是否有Toolkit.getToolkit()的公共API。enterNestedEventLoop()和Toolkit.getToolkit()。exitNestedEventLoop()?

2 个答案:

答案 0 :(得分:1)

对于我改过的问题:

  

是否有Toolkit.getToolkit()。enterNestedEventLoop()和Toolkit.getToolkit()。exitNestedEventLoop()的公共API?

此后,该API已在以下位置公开:

javafx.application.Platform.enterNestedEventLoop()

答案 1 :(得分: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()来修改它。