3

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.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Haxor
  • 2,306
  • 4
  • 16
  • 18
  • 3
    [What have you tried?](http://mattgemmell.com/2008/12/08/what-have-you-tried/) – Gilberto Torrezan Oct 08 '12 at 17:16
  • When a new song is selected, use a background thread that finds the time of the player and updates the seek bar every second. You can use a JSlider as suggested or create your own component. Assuming that you want the seek bar to move while the song is playing of course... – Rempelos Oct 08 '12 at 17:49
  • Can you please help me with the thread.I am not able to figure out,how shall i start? with the thread it is slider.setmaximum=player.getDuration(); slider.setminimum=0; and the value and how do i make the seek bar move along with the song.how shall i repaint the frame? @Rempelos – Haxor Oct 08 '12 at 19:40

3 Answers3

7

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

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
3

You could use a JSlider.

You can learn more from the Slider tutorial

Slider tutorial

Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
  • In addition this [simple example](http://weblogs.java.net/blog/mkarg/archive/2010/01/03/did-you-know-swingworker-can-send-progress-status) could help (updating the slider via `SwingWorker`) – Rempelos Oct 08 '12 at 17:19
  • ya currently m using a JSlider,but the problem is,for the interface of my media player,i need to give the slider a minimum n maximum value first... but m thinking slider.maximum=duration of the song and i can get duration of the song only after it has some mp3 file loaded..if some how i can revalidate the frame...is it possible? – Haxor Oct 08 '12 at 17:20
1

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.

Rempelos
  • 1,220
  • 10
  • 18
  • I tried your code,it worked,but with some flaws 1st. whenever m associating a 2nd thread with my media player,it hangs for a second (dont know if my low pc config is the issue) 2nd. The slider keep on going even after i pause or stop. I tried this by myself.i started a newthread and updated the position of the slider with thread.sleep(1000) the problem is that the player hangs. **NOTE**: I have associated 1st thread with a progress bar (which also shows the update),hence the slider thread is my 2nd @Rempelos it is only lagging,otherwise evrything is fine now. help me sort out this hang issue – Haxor Oct 08 '12 at 22:39
  • Thank you .I will try do this the way @AndrewThompson said,because using a seperate thread to move the slider is making the application (PC) hang,until i close it somehow.So currently I am thinking of changing the song's position using the progress bar. – Haxor Oct 10 '12 at 14:44
  • If it hangs you're not doing it right. Anyway the progressbar is a good alternative – Rempelos Oct 10 '12 at 14:47