我有一个音乐播放器,其进度条的最大值为mediaPlayer.getTotalDuration().toSeconds().
最近,我一直在尝试使用mouseListener在单击某个位置上的progressBar时,将mediaPlayer设置为返回的X值。
问题:我点击progressBar,它似乎正在接收毫秒,所以我将它乘以1000,以便寻找相应的第二个计数。
这对于一些音乐/ mp3来说是准确的,但是对于较短的音乐/ mp3,或者更长的一些,progressBar只跳到最近的可能位置,或者跳到其他位置,由于X值的* 1000计算而完全不准确。 (下面我已经尝试过某人建议另一个答案来计算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){
//
}
}
});
(不幸的是,计算更糟糕。)
我应该使用什么样的计算来正确寻找点击位置?
您必须明智地选择您的单位,并使它们出现在您的代码中。我通常做的是将进度条限制在[0.0,1.0]范围内,即使用double
算术的百分比。
当您收到鼠标单击事件时,您将转换该[0,1]范围内的事件位置。
需要做两件事:
你有一个准确的点(注意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);
第一个错误就是单击进度条时设置progressBar最大值。虽然正在播放媒体而你没有按下progressBar但是progres bar的最大值是错误的。更改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即滑块组件宽度因进度条两侧的间隙而变小。