我正在用javafx创建交通信号灯模拟器,它使用多线程的概念每2秒更改一次颜色(第一个红灯闪烁并保持2秒)。我有我的代码如下。但是它没有按预期工作。它只会闪烁所有指示灯,直到有人可以帮助我弄清楚我出了什么问题吗?谢谢
public void startThreads() throws InterruptedException {
Runnable taskOne = new Runnable(){
@Override
public void run(){
try {
Platform.runLater(new Runnable() {
@Override
public void run() {
circle.setFill(Color.RED);
circle1.setFill(Color.GREY);
circle2.setFill(Color.GREY);
}
});
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Runnable taskTwo ......
Runnable taskThree .....
Thread thread1 = new Thread(taskOne);
Thread thread2 = new Thread(taskTwo);
Thread thread3 = new Thread(taskThree);
//Start thread 1
thread1.start();
thread1.join();
//start thread 2
thread2.start();
thread2.join();
//Start thread 3
thread3.start();
thread3.join();
}
答案 0 :(得分:3)
等待该线程死亡。
这是
thread1.start();
thread1.join();
与相比,没有提供任何好处
taskOne.run();
因为这将停止执行调用join
的方法,直到Thread
完成为止。
通过使用Timeline
,可以以更加优雅的方式实现您正在尝试做的事情:
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, evt -> {
circle.setFill(Color.RED);
circle1.setFill(Color.GREY);
circle2.setFill(Color.GREY);
}),
new KeyFrame(Duration.seconds(2), evt -> {
// TODO: GUI modifications for second state
}),
new KeyFrame(Duration.seconds(4), evt -> {
// TODO: GUI modifications for third state
})
);
timeline.play();
您可能需要调整第三个KeyFrame
的持续时间。 Duration
参数指定从动画开始开始的时间。 EventHandler<ActionEvent>
在JavaFX应用程序线程上执行,并且不得包含长时间运行的代码,例如Thread.sleep
。您可能需要添加其他KeyFrame
。
答案 1 :(得分:1)
我对如何诚实地进行这项工作感到非常困惑,我同意Sedrick签出JavaFX Animation类的经验,但是我很无聊,所以我完成了这项工作,当然也有更好的方法可以做到这一点,但是我尽了最大努力去保留尽可能多的代码,因为您想从中学习。只是再次看了看它的p̶r̶e̶t̶t̶y̶̶m̶u̶c̶h̶只有变量名大声笑
public class Main extends Application {
private Circle circle;
private Circle circle1;
private Circle circle2;
private HashMap<Circle,Color> colorHashMap = new HashMap<>();
private HashMap<Circle,Integer> counterHashMap = new HashMap<>();
@Override
public void start(Stage stage) {
circle = new Circle(15, 15,30, Color.GREEN);
colorHashMap.put(circle,Color.GREEN);
counterHashMap.put(circle, 3);//Start On
circle1 = new Circle(15, 45,30, Color.GREY);
colorHashMap.put(circle1,Color.YELLOW);
counterHashMap.put(circle1, 2);
circle2 = new Circle(15, 60,30, Color.GREY);
colorHashMap.put(circle2,Color.RED);
counterHashMap.put(circle2, 1);
VBox vBox = new VBox();
vBox.getChildren().addAll(circle,circle1,circle2);
Scene scene = new Scene(vBox);
stage = new Stage();
stage.setScene(scene);
stage.show();
try {
startThreads();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void startThreads() throws InterruptedException {
new Thread(()->{
while (true) {
flipColor(circle);
flipColor(circle1);
flipColor(circle2);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
private void flipColor(Circle circle){
if(counterHashMap.get(circle)%3==0) {
Platform.runLater(()->circle.setFill(colorHashMap.get(circle)));
counterHashMap.put(circle,1);
}
else {
if(!circle.getFill().equals(Color.GREY))
Platform.runLater(()->circle.setFill(Color.GREY));
counterHashMap.put(circle,counterHashMap.get(circle)+1);
}
}
public static void main(String[] args) { launch(args); }
}
答案 2 :(得分:1)
这里是一个使用MCVE的Timeline。要获得不同的持续时间,请使用@fabian Timeline
示例。此示例对所有灯的持续时间为2秒。
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
*
* @author blj0011
*/
public class TrafficLightsFX extends Application
{
String currentLight = "GREEN";
@Override
public void start(Stage primaryStage)
{
//Light GUI
//https://www.color-hex.com/color-palette/35021
String COLOR_GREEN_DARK = "#008000";
String COLOR_GREEN = "47C746";
String COLOR_YELLOW_DARK = "CA7602";
String COLOR_YELLOW = "FFFF40";
String COLOR_RED_DARK = "A30504";
String COLOR_RED = "FF0000";
Circle red = new Circle(25, Color.valueOf(COLOR_RED_DARK));
Circle green = new Circle(25, Color.valueOf(COLOR_GREEN_DARK));
Circle yellow = new Circle(25, Color.valueOf(COLOR_YELLOW_DARK));
VBox trafficLight = new VBox(red, yellow, green);
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(2), (ActionEvent event) -> {
switch (currentLight) {
case "GREEN":
red.setFill(Color.valueOf(COLOR_RED_DARK));
green.setFill(Color.valueOf(COLOR_GREEN));
currentLight = "YELLOW";
break;
case "RED":
yellow.setFill(Color.valueOf(COLOR_YELLOW_DARK));
red.setFill(Color.valueOf(COLOR_RED));
currentLight = "GREEN";
break;
case "YELLOW":
green.setFill(Color.valueOf(COLOR_GREEN_DARK));
yellow.setFill(Color.valueOf(COLOR_YELLOW));
currentLight = "RED";
break;
}
}));
timeline.setCycleCount(Timeline.INDEFINITE);
Button btn = new Button();
btn.setText("Start");
btn.setOnAction((ActionEvent event) -> {
switch (timeline.getStatus()) {
case STOPPED:
case PAUSED:
timeline.play();
break;
case RUNNING:
timeline.pause();
break;
}
});
VBox root = new VBox(new StackPane(trafficLight), btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
}