Make a seek bar for media player.

2019-04-12 20:03发布

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.

标签: java swing jmf
3条回答
神经病院院长
2楼-- · 2019-04-12 21:05

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.

Duke Box using progress bar for track postion

查看更多
在下西门庆
3楼-- · 2019-04-12 21:05

You could use a JSlider.

You can learn more from the Slider tutorial

Slider tutorial

查看更多
戒情不戒烟
4楼-- · 2019-04-12 21:10

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.

查看更多
登录 后发表回答