0

I want to achieve something like this: user press the login button and then label shows: "Connecting."
0.5 sec time interval
"Connecting.."
0.5 sec time interval
"Connecting..."
etc

Just a visual effect that indicates something is actually going on "under the hood".

All I managed to get wasn't quite what I was expecting. I click the button, wait 1.5 sec and then I got "Connecting...", missing 2 previous steps.

First, my Status class

public class Status {
    private static StringProperty status = new SimpleStringProperty();

    public static void setStatus(String newStatus) {
        status.setValue(newStatus);
    }

    public static String getStatus() {
        return status.getValue();
    }

    public static StringProperty get() {
        return status;
    }
}

and my LoginView class

public class LoginView extends Application {

   private Button loginButton = new Button("Log in");
   private Label statusLabel;

   private void createLabels() {        
      statusLabel = new Label(Status.getStatus());
      statusLabel.textProperty().bind(Status.get());
   }

}  

 private void createButtons() {        
        loginButton.setOnAction(e -> {
            try {
                Status.setStatus("Connecting.");
                Thread.sleep(500);
                Status.setStatus("Connecting..");
                Thread.sleep(500);
                Status.setStatus("Connecting...");
                Thread.sleep(500);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        });
    }
user9309329
  • 313
  • 3
  • 13

2 Answers2

2

Run a Task from a different thread. Task allows you to update it's message property on the JavaFX application thread that should be used to update the GUI and must not be blocked by long-running tasks, since it's responsible for rendering:

Task<Void> task = new Task<Void>() {

    @Override
    protected Void call() throws InterruptedException {
        updateMessage("Connecting.");
        Thread.sleep(500);
        updateMessage("Connecting..");
        Thread.sleep(500);
        updateMessage("Connecting...");
        Thread.sleep(500);

        return null;
    }

};

// bind status to task's message
Status.get().bind(task.messageProperty());

// run task on different thread
new Thread(task).start();
fabian
  • 80,457
  • 12
  • 86
  • 114
1

You should do animations with the Timeline API. Have a look here:

https://docs.oracle.com/javase/8/javafx/api/javafx/animation/Timeline.html

Basically you just define KeyFrames at 0.5 seconds distance and set the value of the text to add a another dot. You can also make it repeat indefinitely until the connection is established to get cyclic animation.

Another way is to make a SequentialTransition which will have two PauseTransitions of 0.5 seconds.

BTW in your code you pause the main UI thread and that is why you can’t see the animation.

vl4d1m1r4
  • 1,688
  • 12
  • 21