3

我正在使用 JMF 制作媒体播放器,我想使用自己的控制组件 谁能帮我为媒体播放器制作一个搜索栏,以便它可以根据滑块位置播放歌曲。

只是建议我一些逻辑,我可以在之后弄清楚编码部分

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;

这是代码。现在我怎样才能让滑块随着歌曲移动?当我拖动/单击它时,滑块可以工作,但它不会随着歌曲移动。

4

3 回答 3

7

为此使用滑块的问题在于,当滑块位置以编程方式移动时,它会触发事件。当在滑块上触发事件时,通常意味着应用程序。必须做一些事情,例如移动歌曲位置。效果是一个永无止境的循环。通过设置标志并忽略某些事件可能有一种解决方法,但我决定采用不同的方式。

相反,我使用 aJProgressBar来指示轨道中的位置,并使用 aMouseListener来检测用户何时单击单独的位置。使用 Swing 更新进度条Timer,每 50-200 毫秒检查一次轨道位置。当MouseEvent检测到 a 时,重新定位轨道。

该栏可以在此 GUI 的右上角看到。将鼠标悬停在它上面将产生一个工具提示,显示该鼠标位置在轨道上的时间。

Duke Box 使用进度条跟踪位置

于 2012-10-08T23:32:05.730 回答
3

您可以使用 JSlider。

您可以从Slider 教程中了解更多信息

滑块教程

于 2012-10-08T17:14:28.670 回答
1

您不必revalidate为了更改滑块而进入容器。

每次创建新播放器时使用这些行:

  slider.setMinimum(0);
  slider.setMaximum(duration);
  slider.setValue(0);

  new UpdateWorker(duration).execute();

其中duration是保存歌曲持续时间的变量,以秒为单位。

这是更新滑块的代码(用作内部类):

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));
    }

}

现在滑块将向右移动,直到歌曲结束。

另请注意,除非您想使用自定义滑块,否则 JMF 通过player.getVisualComponent()(参见此示例)提供了一个简单(且有效)的滑块。

更新

为了暂停/恢复工作线程(以及滑块和歌曲),这里有一个带有设置适当标志的按钮的示例。

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");
        }
    }
});

该方法doInBackground应更改为:

@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;
}

相应地修改它以暂停/恢复歌曲以及滑块。

您还应该考虑@AndrewThompson 的回答。

于 2012-10-08T21:34:41.950 回答