我有一个音乐播放器,它的ProgressBar
最大值为mediaPlayer.getTotalDuration().toSeconds()
最近我一直在尝试做一个MouseListener
,以便在单击某个位置时ProgressBar
寻求返回的 X 值的mediaPlayer
。
问题:我单击ProgressBar
,它似乎正在接收毫秒,所以我将其乘以 1000,以便它寻求相应的秒数。
这适用于某些音乐/mp3,但对于较短的音乐/mp3,或较长的音乐/mp3,ProgressBar
仅跳到最近的可能位置,或跳到其他位置,由于X值的* 1000
计算,完全不准确。(下面我尝试了某人的建议,以获得另一个答案,将 X 值计算为秒,我也尝试设置ProgressBar
值并将该值设置为mediaPlayer
所在的位置。
"int 点"是我接收 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] 范围内的事件位置。
需要两件事:
- 进度条的宽度(以像素为单位(
- 鼠标单击相对于进度条组件的 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);
您犯的第一个错误是在单击进度条时设置进度条最大值。当媒体正在播放并且您没有按进度栏时,进度栏的最大值是错误的。更改媒体播放器持续时间时,应设置此值。您应该将侦听器添加到 totalDuration属性更改,方法与媒体播放器分配媒体的方法相同。
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());
}
});
第二个问题是滑块组件及其进度条具有不同的大小。
进度栏鼠标侦听器:
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是怎么出现的。通过反复试验获得这些值。由于滑块组件大于其进度条,因此 getWidth(( 返回更大的值。这包括进度条两侧的差距。-9 用于调整单击位置以调整滑块组件和进度条开头之间的间隙。-19 这是滑块组件宽度通过进度条两侧的间隙而减小。