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

2018-09-03  本文已影响530人  QingMings
1. 问题分析

长按按钮 一直不停的触发事件
分析问题:

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

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

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

触发按钮onAction 事件怎么实现呢,通过翻阅源码发现 Buttonfire() 的方法可以触发 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;
        }
    }
2. 代码实现
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;
        }
    }
}
3. 测试效果
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();
    }
}

15359432933140.jpg
上一篇下一篇

猜你喜欢

热点阅读