multithreading 计时器和 javafx

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16764549/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 01:22:50  来源:igfitidea点击:

Timers and javafx

multithreadingtimerjavafx-2javafx

提问by i .

I am trying to write a code that will make things appear on the screen at predetermined but irregular intervals using javafx. I tried to use a timer (java.util, not javax.swing) but it turns out you can't change anything in the application if you are working from a separate thread.(Like a Timer) Can anyone tell me how I could get a Timer to interact with the application if they are both separate threads?

我正在尝试编写一个代码,使用 javafx 使事物以预定但不规则的间隔出现在屏幕上。我尝试使用计时器(java.util,而不是javax.swing)但事实证明,如果您从单独的线程工作,则无法更改应用程序中的任何内容。(如计时器)谁能告诉我我怎么做如果它们都是单独的线程,则获取 Timer 与应用程序交互?

采纳答案by Michael Berry

If you touch any JavaFX component you must do so from the Platform thread (which is essentially the event dispatch thread for JavaFX.) You do this easily by calling Platform.runLater(). So, for instance, it's perfectly safe to do this:

如果您接触任何 JavaFX 组件,您必须从平台线程(它本质上是 JavaFX 的事件分派线程)执行此操作。您可以通过调用Platform.runLater(). 因此,例如,这样做是完全安全的:

new Thread() {
    public void run() {
        //Do some stuff in another thread
        Platform.runLater(new Runnable() {
            public void run() {
                label.update();
                javafxcomponent.doSomething();
            }
        });
    }
}.start();

回答by Tomas Mikula

You don't need java.util.Timeror java.util.concurrent.ScheduledExecutorServiceto schedule future actions on the JavaFX application thread. You can use JavaFX Timeline as a timer:

您不需要java.util.Timerjava.util.concurrent.ScheduledExecutorService安排 JavaFX 应用程序线程上的未来操作。您可以使用 JavaFX Timeline 作为计时器:

new Timeline(new KeyFrame(
        Duration.millis(2500),
        ae -> doSomething()))
    .play();

Alternatively, you can use a convenience method from ReactFX:

或者,您可以使用ReactFX的便捷方法:

FxTimer.runLater(
        Duration.ofMillis(2500),
        () -> doSomething());

Note that you don't need to wrap the action in Platform.runLater, because it is already executed on the JavaFX application thread.

请注意,您不需要将操作包装在 中Platform.runLater,因为它已在 JavaFX 应用程序线程上执行。

回答by Flo C

berry120 answer works with java.util.Timer too so you can do

berry120 答案也适用于 java.util.Timer 所以你可以这样做

Timer timer = new java.util.Timer();

timer.schedule(new TimerTask() {
    public void run() {
         Platform.runLater(new Runnable() {
            public void run() {
                label.update();
                javafxcomponent.doSomething();
            }
        });
    }
}, delay, period);

I used this and it works perfectly

我用过这个,效果很好