如何让 javafx 场景在 15 秒计时器上发生变化?

How do I get a javafx scene to change on a 15 second timer?

在我当前的代码中,每次我添加类似 Platform.runLater 的内容时,它都会崩溃,因为您不能在主场景中使用 Thread.sleep。这是我的工作代码的最后一个实例,我们将不胜感激。

import javafx.application.Platform;
import javafx.animation.KeyFrame;
import javafx.animation.PauseTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
import javafx.scene.Group;
import javafx.scene.Scene;
import java.util.Random;

public class Testing2 extends Application {
    private static final double MAX_X = 1000;
    private static final double MAX_Y = 750;

    private static String Converted = null;
    private int MIN_X2 = 20;
    private int MIN_Y2 = 20;
    private int MAX_X2 = 950;
    private int MAX_Y2 = 700;
    private int clickCount = 0;
    private Random random;
    Random generator = new Random();
    public int Seconds = 15;
    Scene scene, scene2;
    Stage window;

    private final Text text2 = new Text("All Done!");

    public void changeScene(Stage stage) {
        StackPane root2 = new StackPane();
        root2.getChildren().add(text2);
        Scene scene2 = new Scene(root2, 200, 200);
        stage.setScene(scene2);
    }

    public void init() {
        random = new Random();
    }


    @Override
    public void start(Stage primaryStage) throws Exception{
        window = primaryStage;
        Circle circle = new Circle(MAX_X / 2, MAX_Y / 2, 15);//(StartX, StartY, Size)
        Text clickCountText = new Text("Clicks: " + clickCount);
        Text Space = new Text("           ");
        Text label = new Text("");

        circle.setOnMouseClicked((event) -> {

            circle.setCenterX(random.nextInt(MAX_X2 - MIN_X2) + MIN_X2);
            circle.setCenterY(random.nextInt(MAX_Y2 - MIN_Y2) + MIN_Y2);
            circle.getCenterX();
            clickCount ++;
            clickCountText.setText("Clicks: "+ clickCount);



        });


        Group layout = new Group(
                circle,
                new FlowPane(clickCountText, Space, label)
        );





//create 2 strings, convert the number to a string, concat 3 strings and assign to variable, put variable in setText

        PauseTransition pause = new PauseTransition(Duration.seconds(1));

        pause.setOnFinished(event -> {
            String String1 = "There are ";
            String String2 = " Seconds Left";

            for(int n=15; n>=0; n--){
                Converted = Integer.toString(Seconds);
            String String3 = String1 + Seconds + String2;

        }}
        );
        final IntegerProperty i = new SimpleIntegerProperty(16);
        Timeline timeline = new Timeline(
            new KeyFrame(
                Duration.seconds(1),
                event -> {
                    i.set(i.get() - 1);
                    label.setText("You have: " + i.get() + " seconds remaining!");
                }
            )
        );

        timeline.setCycleCount(16);
        timeline.play();


        pause.play();
        primaryStage.setScene(new Scene(layout, MAX_X, MAX_Y, Color.WHITE));
        primaryStage.setResizable(false);
        primaryStage.show();
    }

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

该程序应该生成一个圆圈,当它被点击时,它会将圆圈移动到屏幕上的随机位置。每点击一次,点击次数就会增加一次。一旦计时器达到 0,我希望场景更改为显示文本的屏幕,“您在 15 秒内获得了 __ 次点击!干得好!”。我是通过 eclipse 运行 这个,所以你可以把它粘贴进去试试。

一种不使用线程的简单方法是创建另一个时间轴,就像您创建 timeline 的方式一样,您可以在其中 setScene 为您的 primaryStage,就像这样:

Timeline finishTimeline = new Timeline(
            new KeyFrame(
                Duration.millis(1),
                event -> {
                    StackPane s = new StackPane();
                    s.getChildren().add(new Label("your label here"));
                    Scene scene = new Scene(s, 200, 200);
                    primaryStage.setScene(scene);
                }
            )
        );

请注意,您应该在完成第一个时间线时播放此 finishTimeline,因此您可以使用 SequentialTransition 按顺序播放两个时间线:

SequentialTransition st = new SequentialTransition(timeline, finishTimeline);
st.play();

现在将您的代码修改为 100% 精确。