Rohan
Rohan

Reputation: 561

JavaFX: How to disable a button for a specific amount of time?

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();

Upvotes: 6

Views: 10944

Answers (4)

Uluk Biy
Uluk Biy

Reputation: 49185

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();

Upvotes: 5

Antonio J.
Antonio J.

Reputation: 1760

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.

Upvotes: 0

Michael Berry
Michael Berry

Reputation: 72254

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.

Upvotes: 6

scottb
scottb

Reputation: 10084

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.

Upvotes: 2

Related Questions