如何在 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 的实现中考虑这一点。这完全取决于您真正需要什么。
本质上,我试图在 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 的实现中考虑这一点。这完全取决于您真正需要什么。