【问题标题】:Click on progressbar to seek MediaPlayer点击进度条寻找MediaPlayer
【发布时间】:2017-07-11 15:38:51
【问题描述】:

我有一个音乐播放器,其 ProgressBar 的最大值为 mediaPlayer.getTotalDuration().toSeconds()

最近我一直在尝试创建一个MouseListener 来寻找mediaPlayer 到当ProgressBar 在某个位置被点击时返回的X 值。

问题:我点击ProgressBar,它似乎正在接收毫秒,所以我将它乘以 1000,以便它寻求相应的秒数。

这对某些音乐/mp3 准确有效,但对于较短或较长的音乐/mp3,ProgressBar 仅跳转到最近的可能位置,或跳转到其他位置,由于 * 1000 计算完全不准确X 值。 (下面我尝试了某人的建议,以将 X 值计算为秒,我还尝试设置 ProgressBar 值并将该值设置为 mediaPlayer 所在的位置。)

“int point”是我收到 X 值的地方。

代码:

progressBar.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent mouseClick) {
        try{
            progressBar.setMaximum((int)mediaPlayer.getTotalDuration().toSeconds());
            int point = (int)Math.round(((double)mouseClick.getX() / (double)progressBar.getWidth()) * progressBar.getMaximum()); // previously tried "* 1000".
            Duration pointDuration = new Duration(point);
            mediaPlayer.seek(pointDuration);
        } catch (Exception e7){
                //
        }
    }
});

(不幸的是,计算更糟糕。)

我应该使用什么样的计算来正确寻找点击的位置?

【问题讨论】:

  • Slider 可能是比 ProgressBar 更好的解决方案。如果您愿意,您可以使用 CSS 来设置滑块的样式,使其看起来像 ProgressBar 或至少与其默认外观不同。有关如何使用 Slider 执行此操作的信息,请参阅 Oracle Introduction to JavaFX Media 教程。

标签: java progress-bar media-player


【解决方案1】:

您必须明智地选择单位,并让它们出现在您的代码中。我通常做的是将进度条限制在 [0.0,1.0] 范围内,即double 算术的百分比。

当您收到鼠标点击事件时,您会在 [0,1] 范围内转换事件位置。

需要两件事:

  1. 进度条的宽度(以像素为单位)
  2. 鼠标点击相对于进度条组件的 x 坐标

你有一个准确的观点(注意toMilliseconds):

double dx = evt.getX();
double dwidth = progressBar.getWidth();
double progression = (dx / dwidth);
int milliseconds = (progression * mediaPlayer.getTotalDuration().toMilliseconds())
Duration duration = new Duration(milliseconds);
mediaPlayer.seek(duration);

【讨论】:

    【解决方案2】:

    您犯的第一个错误是在单击进度条时设置progressBar 最大值。当媒体正在播放并且您没有按下progressBar 时,进度条的最大值是错误的。当 mediaPlayer 持续时间改变时,应该设置这个值。您应该使用与 mediaPlayer 分配媒体相同的方法将侦听器添加到 totalDurationProperty 更改。

    Media media = new Media(filePath);
    mediaPlayer = new MediaPlayer(media);
    mainMediaView.setMediaPlayer(mediaPlayer);
    
    mediaPlayer.totalDurationProperty().addListener(new ChangeListener<Duration>() {
                    @Override
                    public void changed(ObservableValue<? extends Duration> observable, Duration oldValue,
                            Duration newValue) {
                        progressBar.setMax(newValue.toSeconds());
                    }
                });
    

    第二个问题是 Slider 组件和它的进度条有不同的大小。

    progressBar 鼠标监听器:

    progressBar.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent mouseClick) {
            try{
              double value;
              value = (mouseClick.getX()-9) * (progressBar.getMax() / (progressBar.getWidth()-19));
              progressBar.setValue(value); 
            } catch (Exception e7){
    
            }
        }
    });
    

    你可能会问 -9 和 -19 是怎么出现的。通过反复试验得到这些值。由于 Slider 组件大于其进度条,getWidth() 返回较大的值。这包括进度条两侧的间隙。 -9 用于将点击位置调整为滑块组件和进度条开始之间的间隙。 -19 滑块组件宽度因进度条两侧的间隙而变小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多