gpt4 book ai didi

java - 更改监听器在 JSlider 中造成阻碍

转载 作者:行者123 更新时间:2023-12-01 12:47:00 25 4
gpt4 key购买 nike

我编写了这段用于播放音乐的代码,JSlider随着音乐的进度自动向前移动,我在JSlider中添加了更改监听器以用光标更改音乐位置,问题是当JSlider的旋钮随着音乐的进度移动时音乐进度changeListener();方法也会被调用,这会在播放音乐时造成障碍,因此我希望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);
}


}

最佳答案

只要底层 BoundedRangeModel 发生更改,就会引发 stateChanged 事件。这可能有多种原因。问题是,你不知道为什么,而且通常也不关心。

就您的情况而言,有两种(主要)情况可能会更改模型。 while-loop 和用户。

您需要某种方法来改变状态,以便能够检测谁在进行更改或在某些情况下阻止通知更改。

在这个(简单)示例中,我使用简单的标志来指示更新发生的位置,并停止任一修改元素更新模型,直到另一个元素完成为止。这在这里起作用是因为我使用了 Swing Timer 来执行进度更新,这确保了“定时”更新和用户更新都在同一线程的上下文中发生。这提供了一定程度的保护,因为在运行 stateChanged 方法时,Timer 不可能尝试更改 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();
}
}
}

}

关于java - 更改监听器在 JSlider 中造成阻碍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24600159/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com