Java,for循环中的更新阶段

Java,for循环中的更新阶段,java,javafx,Java,Javafx,我制作了一个创建图像的Java应用程序。我想把一个for循环中的代码放到另一个for循环中,每次代码完成并返回到第一个for循环时更新stage/screen,但是如果我把它们放到第一个for循环中,使用setScene方法和show方法似乎没有什么帮助 对于下面的示例,我希望圆形绘图是自己绘制的,而不是单击。我想每100毫秒使用thread.sleep方法 package javaFX; import java.awt.Dimension; import java.awt.Toolkit;

我制作了一个创建图像的Java应用程序。我想把一个for循环中的代码放到另一个for循环中,每次代码完成并返回到第一个for循环时更新stage/screen,但是如果我把它们放到第一个for循环中,使用setScene方法和show方法似乎没有什么帮助

对于下面的示例,我希望圆形绘图是自己绘制的,而不是单击。我想每100毫秒使用thread.sleep方法

package javaFX;

import java.awt.Dimension;
import java.awt.Toolkit;

import javafx.application.Application;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class circles extends Application {

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    double WIDTH = screenSize.getWidth() - 80;
    double HEIGHT = screenSize.getHeight() - 80;

    @Override
    public void start(Stage primaryStage) {
        Group root = new Group();
        Scene scene = new Scene(root, WIDTH, HEIGHT, Color.WHITE);
        Canvas canvas = new Canvas(WIDTH, HEIGHT);
        root.getChildren().add(canvas);
        GraphicsContext graphics = canvas.getGraphicsContext2D();
        primaryStage.setTitle("Circles!");

        canvas.setOnMouseClicked(clickEvent -> {
            for (int i = 0; i < 50; i++) {
                double ran = Math.random() * WIDTH;
                double nu = Math.random()*1000;
                int ranNum = (int) nu;
                graphics.strokeOval(ran, ran, ran, ran);
            }
        });     
        primaryStage.setScene(scene);
        primaryStage.setResizable(false);
        primaryStage.show();
    }
}
packagejavafx;
导入java.awt.Dimension;
导入java.awt.Toolkit;
导入javafx.application.application;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
导入javafx.scene.control.Button;
导入javafx.scene.layout.StackPane;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
公共类循环扩展应用程序{
维度screenSize=Toolkit.getDefaultToolkit().getScreenSize();
双宽度=屏幕大小。getWidth()-80;
双倍高度=屏幕大小。getHeight()-80;
@凌驾
公共无效开始(阶段primaryStage){
组根=新组();
场景=新场景(根、宽度、高度、颜色、白色);
画布=新画布(宽度、高度);
root.getChildren().add(画布);
GraphicsContext graphics=canvas.getGraphicsContext2D();
初级阶段。设置标题(“圆圈!”);
canvas.setOnMouseClicked(点击事件->{
对于(int i=0;i<50;i++){
double ran=Math.random()*宽度;
double nu=Math.random()*1000;
int ranNum=(int)nu;
graphics.strokeova(跑,跑,跑,跑);
}
});     
初级阶段。场景(场景);
primaryStage.SetResizeable(假);
primaryStage.show();
}
}

问题已解决!使用
AnimationTimer
,如下所示:

import java.awt.Dimension;
import java.awt.Toolkit;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Testing extends Application {

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    double WIDTH = screenSize.getWidth() - 80;
    double HEIGHT = screenSize.getHeight() - 80;

    @Override public void start(Stage primaryStage) {
        Group root = new Group();
        Scene scene = new Scene(root, WIDTH, HEIGHT, Color.WHITE);
        Canvas canvas = new Canvas(WIDTH, HEIGHT);
        root.getChildren().add(canvas);
        GraphicsContext graphics = canvas.getGraphicsContext2D();
        primaryStage.setTitle("Circles!");

        // canvas.setOnMouseClicked(clickEvent -> {
        // for (int i = 0; i < 50; i++) {
        // double ran = Math.random() * WIDTH;
        // graphics.strokeOval(ran, ran, ran, ran);
        // }
        // });

        primaryStage.setScene(scene);
        primaryStage.setResizable(false);
        primaryStage.show();

        new AnimationTimer() {
            @Override public void handle(long currentNanoTime) {
                for (int i = 0; i < 50; i++) {
                    double ran = Math.random() * WIDTH;
                    graphics.strokeOval(ran, ran, ran, ran);
                }

                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // Do nothing
                }
            }
        }.start();
    }
}
导入java.awt.Dimension;
导入java.awt.Toolkit;
导入javafx.animation.AnimationTimer;
导入javafx.application.application;
导入javafx.scene.Group;
导入javafx.scene.scene;
导入javafx.scene.canvas.canvas;
导入javafx.scene.canvas.GraphicsContext;
导入javafx.scene.paint.Color;
导入javafx.stage.stage;
公共类测试扩展了应用程序{
维度screenSize=Toolkit.getDefaultToolkit().getScreenSize();
双宽度=屏幕大小。getWidth()-80;
双倍高度=屏幕大小。getHeight()-80;
@覆盖公共无效开始(阶段primaryStage){
组根=新组();
场景=新场景(根、宽度、高度、颜色、白色);
画布=新画布(宽度、高度);
root.getChildren().add(画布);
GraphicsContext graphics=canvas.getGraphicsContext2D();
初级阶段。设置标题(“圆圈!”);
//canvas.setOnMouseClicked(点击事件->{
//对于(int i=0;i<50;i++){
//double ran=Math.random()*宽度;
//graphics.strokeova(跑,跑,跑,跑);
// }
// });
初级阶段。场景(场景);
primaryStage.SetResizeable(假);
primaryStage.show();
新的AnimationTimer(){
@重写公共无效句柄(长currentNanoTime){
对于(int i=0;i<50;i++){
double ran=Math.random()*宽度;
graphics.strokeova(跑,跑,跑,跑);
}
试一试{
睡眠(100);
}捕捉(中断异常e){
//无所事事
}
}
}.start();
}
}

JavaFX不会为您更新它。使用while循环之类的东西的问题是JavaFX不知道您已经完成了指令(或者至少,这是我从文档中得到的印象)并开始绘制过程。似乎也不存在手动强制重画的东西。因此,您必须使用AnimationTimer。

请将您的代码添加到问题中,以便人们能够理解此问题并为您提供帮助。您确实不应该在
AnimationTimer中调用
Thread.sleep
(因为这将暂时冻结JavaFX应用程序线程和整个应用程序,包括输入处理和其他动画)。相反,如果您希望定期执行操作,请查看。@jewelsea,同意。但是没有需要担心的输入。冻结应用程序线程对用户没有任何影响,因为线程没有查找任何内容。