简体   繁体   English

由于单击按钮而调用JavaFX AnimationTimer时无法启动

[英]JavaFX AnimationTimer doesn't start when it is called as a result of a Button click

I am trying to add a 'start' button to a small animation of the earth orbiting the sun. 我正在尝试向围绕太阳旋转的地球的小动画添加“开始”按钮。 My problem is the AnimationTimer never seems to recieve the start() call when I click the button. 我的问题是,当我单击按钮时,AnimationTimer似乎从未收到过start()调用。

When the Event for clicking the button is fired the animation timer should start, thus making graphics context (which is on the canvas) start to be drawled on. 触发单击按钮的事件时,动画计时器应启动,从而开始绘制图形上下文(在画布上)。

I'm sure I've made a stupid mistake somewhere, but for the life of me I can't figure it out. 我敢肯定我在某个地方犯了一个愚蠢的错误,但是对于我的一生,我无法弄清楚。

Here's the code: 这是代码:

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();
    }
}

Your canvas is on top of the button, preventing the button from receiving mouse events. 您的画布在按钮上方,以防止按钮接收鼠标事件。

You can either: 您可以:

reverse the order you add the components, so that the button appears on top of the canvas: 反转添加组件的顺序,以使按钮出现在画布顶部:

    root.getChildren().addAll(canvas, btn);

or make the canvas mouse-transparent (assuming you don't want to process mouse events on it): 或使画布鼠标透明(假设您不想在其上处理鼠标事件):

    canvas.setMouseTransparent(true);

or use a VBox instead of a Group , so the components don't overlay each other: 或使用VBox代替Group ,这样组件之间不会相互重叠:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM