我已经编写了这个用于播放音乐的代码,JSlider随着音乐的进展自动向前移动,我已经为JSlider添加了更改侦听器,用于通过光标改变音乐位置,问题是当JSlider的nob移动时音乐改变进展Listener();方法也被调用,这在播放音乐时会造成障碍,所以我想要那个changeListener();只有当我用游标移动JSlider的nob时才应该调用该方法。请告诉我们该怎么做。
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class A implements ChangeListener {
Clip clip;
public A() throws Exception {
JFrame f = new JFrame();
f.setSize(800,400);
f.setVisible(true);
f.setLayout(null);
URL url = this.getClass().getClassLoader().getResource("jal pari.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
clip = AudioSystem.getClip();
clip.open(audioIn);
int x = (int)(clip.getMicrosecondLength()/1000000);
JSlider s = new JSlider(JSlider.HORIZONTAL,0,x,0);
s.addChangeListener(this);
s.setBounds(50,50,800,100);
f.add(s);
clip.start();
while( clip.getMicrosecondPosition()!=clip.getMicrosecondLength() ) {
s.setValue((int)(clip.getMicrosecondPosition()/1000000));
}
}
public static void main(String arg[]) throws Exception {
new A();
}
public void stateChanged(ChangeEvent e) {
JSlider js = (JSlider)e.getSource();
int v = js.getValue();
clip.setMicrosecondPosition(v*1000000);
}
}
答案 0 :(得分:1)
每当基础stateChanged
发生更改时,都会引发BoundedRangeModel
事件。这可能有多种原因。问题是,你不知道为什么,而且一般都不关心。
在您的情况下,您有两个(主要)情况可能会更改模型。 while-loop
和用户。
您需要的是一些改变状态的方法,以便能够在某些情况下检测谁在进行更改或阻止更改通知。
在这个(简单)示例中,我使用简单的标志来指示更新发生的位置,并停止修改元素以更新模型,直到另一个完成。这可以在这里使用,因为我使用了Swing Timer
来执行进度更新,这确保了"定时"更新和用户更新发生在同一线程的上下文中。这提供了一定程度的保护,因为Timer
在stateChanged
方法运行时尝试更改UI的状态是不可能的。
这也意味着当从{"时间进度"中提出stateChanged
事件时代码,我们的stateChanged
处理程序会忽略它,因此它不会弄乱Clip
的当前位置
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class MusicPlayer {
public static void main(String[] args) {
new MusicPlayer();
}
public MusicPlayer() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JSlider slider;
private Clip clip;
private Timer updateTimer;
private boolean timerUpdate = false;
private boolean userUpdate = false;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
slider = new JSlider();
slider.setMinorTickSpacing(5);
slider.setMajorTickSpacing(10);
slider.setPaintTicks(true);
slider.setValue(0);
add(slider);
updateTimer = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (clip != null) {
if (!userUpdate) {
timerUpdate = true;
try {
long length = TimeUnit.NANOSECONDS.convert(clip.getMicrosecondLength(), TimeUnit.SECONDS);
long time = TimeUnit.NANOSECONDS.convert(clip.getMicrosecondPosition(), TimeUnit.SECONDS);
int progress = (int) Math.round(((double) time / (double) length) * 100d);
slider.setValue(progress);
} finally {
timerUpdate = false;
}
}
}
}
});
updateTimer.start();
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
if (!timerUpdate && !userUpdate) {
userUpdate = true;
try {
long length = clip.getMicrosecondLength();
int progress = slider.getValue();
long time = (long) (length * (progress / 100d));
clip.setMicrosecondPosition(time);
} finally {
userUpdate = false;
}
}
}
});
try {
File source = new File("\\...\\Kalimba.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(source);
clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException exp) {
exp.printStackTrace();
}
}
}
}