JAVAFX:How to disable button for specific time?

2019-02-17 15:17发布

I want to disable a button for a specific time in JavaFX application. Is there any option to do this? If not, is there any work around for this?

Below is my code in application. I tried Thread.sleep, but i know this is not the good way to stop the user from clicking on next button.

nextButton.setDisable(true);
final Timeline animation = new Timeline(
        new KeyFrame(Duration.seconds(delayTime),
        new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent actionEvent) {
                nextButton.setDisable(false);
            }
        }));
animation.setCycleCount(1);
animation.play();

标签: javafx-2
4条回答
不美不萌又怎样
2楼-- · 2019-02-17 15:47

You could use the simple approach of a thread that provides the relevant GUI calls (through runLater() of course):

new Thread() {
    public void run() {
        Platform.runLater(new Runnable() {
            public void run() {
                myButton.setDisable(true);
            }
        }
        try {
            Thread.sleep(5000); //5 seconds, obviously replace with your chosen time
        }
        catch(InterruptedException ex) {
        }
        Platform.runLater(new Runnable() {
            public void run() {
                myButton.setDisable(false);
            }
        }
    }
}.start();

It's perhaps not the neatest way of achieving it, but works safely.

查看更多
干净又极端
3楼-- · 2019-02-17 15:48

The method to disable a JavaFX control is:

myButton.setDisable(true);

You can implement the time logic programmatically in any way you wish, either by polling a timer or by having this method invoked in response to some event.

If you have created this button instance through FXML in SceneBuilder, then you should assign the button an fx:id so that its reference is automatically injected into your controller object during the loading of the scene graph. This will make it easier for you to work with in your controller code.

If you have created this button programmatically, then you'll already have its reference available in your code.

查看更多
Ridiculous、
4楼-- · 2019-02-17 15:48

Or you could use a Service and bind the running property to the disableProperty of the button do you want to disable.

public void start(Stage stage) throws Exception {
    VBox vbox = new VBox(10.0);
    vbox.setAlignment(Pos.CENTER);      

    final Button button = new Button("Your Button Name");
    button.setOnAction(new EventHandler<ActionEvent>() {            
        @Override
        public void handle(ActionEvent event) {
            Service<Void> service = new Service<Void>() {                   
                @Override
                protected Task<Void> createTask() {
                    return new Task<Void>() {
                        @Override
                        protected Void call() throws Exception {
                            Thread.sleep(5000);//Waiting time
                            return null;
                        }
                    };
                }
            };
            button.disableProperty().bind(service.runningProperty());               
            service.start();
        }
    });     

    vbox.getChildren().addAll(button);
    Scene scene = new Scene(vbox, 300, 300);
    stage.setScene(scene);
    stage.show();
}

But the Timeline solution given by Uluk Biy, looks more elegant.

查看更多
我只想做你的唯一
5楼-- · 2019-02-17 16:03

You could also be using the Timeline:

  final Button myButton = new Button("Wait for " + delayTime + " seconds.");
  myButton.setDisable(true);

  final Timeline animation = new Timeline(
            new KeyFrame(Duration.seconds(delayTime),
            new EventHandler<ActionEvent>() {
                @Override public void handle(ActionEvent actionEvent) {
                    myButton.setDisable(false);
                }
            }));
  animation.setCycleCount(1);
  animation.play();
查看更多
登录 后发表回答