Java Reference
In-Depth Information
#playPauseButton:hover, #seekEndButton:hover, #seekStartButton:hover {
-fx-background-color: rgb(255, 255, 255, 0.1);
}
The logic that controls the actual seek operation is encapsulated in the seekAndUpdatePosition method.
Remember that the seek method has no effect if the player is in the STOPPED state. If that is the case, we need to call
the pause method before the seek method is called or the seek will not work. Also note that after seek is called, we
manually update the position slider if the MediaPlayer is not playing. This is necessary because the MediaPlayer 's
currentTime property is not updated automatically by the call to seek. If the MediaPlayer is playing, this is not
noticeable because playback will immediately continue from the new seek position, causing the currentTime to
be quickly updated as well. On the other hand, if the MediaPlayer is not playing then the currentTime will not be
updated, causing the position slider (which listens to and displays currentTime updates) to become out of sync with
the new playback position. This is noticeable the next time the play button is pressed; the position slider will suddenly
skip ahead or back to the position of the last seek.
This discussion has led nicely to the third control in the audio player that makes use of the seek function: the
aforementioned position slider. The position slider does double duty: It displays the currentTime value but can
also be dragged to a new position, resulting in a call to the seek method. As you can probably guess, there are some
subtleties to account for when getting this to work properly. Listing 9-19 shows the code required to implement the
first part of this functionality: displaying the currentTime value on the position slider.
Listing 9-19. Displaying the Value of currentTime on the Position Slider
private class CurrentTimeListener implements InvalidationListener {
@Override
public void invalidated(Observable observable) {
Platform.runLater(() -> {
final MediaPlayer mediaPlayer = songModel.getMediaPlayer();
final Duration currentTime = mediaPlayer.getCurrentTime();
currentTimeLabel.setText(formatDuration(currentTime));
updatePositionSlider(currentTime);
});
}
}
private void updatePositionSlider(Duration currentTime) {
if (positionSlider.isValueChanging())
return;
final MediaPlayer mediaPlayer = songModel.getMediaPlayer();
final Duration total = mediaPlayer.getTotalDuration();
if (total == null || currentTime == null) {
positionSlider.setValue(0);
} else {
positionSlider.setValue(currentTime.toMillis() / total.toMillis());
}
}
Like the status property, MediaPlayer 's currentTime property is updated on a different thread than the main
JavaFX application thread. Therefore we cannot bind to it directly and must instead attach an InvalidationListener
that utilizes Platform.runLater to perform updates to live scene graph nodes such as the position slider. Listing 9-19
shows the implementation of the CurrentTimeListener inner class that accomplishes this for us. The Runnable 's
 
Search WWH ::




Custom Search