JavaFX,primaryStage.show()之后的代码,如何?
我的目标是在舞台+场景出现后,每秒钟看到矩形的颜色变化 我研究并尝试了几件事:JavaFX,primaryStage.show()之后的代码,如何?,java,multithreading,javafx,sleep,show,Java,Multithreading,Javafx,Sleep,Show,我的目标是在舞台+场景出现后,每秒钟看到矩形的颜色变化 我研究并尝试了几件事: primaryStage.show()下的代码[查看我的示例代码] primaryStage.setOnShown()或primaryStage.setOnShowing()文件 阶段中的EventHandler 来自场景的EventHandler 带有eventhandler的按钮 一切都是徒劳的。 在大多数情况下,阶段到来,然后程序在背景中执行颜色更改(没有可视化),最后场景出现并显示最终结果。或者版本2:我
- primaryStage.show()下的代码[查看我的示例代码]
- primaryStage.setOnShown()或primaryStage.setOnShowing()文件
- 阶段中的EventHandler
- 来自场景的EventHandler
- 带有eventhandler的按钮
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
GridPane gridPane = new GridPane();
Rectangle[] recs = new Rectangle[10];
for (int i = 0; i < recs.length; i++) {
recs[i] = new Rectangle(30, 30, Color.GREEN);
recs[i].setStroke(Color.BLACK);
gridPane.add(recs[i], i, 0);
}
primaryStage.setTitle("Code after primaryStage.show()");
primaryStage.setScene(new Scene(gridPane, 400, 300));
primaryStage.show();
for (Rectangle rec : recs) {
Thread.sleep(1000);
rec.setFill(Color.ORANGE);
}
}
public static void main(String[] args) {
launch(args);
}
}
包装样品;
导入javafx.application.application;
导入javafx.scene.scene;
导入javafx.scene.layout.GridPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
公共类主扩展应用程序{
@凌驾
public void start(Stage primaryStage)引发异常{
GridPane GridPane=新建GridPane();
矩形[]recs=新矩形[10];
对于(int i=0;i
这里的问题是,您的循环在主应用程序线程上运行,因此它会锁定任何GUI更新,直到更新完成
改为在自己的线程上执行循环,并使用Platform.runLater()
更新每个矩形:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
GridPane gridPane = new GridPane();
Rectangle[] recs = new Rectangle[10];
for (int i = 0; i < recs.length; i++) {
recs[i] = new Rectangle(30, 30, Color.GREEN);
recs[i].setStroke(Color.BLACK);
gridPane.add(recs[i], i, 0);
}
primaryStage.setTitle("Code after primaryStage.show()");
primaryStage.setScene(new Scene(gridPane, 400, 300));
primaryStage.show();
new Thread(() -> {
for (Rectangle rec :
recs) {
try {
Thread.sleep(1000);
Platform.runLater(() -> rec.setFill(Color.ORANGE));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
public static void main(String[] args) {
launch(args);
}
}
在应用程序的后台打开一个新线程,以便UI保持响应
然后,我们可以在try/catch
块中启动您的循环
Platform.runLater(() -> rec.setFill(Color.ORANGE));
使用后台线程时,必须知道不能直接更改UI。这一行告诉JavaFX在JavaFX应用程序线程上执行rec.setFill()
语句
.start();
您已经创建了新的
线程
,这只是它的开始。这里是使用时间线的另一种方法。代码来自
导入java.util.concurrent.AtomicInteger;
导入javafx.animation.KeyFrame;
导入javafx.animation.Timeline;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.scene.scene;
导入javafx.scene.layout.GridPane;
导入javafx.scene.paint.Color;
导入javafx.scene.shape.Rectangle;
导入javafx.stage.stage;
导入javafx.util.Duration;
公共类主扩展应用程序
{
@凌驾
public void start(Stage primaryStage)引发异常
{
GridPane GridPane=新建GridPane();
矩形[]recs=新矩形[10];
对于(int i=0;i{
System.out.println(“在UI线程上每1秒调用一次”);
recs[counter.getAndIncrement()].setFill(Color.ORANGE);
}));
设置循环计数(记录长度);
第二个是玩;
}
公共静态void main(字符串[]args)
{
发射(args);
}
}
谢谢您的详细回答。代码运行良好,易于阅读。
.start();
import java.util.concurrent.atomic.AtomicInteger;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Main extends Application
{
@Override
public void start(Stage primaryStage) throws Exception
{
GridPane gridPane = new GridPane();
Rectangle[] recs = new Rectangle[10];
for (int i = 0; i < recs.length; i++) {
recs[i] = new Rectangle(30, 30, Color.GREEN);
recs[i].setStroke(Color.BLACK);
gridPane.add(recs[i], i, 0);
}
primaryStage.setTitle("Code after primaryStage.show()");
primaryStage.setScene(new Scene(gridPane, 400, 300));
primaryStage.show();
AtomicInteger counter = new AtomicInteger();
Timeline oneSecondsWonder = new Timeline(new KeyFrame(Duration.seconds(1), (ActionEvent event) -> {
System.out.println("this is called every 1 second on UI thread");
recs[counter.getAndIncrement()].setFill(Color.ORANGE);
}));
oneSecondsWonder.setCycleCount(recs.length);
oneSecondsWonder.play();
}
public static void main(String[] args)
{
launch(args);
}
}