JavaFX AnimationTimer在由于按钮单击而被调用时不会启动

JavaFX AnimationTimer在由于按钮单击而被调用时不会启动,java,javafx,Java,Javafx,我试图在地球绕太阳运行的小动画中添加一个“开始”按钮。我的问题是,当我点击按钮时,AnimationTimer似乎从未收到开始调用 当点击按钮的事件被触发时,动画定时器应该启动,从而使画布上的图形上下文开始绘制 我肯定我在某个地方犯了一个愚蠢的错误,但以我的生命来说,我无法理解它 代码如下: import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Group; import jav

我试图在地球绕太阳运行的小动画中添加一个“开始”按钮。我的问题是,当我点击按钮时,AnimationTimer似乎从未收到开始调用

当点击按钮的事件被触发时,动画定时器应该启动,从而使画布上的图形上下文开始绘制

我肯定我在某个地方犯了一个愚蠢的错误,但以我的生命来说,我无法理解它

代码如下:

import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.control.Button;
import javafx.animation.AnimationTimer;

public class Orbit extends Application {

    private static int WINDOW_WIDTH  = 500;
    private static int WINDOW_HEIGHT = 500;

    private static int EARTH_RADIUS = 100;
    private static int EARTH_ORBIT_RADIUS = 128;

    private static int SUN_RADIUS = 100;

    public static void main(String[] args) { launch(args); }

    public void start(Stage stage) {
        stage.setTitle("Orbit");

        Group root = new Group();
        Scene theScene = new Scene(root);
        stage.setScene(theScene);

        Canvas canvas = new Canvas(WINDOW_WIDTH, WINDOW_HEIGHT);

        GraphicsContext gc = canvas.getGraphicsContext2D();

        Image earth = new Image("earth.png", EARTH_RADIUS, EARTH_RADIUS, false, false)
            , sun   = new Image("sun.png", SUN_RADIUS, SUN_RADIUS, false, false)
            , space = new Image("space.png");

        final long startNanoTime = System.nanoTime();

        final AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long currentNanoTime) {
                double t = (currentNanoTime - startNanoTime) / 1000000000.0;

                int centerX = (WINDOW_WIDTH - SUN_RADIUS) / 2
                  , centerY = (WINDOW_HEIGHT - SUN_RADIUS) / 2;

                double x = centerX + EARTH_ORBIT_RADIUS * Math.cos(t)
                     , y = centerY + EARTH_ORBIT_RADIUS * Math.sin(t);

                gc.drawImage(space, 0, 0);
                gc.drawImage(earth, x, y);
                gc.drawImage(sun, centerX, centerY);
            }
        };

        Button btn = new Button("Start");
        btn.setOnMousePressed(actionEvent -> timer.start());

        root.getChildren().addAll(btn, canvas);
        stage.show();
    }
}

画布位于按钮的顶部,防止按钮接收鼠标事件

您可以:

颠倒添加组件的顺序,使按钮显示在画布顶部:

    root.getChildren().addAll(canvas, btn);
或者使画布鼠标透明,假设您不想在其上处理鼠标事件:

    canvas.setMouseTransparent(true);
或者使用VBox而不是组,这样组件就不会相互重叠:

    // Group root = new Group();
    VBox root = new VBox();

谢谢你的帮助,伙计。