Timer JavaFX System.currentTimeMillis()和#x2B;任务

Timer JavaFX System.currentTimeMillis()和#x2B;任务,timer,javafx,task,Timer,Javafx,Task,我目前正在做一些带有一些动画的GUI。最后我自己对标签的颜色变化进行了编码。为此,我执行了以下任务: Task tk= new Task() { @Override protected Void call() throws Exception { colorAnimation=true; boolean red = true; long timer =

我目前正在做一些带有一些动画的GUI。最后我自己对标签的颜色变化进行了编码。为此,我执行了以下任务:

Task tk= new Task() {
            @Override protected Void call() throws Exception
            {
                colorAnimation=true;
                boolean red = true;
                long timer = System.currentTimeMillis();
                long waitTime= 1000;
                nome.setStyle("-fx-background-color: red;");
                main: while(colorAnimation)
                {
                    while(System.currentTimeMillis() < waitTime+ timer)
                    {
                        System.out.println(System.currentTimeMillis()-timer);
                        if(!colorAnimation)
                            break main;
                    }
                    timer=System.currentTimeMillis();

                    red=!red;
                    if(red)
                    {
                        nome.setStyle("-fx-background-color: red;");
                        waitTime=1000;
                    }
                    else
                    {
                        nome.setStyle("-fx-background-color: black;");
                        waitTime=500;
                    }
                }
                nome.setStyle("-fx-background-color: black;");
                return null;
            }
        };
        Thread t = new Thread(tk);
        t.setDaemon(true);
        t.start();
Task tk=新任务(){
@Override protected Void call()引发异常
{
彩色动画=真;
布尔红=真;
长定时器=System.currentTimeMillis();
长等待时间=1000;
命名设置样式(“-fx背景色:红色;”);
主:while(彩色动画)
{
while(System.currentTimeMillis()
上述函数应以红色初始化标签颜色,等待1秒,将其更改为黑色,等待半秒,然后再次将其更改为红色,重复此过程,直到关闭colorAnimation(声明为volatile)。问题是函数在第二个时间段内被阻塞,并且向控制台打印等待时间(System.currentTimeMillis()-timer)在982时被阻塞。如果我将初始等待时间更改为500,那么打印的等待时间将被限制在469。我真的不知道发生了什么事

谢谢

首先,你的代码对我“有效”,所以我无法解释为什么你会看到你看到的效果

不过你不应该用这个。它违反了JavaFX的一条规则:您不应该从JavaFX应用程序线程外部访问场景图的状态。(例如,请参阅上的一节。)可能是在尝试执行
setStyle(…)
调用时引发异常,导致线程终止;这可以解释你所看到的行为。(但是,在我的系统上似乎没有发生这种情况。)

此外,您的代码非常复杂,很难维护。有一些更高级的API是为这种功能设计的,例如。您应该使用这些API来简化代码并避免线程错误

例如:

import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

public class ColorAnimationTest extends Application {

    @Override
    public void start(Stage primaryStage) {

        Label nome = new Label("Hello");

        // This chunk of code replaces your entire thread/task code
        Timeline animation = new Timeline(
                new KeyFrame(Duration.millis(1000), 
                        event -> nome.setStyle("-fx-background-color: red;")),
                new KeyFrame(Duration.millis(1500),
                        event -> nome.setStyle("-fx-background-color: black")));

        animation.setCycleCount(Animation.INDEFINITE);
        animation.play();

        // Button to stop/start the animation:
        Button button = new Button();
        button.setOnAction(event -> {
            if (animation.getStatus() == Animation.Status.RUNNING) {
                animation.stop();
            } else {
                animation.play();
            }
        });

        // change text of button approprite to animation state:
        button.textProperty().bind(Bindings
                .when(animation.statusProperty().isEqualTo(Animation.Status.RUNNING))
                .then("Stop")
                .otherwise("Start"));

        VBox root = new VBox(10, nome, button);
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root, 350, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

谢谢你的回复和技巧。我看到了代码,我想知道这是否有效。我的问题在于您为红色和黑色设置的持续时间。据我所知,该代码将使颜色每秒更改为红色,并将每1,5秒更改为黑色。第二个三号有问题吗?据我所知,会有,因为这两个事件将试图改变颜色在同一时间。我说的对吗?你为什么不运行它?然后阅读java文档,了解各种方法调用的作用。对不起,我目前不在桌面计算机上,所以现在无法尝试,但我肯定会尽快尝试。