Axel Jonsson
Axel Jonsson

Reputation: 37

JavaFX button handle() not calling methods

This seems like it is a very basic issue and that the answer is right in front of me, but I still can't figure out what's wrong. I have a button, and when handling the click event I change the style and text of a Label. After that, I call a method which changes the style once again when finished.

My problem is that the style changes in the handle() method does not affect my label, and instead it goes straight from its default style to the style set by connect().

Mind you that it's not because it changes too fast, the connect() method usually takes a full second or so to complete as it connects to a remote server.

I tried sleeping the thread for a second (in case my were too slow) inbetween setStyle() and connect(), but to no avail. I would greatly appreciate any help, and hopefully learn something along the way.

This is my code:

Button loginButton = new Button();

    loginButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            loginStatus.setText("Loggin in...");

            //The line below should change the color until connect does it's thing, but it doesn't
            loginStatus.setStyle("-fx-text-fill:#ffcc00"); 

            connect(username.getText(), password.getText(), serverField.getText());
        }
    });

And connect() looks like this:

private void connect(String username, String password, String server) {
    try {
        api = new DiscordBuilder(username, password).build();
        api.login();
        api.joinInviteId(server);
        api.getEventManager().registerListener(new ChatListener(api));

        //Instead, it goes straight from the old style to the style set below.
        loginStatus.setStyle("-fx-text-fill:#009933");

        loginStatus.setText("Online");
    } catch (NoLoginDetailsException e) {
        loginStatus.setText("No login details!");
        loginStatus.setStyle("-fx-text-fill:#cc3300");
        e.printStackTrace();
    } catch (BadUsernamePasswordException e) {
        loginStatus.setText("Bad username or password!");
        loginStatus.setStyle("-fx-text-fill:#cc3300");
        e.printStackTrace();
    } catch (DiscordFailedToConnectException e) {
        loginStatus.setText("Failed to connect!");
        loginStatus.setStyle("-fx-text-fill:#cc3300");
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Upvotes: 0

Views: 930

Answers (1)

guleryuz
guleryuz

Reputation: 2734

what you need is Task.

also as stated here

Implementing long-running tasks on the JavaFX Application thread inevitably makes an application UI unresponsive. A best practice is to do these tasks on one or more background threads and let the JavaFX Application thread process user events.

so your code should look like this

    Button loginButton = new Button();
    loginButton.setOnAction(new EventHandler<ActionEvent>() {
        @Override
        public void handle(ActionEvent event) {
            loginStatus.setText("Loggin in...");
            //The line below should change the color until connect does it's thing, but it doesn't
            loginStatus.setStyle("-fx-text-fill:#ffcc00"); 
            Task<Void> task = new Task<Void>() {
                @Override
                protected Void call() throws Exception {
                    connect(username.getText(), password.getText(), serverField.getText());
                    return null;
                }
            };
            new Thread(task).start();
        }
    });

and in your connect method surround your ui updating methods with Platform.runLater

Platform.runLater(() -> {
    loginStatus.setStyle("-fx-text-fill:#009933");
    loginStatus.setText("Online");
}) ;

Upvotes: 1

Related Questions