如何在 JavaFX 中创建一个 run-while-while-button-is-pushed 类型的按钮?

How to create a run-while-button-is-pushed type button in JavaFX?

本质上,我试图在 GUI 上创建一个按钮,当它被按下时每 0.5 秒运行一些语句。目前我已经创建了名为 "Next Generation".

的实际按钮
Button nextGenButton = new Button("Next Generation");

这之后我将如何进行?我假设我必须使用某种事件处理程序?

查看 setOnMousePressed and setOnMouseReleased

您的代码看起来有点像这样:

final Button btn = new Button("Click me!");
btn.setOnMousePressed((event) -> {
    /**
     * Check if this is the first time this handler runs.
     * - If so, start a timer that runs every 0.5 seconds.
     * - If not, do nothing. The timer is already running.
     */
});
btn.setOnMouseReleased((event) -> {
    //Stop the timer.
});

请注意onMousePressed在按下按钮时会重复调用,因此您必须检查它是否是第一次。

可以使用武装属性的按钮。不要使用鼠标或按键事件,否则您将不得不检查所有这些事件。检查动作事件也无济于事,因为它被触发了一次。 G。鼠标被释放。使用武装属性,您还可以覆盖e。 G。当用户在键盘上按下 space 键且按钮具有焦点时按钮将被激活。

使用带有计数器的文本字段的示例,该计数器在按下按钮时增加:

public class ButtonDemo extends Application {

    // counter which increases during button armed state
    int counter = 0;

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

    @Override
    public void start(Stage primaryStage) {

        // create textfield with the counter value as text
        TextField textField = new TextField();
        textField.setAlignment( Pos.CENTER_RIGHT);
        textField.setText( String.valueOf(counter));

        // timeline that gets started and stopped depending on the armed state of the button. event is fired every 500ms
        Timeline timeline = new Timeline(new KeyFrame(Duration.millis(500), actionEvent -> { counter++; textField.setText( String.valueOf(counter)); }));
        timeline.setCycleCount(Animation.INDEFINITE);

        // button which starts/stops the timeline depending on the armed state
        Button button = new Button( "ClickMe");
        button.armedProperty().addListener(new ChangeListener<Boolean>() {

            @Override
            public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {

                System.out.println( "armed: " + newValue);

                if( newValue) {

                    timeline.play();

                } else {

                    timeline.stop();

                }

            }
        });

        // container for nodes
        HBox hBox = new HBox();
        hBox.setSpacing(5.0);
        hBox.getChildren().addAll( button, textField);


        primaryStage.setScene(new Scene( hBox, 640, 480));
        primaryStage.show();
    }

}

请注意,我示例中的事件每 500 毫秒触发一次。所以按钮必须按下至少 500 毫秒。如果您还想在短按按钮时触发事件,则必须在 ChangeListener 的实现中考虑这一点。这完全取决于您真正需要什么。