Mr Baloon
Mr Baloon

Reputation: 2766

How to disable a button while processing

How can I disable a JavaFX button while something is processing (to prevent user from spamming the button)?

primaryStage.setTitle("Update Stuff");

Label lbl = new Label();
lbl.setText("Nothing here yet");

Button btn = new Button();
btn.setText("Update");
btn.setOnAction(new EventHandler<ActionEvent>() {

    @Override
    public void handle(ActionEvent event) {
        btn.setDisable(true); //I tried this, but to no avail
        lbl.setText(getNumberOfViewers()); // this might take a few seconds, need to disable button during this time
        btn.setDisable(false);
    }
});

VBox root = new VBox();
root.setAlignment(Pos.CENTER);
root.getChildren().addAll(btn, lbl);
primaryStage.setScene(new Scene(root, 200, 100));
primaryStage.show();

Upvotes: 1

Views: 1984

Answers (2)

WillBD
WillBD

Reputation: 1919

Based off of your code you posted, it would be something like this in javafx 8:

primaryStage.setTitle("Update Stuff");

Label lbl = new Label();
lbl.setText("Nothing here yet");

Button btn = new Button();
btn.setText("Update");
btn.setOnAction(new EventHandler<ActionEvent>() {

    @Override
    public void handle(ActionEvent event) {
        btn.setDisable(true);
        new Thread(()->{
            final String numberOfViews =  getNumberOfViewers();
            Platform.runLater(()->{
                lbl.setText(numberOfViews);
                btn.setDisable(false);
            });                   
        }).start();
        lbl.setText(getNumberOfViewers()); // this might take a few seconds, need to disable button during this time
    }
});

VBox root = new VBox();
root.setAlignment(Pos.CENTER);
root.getChildren().addAll(btn, lbl);
primaryStage.setScene(new Scene(root, 200, 100));
primaryStage.show();

The new thread will make it so that the UI thread is never actually blocked (and windows doesn't give you that nasty 'the application has stopped responding' business), and then inside the thread, anytime you want to change something on the GUI, use the Platform.runLater() syntax, technically you are making a new 'Runnable' object inside of the runLater method, but thanks to lambda expressions, you don't need to worry about that! If you don't use the Platform.runLater() you'll get a 'not on the Javafx application Thread' exception when you try to update stuff.

Also worth noting, I think in javafx 2.* (java 7) it's btn.setEnable(false) instead of btn.setDisable(true) just a change of how they went about it. same effect.

Upvotes: 2

rert588
rert588

Reputation: 769

use the f.f.g code

btn.setEnabled(false);

within the handle method, then after:

btn.setEnabled(true);

Upvotes: 0

Related Questions