There are some really poor suggestions on this thread.
Don't run a busy loop with a counter that goes to a million on the JavaFX thread, it will hang your app periodically.
Similarly, don't call Thread.sleep on the JavaFX application thread, it will also hang your app periodically.
For most operations in JavaFX, you need to relinquish control of the JavaFX application thread, so that the system can take action on the commands which you have issued. Not doing so just hangs the UI and application and, in addition, it doesn't do what you expect. It doesn't do the first thing, then pause, then do the next thing. Instead, the system just buffers up all the things you asked it to do, and only executes them all at once after you release control back to the system.
Knute's suggestion to use a Task which runs a separate thread which does the pauses, then a runLater call to execute the event at each period, does at least fix one of the main problems occurring here by shifting the pause into its own thread rather than in the JavaFX application thread.
If you want a delay for a period in JavaFX, where something happens after a period, one way to accomplish that is to use a PauseTransition with a setOnFinished call:
An advantage of this over a task-based approach which spawns another thread is that there is no other user thread involved, so you have less concurrent code to manage and worry about, which is pretty much always a good thing.
For more complex interactions, a Timeline can be used rather than a PauseTransition.
The key thing about timeline and pause transition is that they are event-based, so you provide a callback event handler function in each case whenever the event you wish (the pause for a certain period of time) is triggered.
Due to the event handling nature of the system, there is no busy waiting or sleeping the JavaFX thread, instead, you get notified and can take action when the event is fired.
There is an example of a timeline based approach here:
But, because there are higher-level APIs built for media processing, this is even simpler.
First, for playing beep type sounds, you can use a simpler API than Media, AudioClip is built for that:
If you want to repeat the same sound more than once, then you can set the cycle count on the audio clip:
Now, sometimes it is a good idea to use the richer API and functionality of the Media classes rather than an AudioClip. For example, when the Media being played is pretty long and should be buffered (unlike an AudioClip which can load the entire media into memory), or when you need the extra functionality provided by the Media API.
One such example is the double beep situation you provide in your follow-up question, where you are playing one sound, then playing another different sound after the first sound completes.
Rather than trying to do a busy wait pause of the JavaFX application thread which hangs your app, listen for an event which signals that the first media has finished playing, and use that event to trigger playing the second media.
> I also consider using "aplay" system call cause so far this approach is working best on Linux
My guess is that using system calls for this kind of thing is probably not a good idea.
You lose platform independence and you end up re-inventing the wheel because there is already decent media playback support in JavaFX.