【问题标题】:JSlider Event Firing twiceJSlider 事件触发两次
【发布时间】:2013-03-28 05:23:29
【问题描述】:

我有一个带有附加 ChangeListerner 的简单 JSlider。代码如下:

JSlider slider = new JSlider();
slider.setMinorTickSpacing(2);
slider.setMajorTickSpacing(20);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.setSnapToTicks(true);
slider.setOrientation(SwingConstants.VERTICAL);
contentPane.add(slider, BorderLayout.CENTER);

slider.addChangeListener(new SliderListener());

class SliderListener implements ChangeListener {
    public void stateChanged(ChangeEvent e) {
        JSlider source = (JSlider)e.getSource();
        if (!source.getValueIsAdjusting()) {
            System.out.println("boo");
        }    
    }
}

如您所见,代码并没有做太多事情,我现在要做的就是确保事件只触发一次,因此我的事件只是在 Eclipse 中向控制台打印一些内容。

但每次更改滑块时,上面的代码都会打印两次“boo”。我猜这与 Slider 上的 Mouse Release 有关,但无论如何,我希望它只触发一次事件,因此只打印一次单词。

我怎样才能做到这一点?

谢谢

【问题讨论】:

  • 你有没有试过创建一个基本上只有这个滑块的程序,看看你是否可以复制问题?
  • 如果你把你的整个代码放在这里会更好理解你的代码..
  • @PM77-1 我的整个程序就是这样!基本上是一个JSlider。我已经找到了一些关于这种行为的更具体的信息。只有当我将滑块移动到刻度标签之间的位置时,它才会这样做。代码已更新。
  • @Ciwan - 这个案例似乎为社区所知。请参阅以下讨论:groups.google.com/forum/?fromgroups=#!topic/…
  • 把 changeEvent 想象成一把霰弹枪——它会触发多个触发器,并且从广义上讲,您在侦听器中对此无能为力。相反,请保护触发的相关更改(填充 println 的“真实”代码)以防止重复,即如果其当前状态不受通知影响,则不执行任何操作。

标签: java swing jslider changelistener


【解决方案1】:

您确定没有添加两次侦听器吗?以下 SSCCE 在我的机器(OS X、JDK7)上按预期工作

import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.WindowConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.EventQueue;

public class SliderTest {
  public static void main( String[] args ) {
    EventQueue.invokeLater( new Runnable() {
      @Override
      public void run() {
        JFrame frame = new JFrame(  );
        final JSlider slider = new JSlider( 0, 100 );
        frame.add( slider );
        slider.addChangeListener( new ChangeListener() {
          @Override
          public void stateChanged( ChangeEvent e ) {
            if ( !( slider.getValueIsAdjusting() ) ){
              System.out.println( "SliderTest.stateChanged" );
            }
          }
        } );
        frame.pack();
        frame.setVisible( true );
        frame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
      }
    } );
  }
}

【讨论】:

  • OP 澄清说,当他绘制 滴答声 并将setSnapToTicks 设置为 True 并且滑块在 在滴答声之间 停止时会发生这种情况.显然在这种情况下,第二个事件会自动触发,以便将滑块调整到最近的刻度。
【解决方案2】:

我知道这个问题。我的解决方法是将全局 eventOnwer 设置为所有其他侦听器, 这解决了当一个是事件所有者时发生的其他事件触发。 然后,为了解决滑块问题,我在if 中将getValueIsAdjusting() 设置为true。万一发生火灾,return

【讨论】:

    猜你喜欢
    • 2014-04-07
    • 2013-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-27
    相关资源
    最近更新 更多