Java JSlider未正确地从鼠标事件更新
我有一个小程序,可以从JFileChooser中选择音频文件。创建或更新两个JSLIDER以匹配剪辑的长度,标题为“点A”和“点B”。按下一个按钮,然后文件播放到A点。当它到达A点时,剪辑开始以交叉淡入的方式将音频从A点循环到B点 问题是,我必须确保A点永远不会因为明显的原因超过B点,但我的方法对此不起作用 添加一个changelistener,在源JSlider正在更新或未更新时进行更新,这是我尝试过的两件事。对于Java JSlider未正确地从鼠标事件更新,java,swing,mouse,jslider,changelistener,Java,Swing,Mouse,Jslider,Changelistener,我有一个小程序,可以从JFileChooser中选择音频文件。创建或更新两个JSLIDER以匹配剪辑的长度,标题为“点A”和“点B”。按下一个按钮,然后文件播放到A点。当它到达A点时,剪辑开始以交叉淡入的方式将音频从A点循环到B点 问题是,我必须确保A点永远不会因为明显的原因超过B点,但我的方法对此不起作用 添加一个changelistener,在源JSlider正在更新或未更新时进行更新,这是我尝试过的两件事。对于!source.getValueIsAdjusting(),它适用于使用箭头键,
!source.getValueIsAdjusting()
,它适用于使用箭头键,但不适用于鼠标;对于source.getValueIsAdjusting()
,它以延迟方式工作:它似乎是在比较或重置延迟事件的值
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JApplet;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SliderExample extends JApplet{
private MyPanel panel;
private final Random rand = new Random();
public SliderExample() {
panel = new MyPanel();
add(panel);
}
private class MyPanel extends JPanel implements
ActionListener{
private JSlider sliderA, sliderB;
private final Timer t = new Timer(20, this);
public MyPanel()
{
super(false);
sliderA = new JSlider(JSlider.HORIZONTAL, 0, 20, 5);
sliderB = new JSlider(JSlider.HORIZONTAL, 0, 20, 15);
sliderA.setBorder(BorderFactory.createTitledBorder("Point A"));
sliderB.setBorder(BorderFactory.createTitledBorder("Point B"));
sliderA.setMajorTickSpacing(5);
sliderB.setMajorTickSpacing(5);
sliderA.setMinorTickSpacing(1);
sliderB.setMinorTickSpacing(1);
sliderA.setPaintTicks(true);
sliderB.setPaintTicks(true);
sliderA.setPaintLabels(true);
sliderB.setPaintLabels(true);
sliderA.addChangeListener(new SliderHandler());
sliderB.addChangeListener(new SliderHandler());
add(sliderA);
add(sliderB);
t.start();
}
@Override
public void actionPerformed(ActionEvent e) {
// uncomment these to see that the slider set value does work
// sliderA.setValue(rand.nextInt(sliderA.getMaximum()));
// sliderB.setValue(rand.nextInt(sliderB.getMaximum()));
int A = sliderA.getValue();
int B = sliderB.getValue();
if (A > B)
{
System.out.println("ERROR: slider A is: " + A + " and slider B is : " + B);
sliderA.setValue(B);
}
}
private class SliderHandler implements ChangeListener
{
private SliderHandler()
{
}
public void stateChanged(ChangeEvent e)
{
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting())
{
if (source == sliderA)
{
if (source.getValue() > sliderB.getValue())
{
source.setValue(sliderB.getValue());
}
}
else if (source == sliderB)
{
if (source.getValue() < sliderA.getValue())
{
source.setValue(sliderA.getValue());
}
}
}
}
}
}
}
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.Random;
导入javax.swing.BorderFactory;
导入javax.swing.JApplet;
导入javax.swing.JPanel;
导入javax.swing.JSlider;
导入javax.swing.Timer;
导入javax.swing.event.ChangeEvent;
导入javax.swing.event.ChangeListener;
公共类SliderExample扩展了JApplet{
私人小组;
私有最终随机兰德=新随机();
公共幻灯片示例(){
panel=新的MyPanel();
添加(面板);
}
私有类MyPanel扩展了JPanel实现
ActionListener{
私人JSlider sliderA,sliderB;
专用最终定时器t=新定时器(20,本);
公共事务委员会()
{
超级(假);
sliderA=新的JSlider(JSlider.HORIZONTAL,0,20,5);
sliderB=新的JSlider(JSlider.HORIZONTAL,0,20,15);
sliderA.setboorder(BorderFactory.createTitledBorder(“点A”));
sliderB.setOrder(BorderFactory.createTitledBorder(“点B”);
sliderA.setMajorTickSpacing(5);
滑块B.设置主滑块间距(5);
sliderA.setMinorTickSpacing(1);
滑块B.setMinorTickSpacing(1);
sliderA.setPaintTicks(true);
sliderB.setPaintTicks(真);
sliderA.setPaintLabels(true);
sliderB.setPaintLabels(真);
addChangeListener(新的SliderHandler());
addChangeListener(新的SliderHandler());
添加(sliderA);
添加(幻灯片b);
t、 start();
}
@凌驾
已执行的公共无效操作(操作事件e){
//取消注释以查看滑块集值是否有效
//setValue(rand.nextInt(sliderA.getMaximum());
//setValue(rand.nextInt(sliderB.getMaximum());
int A=sliderA.getValue();
intb=sliderB.getValue();
如果(A>B)
{
System.out.println(“错误:滑块A为“+A+”,滑块B为“+B”);
sliderA.setValue(B);
}
}
私有类SliderHandler实现ChangeListener
{
专用滑动手柄()
{
}
公共无效状态已更改(更改事件e)
{
JSlider source=(JSlider)e.getSource();
如果(!source.getValueIsAdjusting())
{
如果(源==sliderA)
{
if(source.getValue()>sliderB.getValue())
{
setValue(sliderB.getValue());
}
}
else if(source==sliderB)
{
if(source.getValue()
对我来说似乎还可以。我已将滑块更改为+1或-1形式,这是我试图移动的值。例如:
import javax.swing.*;
import javax.swing.event.*;
@SuppressWarnings("serial")
public class SliderExample2 extends JPanel {
private JSlider sliderA = new JSlider(JSlider.HORIZONTAL, 0, 20, 5);
private JSlider sliderB = new JSlider(JSlider.HORIZONTAL, 0, 20, 15);
private JSlider[] sliders = {sliderA, sliderB};
private String[] titles = {"Point A", "Point B"};
private ChangeListener[] changeListeners = {new ChangeListenerA(),
new ChangeListenerB()};
public SliderExample2() {
for (int i = 0; i < sliders.length; i++) {
sliders[i].setBorder(BorderFactory.createTitledBorder(titles[i]));
sliders[i].setMajorTickSpacing(5);
sliders[i].setMinorTickSpacing(1);
sliders[i].setPaintTicks(true);
sliders[i].setPaintLabels(true);
sliders[i].addChangeListener(changeListeners[i]);
add(sliders[i]);
}
}
private class ChangeListenerA implements ChangeListener {
@Override
public void stateChanged(ChangeEvent cEvt) {
if (sliderA.getValue() >= sliderB.getValue()) {
sliderB.setValue(sliderA.getValue() + 1);
}
}
}
private class ChangeListenerB implements ChangeListener {
@Override
public void stateChanged(ChangeEvent cEvt) {
if (sliderA.getValue() >= sliderB.getValue()) {
sliderA.setValue(sliderB.getValue() - 1);
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SliderExample2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SliderExample2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
基本问题是
getValueIsAdjusting
会干扰更新。如果删除此项,则可以在每次状态更改时进行连续检查。我还认为你的比较是错误的如果a>b,则b=a
,而不是a=b
,但这只是我的期望…请参见编辑以获得答案。我想我一开始回答错了问题,但现在我回答对了。你忘了在你的JSliders上调用setSnapToTicks(true)
。该死的耶!这就是我说的!
import javax.swing.*;
import javax.swing.event.*;
@SuppressWarnings("serial")
public class SliderExample3 extends JPanel {
private JSlider sliderA = new JSlider(JSlider.HORIZONTAL, 0, 20, 5);
private JSlider sliderB = new JSlider(JSlider.HORIZONTAL, 0, 20, 15);
private JSlider[] sliders = {sliderA, sliderB};
private String[] titles = {"Point A", "Point B"};
private ChangeListener[] changeListeners = {new ChangeListenerA(),
new ChangeListenerB()};
public SliderExample3() {
for (int i = 0; i < sliders.length; i++) {
sliders[i].setBorder(BorderFactory.createTitledBorder(titles[i]));
sliders[i].setMajorTickSpacing(5);
sliders[i].setMinorTickSpacing(1);
sliders[i].setPaintTicks(true);
sliders[i].setPaintLabels(true);
sliders[i].setSnapToTicks(true);
sliders[i].addChangeListener(changeListeners[i]);
add(sliders[i]);
}
}
private class ChangeListenerA implements ChangeListener {
@Override
public void stateChanged(ChangeEvent cEvt) {
if (sliderA.getValue() >= sliderB.getValue()) {
sliderA.setValue(sliderB.getValue());
}
}
}
private class ChangeListenerB implements ChangeListener {
@Override
public void stateChanged(ChangeEvent cEvt) {
if (sliderA.getValue() >= sliderB.getValue()) {
sliderB.setValue(sliderA.getValue());
}
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SliderExample3");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SliderExample3());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}