【问题标题】:How to make shape move while button is being pressed JavaFx按下按钮时如何使形状移动JavaFx
【发布时间】:2017-03-04 20:59:58
【问题描述】:

在按下按钮时,我试图让一个圆圈移动到我逐像素定义的方向。到目前为止,我已经设法让它通过这部分的每次点击移动一个像素:

button1.addEventHandler(MouseEvent.MOUSE_PRESSED,
                new EventHandler<MouseEvent>(){
            public void handle(MouseEvent e){
newX = pallo.getTranslateX()+ 1 ;
                pallo.setTranslateX(newX);

            }
        });

pallo 是这里的圆圈,而 button1 是导致它移动的按钮。我一直在阅读有关计时器方法的信息https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html,但我无法理解我应该输入什么来重复序列,比如每 10 毫秒一次,只有在按下按钮时。 有人可以为我提供将功能更改为我所寻求的功能的固定代码,以便我可以尝试理解它吗?

【问题讨论】:

  • 创建动画,例如带有AnimationTimer。按下按钮时启动,松开按钮时停止。

标签: java javafx timer eventhandler


【解决方案1】:

如果您想坚持使用 Timer 课程,您可以执行以下操作:

public class TimerExample {

    private final Timer timer = new Timer();
    private TimerTask timerTask;

    public void setUpButton(Button btn, Circle cir) {
        btn.addEventHandler(MouseEvent.MOUSE_PRESSED, me -> {
            timerTask = new TimerTask() {

                @Override
                public void run() {
                    Platform.runLater(() 
                         -> circle.setTranslateX(circle.getTranslateX() + 1);
                }

            };
            timer.schedule(timerTask, 0L, 10L);
        });

        btn.addEventHandler(MouseEvent.MOUSE_RELEASED, me -> {
            timerTask.cancel();
            timerTask = null;
            timer.purge(); // So TimerTasks don't build up inside the Timer
                           // I'm not 100% sure this must/should be called
                           // every time
        });
    }
}

使用Timer 时,您必须安排TimerTasks 使用它。如您所见,我使用了timer.schedule(timerTask, 0L, 10L),这意味着timerTask 将在0 milliseconds 的初始延迟之后运行,然后是每个10 milliseconds。此调度发生在按下按钮时。释放鼠标时,TimerTask 被取消(不会再次运行),然后我将变量设置为 null 并清除 Timer 以删除对 TimerTask 的任何引用。

run 方法中,您必须操作Platform.runLater(Runnable) 中的圆圈,因为不会在FxApplication 线程上调用TimerTask

就个人而言,如果坚持使用计时器之类的东西,我更愿意使用javafx.animation.AnimationTimer。这是因为AnimationTimerhandle(long) 方法在FxApplication 线程上每帧调用一次。

类似这样的:

public class AnimationTimerExample {

    public void setUpButton(Button btn, Circle circle) {
        AnimationTimer timer = new AnimationTimer() {

            private final long delay = 10_000_000L; // This must be in 
                                                    // nanoseconds
                                                    // since "now" is in
                                                    // nanoseconds
            private long lastExecution;

            @Override
            public void handle(long now) {
                if (now - (lastExecution + delay) <= 0L {
                    // Move circle
                    lastExecution = now;
                }
            }

        };

        btn.addEventHandler(MouseEvent.MOUSE_PRESSED, me -> timer.start());
        btn.addEventHandler(MouseEvent.MOUSE_RELEASED, me -> timer.stop());
    }
}

这里你必须根据延迟手动计算何时运行,但这可以避免任何线程问题。

【讨论】:

  • 收听the pressed property 会更方便,因为它已经检查是否使用主鼠标按钮而不是对任意鼠标按钮做出反应...
猜你喜欢
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多