如何让 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% 精确。
在我当前的代码中,每次我添加类似 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% 精确。