在另一个线程中更改JavaFX中的Text

时间:2015-12-06 21:20:08

标签: java multithreading javafx javafx-8

我有一个耗时的方法,必须在按钮的操作上运行,并且当我运行该方法时,我希望UI仍然是活动的(即用户仍然可以与它交互)。我尝试了几种解决方案。一个是运行方法:

Label label = new Label("current text");
Button button = new Button("Button text");
button.setOnAction(event -> label.setText(runConputation())); // takes a long time

但是这会在UI运行时锁定它。

另一种解决方案是使用单独的线程:

Label label = new Label("current text");
Button button = new Button("Button text");
button.setOnAction(event -> {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            label.setText(runConputation()); // takes a long time
        }
    });
    thread.start();
});

但这会抛出一个IllegalStateException: not in javafx thread或类似的东西。

我尝试添加Platform.runLater(),因为我读到这将解决异常:

Label label = new Label("current text");
Button button = new Button("Button text");
button.setOnAction(event -> {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    label.setText(runConputation()); // takes a long time
                }
            });
        }
    });
    thread.start();
});

...但它会锁定UI。它看起来也很难看。

我也尝试使用Task

Label label = new Label("current text");
Button button = new Button("Button text");
button.setOnAction(event -> {
    Thread thread = new Thread(new Task<Void>() {
        @Override
        public Void call() throws Exception {
            Platform.runLater(new Runnable() {
                @Override
                public void run() {
                    label.setText(runConputation()); // takes a long time
                }
            });
            return null;
        }
    });
    thread.start();
});

有类似的结果。

我想做类似的事情:

Label label = new Label("current text");
Button button = new Button("Button text");
button.setOnAction(event -> {
    Task<String> task = new Task<String>() {
        @Override
        public String call() throws Exception {
            return runConputation();
        }
    };
    Thread thread = new Thread(task);
    thread.start();
    // wait until thread is done
    label.setText(task.getValue());
});

有办法做到这一点吗?

0 个答案:

没有答案