You don't have to revalidate
the container in order to change the slider.
Use these lines each time a new player is created:
slider.setMinimum(0);
slider.setMaximum(duration);
slider.setValue(0);
new UpdateWorker(duration).execute();
where duration
is the variable holding the duration of the song in seconds.
And here is the code (used as inner class) which updates the slider:
private class UpdateWorker extends SwingWorker<Void, Integer> {
private int duration;
public UpdateWorker(int duration) {
this.duration = duration;
}
@Override
protected Void doInBackground() throws Exception {
for (int i = 1; i <= duration; i++) {
Thread.sleep(1000);
publish(i);
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
slider.setValue(chunks.get(0));
}
}
Now the slider will move to the right until the end of the song.
Also note that unless you want to use a custom slider, JMF provides a simple (and working) slider via player.getVisualComponent()
(see this example).
UPDATE
In order to pause/resume the worker thread (and thus the slider and the song), here is an example with a button that sets the appropriate flags.
private boolean isPaused = false;
JButton pause = new JButton("Pause");
pause.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton source = (JButton)e.getSource();
if (!isPaused) {
isPaused = true;
source.setText("Resume");
} else {
isPaused = false;
source.setText("Pause");
}
}
});
The method doInBackground
should be changed to something like that:
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i <= duration; i++) {
if (!isPaused) {
publish(i);
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
while (isPaused) {
try {
Thread.sleep(50);
continue;
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
return null;
}
Modify it accordingly to pause/resume the song along with the slider.
You should also consider @AndrewThompson's answer.