JavaFx - 按下Button 一直触发按钮事件

Posted 程序员牧码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaFx - 按下Button 一直触发按钮事件相关的知识,希望对你有一定的参考价值。

问题分析

长按按钮 一直不停的触发事件

分析问题

  1. 需要监听鼠标按下事件。
  2. 需要在监听到鼠标按下时候一直触发 按钮的 onAction 事件。

监听按钮的鼠标按下事件很简单,代码如下

myBtn.addEventFilter(MouseEvent.ANY, event -> {
            if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
               // Todo  
            } else {
               // Todo
            }
        });

触发按钮onAction 事件怎么实现呢,通过翻阅源码发现 Button 有 fire() 的方法可以触发 ActiveEvent,代码如下

myBtn.fire();

如何一直触发事件呢,这里利用javafx 的 AnimationTimer 来做这件事,通过翻阅源码可以看到AnimationTimer是一个抽象类,javadoc上说,这个类允许创建一个Timer,并且在每一帧都会去调用它的 handle方法,我们可以利用它来实现一直触发事件。

/**
 * The class {@code AnimationTimer} allows to create a timer, that is called in
 * each frame while it is active.
 *
 * An extending class has to override the method {@link #handle(long)} which
 * will be called in every frame.
 *
 * The methods {@link AnimationTimer#start()} and {@link #stop()} allow to start
 * and stop the timer.
 *
 *
 * @since JavaFX 2.0
 */
public abstract class AnimationTimer

通过继承 AnimationTimer 实现一个执行按钮事件的Timer

class ExecuteTimer extends AnimationTimer {
        private long lastUpdate = 0L;
        private Button mbtn;

        public ExecuteTimer(Button button) {
            this.mbtn = button;
        }

        @Override
        public void handle(long now) {
            if (this.lastUpdate > 100) {
            // 当按钮被按下的时候 触发 按钮事件
                if (mbtn.isPressed()) {
                    mbtn.fire();
                }
            }
            this.lastUpdate = now;
        }
    }

代码实现

import javafx.animation.AnimationTimer;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;

/**
 * 按钮按下时候一直执行 action事件
 */
public class WhileButton extends Button {
    private ExecuteTimer timer = new ExecuteTimer(this);

    public WhileButton() {
        this.addEventFilter(MouseEvent.ANY, event -> {
            if (event.getEventType() == MouseEvent.MOUSE_PRESSED) {
                timer.start();
            } else {
                timer.stop();
            }
        });
    }

    class ExecuteTimer extends AnimationTimer {
        private long lastUpdate = 0L;
        private Button mbtn;

        public ExecuteTimer(Button button) {
            this.mbtn = button;
        }

        @Override
        public void handle(long now) {
            if (this.lastUpdate > 100) {
                if (mbtn.isPressed()) {
                    mbtn.fire();
                }
            }
            this.lastUpdate = now;
        }
    }
}

测试效果

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class TestWhileButton extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        WhileButton btn = new WhileButton();
        btn.setText("按下一直执行");
        btn.setOnAction(event -> System.out.println("hehe"));
        Scene scene = new Scene(new StackPane(btn), 300, 250);
        stage.setTitle("Hello World!");
        stage.setScene(scene);
        stage.show();
    }
}

以上是关于JavaFx - 按下Button 一直触发按钮事件的主要内容,如果未能解决你的问题,请参考以下文章

在 javafx 中悬停并按下

如果按下键,则不会触发鼠标交互的 JavaFX 事件

用python tkinter 做界面时,怎么实现键盘按下回车键后,触发某个button按钮?

javafx:如何将Enter键绑定到按钮并在单击时触发事件?

当根据文本框的焦点按下 Enter 键时,如何触发 Button Click 事件?

Delphi6 如何给button按钮添加快捷键(回车)