问题
I am making a media player using JMF, I want to use my own control components Can anyone please help me in making a seek bar for media player so that it can play song according to the slider position.
Just suggest me some logic, I can figure out the coding part afterwards
if(player!=null){
long durationNanoseconds =
(player.getDuration().getNanoseconds());
durationbar.setMaximum((int) player.getDuration().getSeconds());
int duration=(int) player.getDuration().getSeconds();
int percent = durationbar.getValue();
long t = (durationNanoseconds / duration) * percent;
Time newTime = new Time(t);
player.stop();
player.setMediaTime(newTime);
player.start();
mousedrag=true;
Here is the code. Now how can I make the slider move along with the song? Slider works when I drag/click on it, but it doesn't move with the song.
回答1:
The problem with using a slider for this is that when the slider position is moved programmatically, it fires events. When an event is fired on a slider, it typically means the app. has to do something, such as move the song position. The effect is a never ending loop. There is probably a way around this by setting flags and ignoring some events, but I decided to go a different way.
Instead I used a JProgressBar
to indicate the location in the track, and a MouseListener
to detect when the user clicks on a separate position. Update the progress bar use a Swing Timer
that checks the track location every 50-200 milliseconds. When a MouseEvent
is detected, reposition the track.
The bar can be seen in the upper right of this GUI. Hovering over it will produce a tool tip showing the time in the track at that mouse position.
回答2:
You could use a JSlider.
You can learn more from the Slider tutorial
回答3:
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.
来源:https://stackoverflow.com/questions/12786346/make-a-seek-bar-for-media-player