Sliding Tasks: ReScheduler for JavaFX

In the TouchWheel control I wrote for touch devices, I wanted to have a little “snap to grid” animation after a user scrolled to a value. You can see it in this video:

You get informed of the end of a Scroll Event in JavaFX by an event of EventType “ScrollEvent.SCROLL_FINISHED”. That’s not the last of the SrollEvents you’ll recieve though. ScrollEvent.SCROLL_FINISHED just informs you that the user input is over, but you’ll get more events due to inertia. If you ignore the events due to inertia (ScrollEvent.isInertia()), everything is fine, and you can do what you want. But if you allow inertia in a JavaFX scroll event, you have no way of telling when scrolling is over. The continuous events will simply stop after a while.

I looked around for a helper class that would allow me to coalesce all the events that arrive in a certain period of time and execute the Task just once, but since I didn’t find anything except for the NetBeans RequestProcessor. Since I needed to have a way to do the Animation when the series of events has finished,I created this little ReScheduler:

public class ReScheduler {

    private final Runnable runable;
    private final long delay;
    private TimerTask task;
    private final Timer timer = new Timer();

    public ReScheduler(Runnable runnable, long delay) {
        this.runable = runnable;
        this.delay = delay;
        task = new TimerTask() {
            @Override
            public void run() {
                runable.run();
            }
        };
    }

    public void schedule() {
        task.cancel();
        task = new TimerTask() {
            @Override
            public void run() {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        runable.run();
                    }
                });
            }
        };
        timer.schedule(task, delay);
    }
}

With this little Utility class, you can schedule a Runnable as often as you like. If you schedule it again before a time period indicated by the delay, the old task will be canceled, and only if there is no new call before the specified delay, the task will be executed. It’s quite handy for tasks like this, although I’d prefer to have an event of EventType ScrollEvent.INERTIA_FINISHED.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>