使用多线程在特定时间内更改javafx圆圈的颜色
我正在用javafx创建交通灯模拟器,它使用多线程的概念,每2秒钟改变一次颜色(第一个红灯闪烁并保持2秒钟)。我的代码如下所示。但它并没有像预期的那样起作用。它只是闪烁着所有的灯光,有人能帮我找出哪里出了问题吗?谢谢使用多线程在特定时间内更改javafx圆圈的颜色,java,multithreading,javafx,java-threads,Java,Multithreading,Javafx,Java Threads,我正在用javafx创建交通灯模拟器,它使用多线程的概念,每2秒钟改变一次颜色(第一个红灯闪烁并保持2秒钟)。我的代码如下所示。但它并没有像预期的那样起作用。它只是闪烁着所有的灯光,有人能帮我找出哪里出了问题吗?谢谢 public void startThreads() throws InterruptedException { Runnable taskOne = new Runnable(){ @Override public void run(){
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();
}
从
等待此线程死亡
这意味着
thread1.start();
thread1.join();
与之相比没有任何好处
taskOne.run();
因为这会停止调用join
的方法的执行,直到线程完成
通过使用时间线
,您可以以更优雅的方式实现您想要做的事情:
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();
您可能需要调整第三个关键帧的持续时间。Duration
参数指定从动画开始的时间。EventHandler
s在JavaFX应用程序线程上执行,不能包含长时间运行的代码,如thread.sleep
。您可能需要从添加附加的关键帧
等待此线程死亡
这意味着
thread1.start();
thread1.join();
与之相比没有任何好处
taskOne.run();
因为这会停止调用join
的方法的执行,直到线程完成
通过使用时间线
,您可以以更优雅的方式实现您想要做的事情:
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();
您可能需要调整第三个关键帧的持续时间。Duration
参数指定从动画开始的时间。EventHandler
s在JavaFX应用程序线程上执行,不能包含长时间运行的代码,如thread.sleep
。你可能需要添加额外的关键帧
s.我对如何实现这一点感到困惑,老实说,我同意塞德里克的观点,查看一下JavaFX动画课程,但我觉得很无聊,所以我做了这项工作,当然还有更好的方法来实现这一点,但我尽了最大努力,尽可能多地保留代码,因为你想从这只是再看一次它的p,r,e,t,t,y,m,u,c,h,只有变量名lol
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); }
}
public类主扩展应用程序{
私人圈子;
私人圈子1;
私人圈子2;
私有HashMap colorHashMap=新HashMap();
private HashMap counterHashMap=new HashMap();
@凌驾
公众假期开始(阶段){
圆圈=新圆圈(15,15,30,颜色为绿色);
colorHashMap.put(圆圈、颜色、绿色);
counterHashMap.put(圆圈,3);//开始
圆圈1=新圆圈(15,45,30,颜色为灰色);
colorHashMap.put(圆圈1,颜色为黄色);
counterHashMap.put(圈1,2);
圆圈2=新圆圈(15,60,30,颜色为灰色);
colorHashMap.put(圆圈2,颜色为红色);
counterHashMap.put(圈2,1);
VBox VBox=新的VBox();
vBox.getChildren().addAll(圆圈、圆圈1、圆圈2);
场景=新场景(vBox);
阶段=新阶段();
舞台场景;
stage.show();
试一试{
startThreads();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
私有void startThreads()引发InterruptedException{
新线程(()->{
while(true){
flipColor(圆形);
flipColor(圆圈1);
flipColor(圆圈2);
试一试{
《睡眠》(2000年);
}捕捉(中断异常e){
e、 printStackTrace();
}
}
}).start();
}
私有void flipColor(圆形){
if(counterHashMap.get(圆)%3==0){
Platform.runLater(()->circle.setFill(colorHashMap.get(circle));
counterHashMap.put(圆圈,1);
}
否则{
如果(!circle.getFill().equals(Color.GREY))
Platform.runLater(()->circle.setFill(Color.GREY));
counterHashMap.put(圆,counterHashMap.get(圆)+1);
}
}
公共静态void main(字符串[]args){launch(args);}
}
我对如何诚实地完成这项工作感到困惑,我同意塞德里克的观点,请查看JavaFX动画课程,但我很无聊,所以我完成了这项工作,当然还有更好的方法,但我尽了最大努力,尽可能多地保留代码,因为你想从中受益。只是再看一次它的p,r,e,t,t,y,m,u,c,h,只有变量名lol
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); }
}
public类主扩展应用程序{
私人圈子;
私人圈子1;
私人圈子2;
私有HashMap colorHashMap=新HashMap();
private HashMap counterHashMap=new HashMap();
@凌驾
公众假期开始(阶段){
圆圈=新圆圈(15,15,30,颜色为绿色);
colorHashMap.put(圆圈、颜色、绿色);
counterHashMap.put(圆圈,3);//开始
圆圈1=新圆圈(15,45,30,颜色为灰色);
colorHashMap.put(圆圈1,颜色为黄色);
counterHashMap.put(圈1,2);
圆圈2=新圆圈(15,60,30,颜色为灰色);
colorHashMap.put(圆圈2,颜色为红色);
counterHashMap.put(圈2,1);
VBox VBox=新的VBox();
vBox.getChildren().addAll(圆圈、圆圈1、圆圈2);
场景=新场景(vBox);
阶段=新阶段();
舞台场景;
stage.show();
试一试{
startThreads();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
私有void startThreads()引发InterruptedException{
新线程(()->{
while(true){
flipColor(圆形);
flipColor(圆圈1);
flipColor(圆圈2);
试一试{
《睡眠》(2000年);