user3583419
user3583419

Reputation:

JavaFX Button detecting event as well as time elapsed

I implemented another version of this project with Java Swing, but because it could not support multi-touch functionality, I am rewriting it using JavaFX.

So I want the program to wait either for a user clicks a Button object or for a timeout, say 5 seconds - this means that the program would present a Button on the screen at one point and does not proceed to the next phase until either the Button is pressed or 5 seconds pass without it being pressed.

Clearly, detecting a click is elementary because adding ActionEvent would solve it. The tricky part is measuring the time. When implementing with Swing objects, I would have a while loop and have Thread.sleep(very_short_time_interval) inside to periodically check the elapsed time:

lastUpdate = System.currentTimeMillis();
while ((!pressed) && (System.currentTimeMillis() - lastUpdate <= timeout)) {
    Thread.sleep(50);
}

The purpose of the Thread.sleep() in the pseudo-code above was to prevent the while loop from executing too often. Though it does not seem like the best practice, this trick apparently worked when used with Swing objects. But I realized after trying out the same thing with JavaFX Button objects, it turns the shape of the mouse pointer to a circulating ring, indicating the process is busy on Windows. What is worse is the button would not recognize mouse inputs during this busy phase. I am guessing JavaFX objects are heavier than Swing objects and is causing this problem as a result.

So my question is, would there be another way, possibly native function in JavaFX to make a Button expire without requiring a while loop? Or would there be some lighter weight objects than Button that works in a similar manner (listening to mouse clicks) that could work with the original while approach?

Upvotes: 0

Views: 700

Answers (1)

ItachiUchiha
ItachiUchiha

Reputation: 36742

You can use a PauseTransition to wait for n-seconds. On its setOnFinished you can add an action to be performed. If the button has been pressed, you can cancel the transition on its action.

final PauseTransition pt = new PauseTransition(Duration.millis(5000));
pt.setOnFinished( ( ActionEvent event ) -> {
        doSomething();
});
button.setOnAction( (ActionEvent event) -> {
        doSomething();
        pt.stop(); // If the button has been pressed, stop the Transition
});
pt.play();

Upvotes: 1

Related Questions