【问题标题】:How to disable position change of JSlider on mouse right click如何在鼠标右键单击时禁用 JSlider 的位置更改
【发布时间】:2012-03-16 11:13:48
【问题描述】:

我在我的应用程序中使用JSlider。我只想左键单击滑动JSlider,我想禁用右键单击JSlider。我能够在右键单击时获得事件,但滑块正在将其值更改为其他位置。

jSlider.addChangeListener(new ChangeListener() {

    public void stateChanged(ChangeEvent e) {
        //code
    }
});

jSlider.addMouseListener(new MouseAdapter() {

    public void mouseReleased(MouseEvent e) {

        if (e.getButton() == java.awt.event.MouseEvent.BUTTON3) {
            //code
        } else {
            //code
        }

    }
});

【问题讨论】:

    标签: java swing awt core jslider


    【解决方案1】:

    我使用的是JDK1.7.0_03,Windows 7

    UIManager.put("Slider.onlyLeftMouseButtonDrag", Boolean.TRUE);
    

    JDK1.6.0_31:

    Bug ID: 6614972 JSlider value should not change on right-click

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.plaf.metal.MetalSliderUI;
    
    public class SliderOnlyLeftMouseButtonDragTest {
      public JComponent makeUI() {
        JSlider slider00 = new JSlider(0,10,5);
        JSlider slider01 = new JSlider(0,10,5);
        slider01.setUI(new MetalSliderUI() {
          protected TrackListener createTrackListener(JSlider slider) {
            return new TrackListener() {
              @Override public void mousePressed(MouseEvent e) {
                if(!SwingUtilities.isLeftMouseButton(e)) {
                  return;
                }
                super.mousePressed(e);
              }
            };
          }
        });
        JPanel p = new JPanel();
        p.add(slider00);
        p.add(slider01);
        return p;
      }
      public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
          @Override public void run() {
            createAndShowGUI();
          }
        });
      }
      public static void createAndShowGUI() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        f.getContentPane().add(new SliderOnlyLeftMouseButtonDragTest().makeUI());
        f.setSize(320, 240);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
      }
    }
    

    【讨论】:

    • Thaks ,但这是一个现有的应用程序,我正在使用 JAVA 6。我们在 java 6.. 中有解决方案吗?
    • 很好地追踪该错误 :-) ui-delegates 的即时子类化并按实例设置它们有缺点,但是,在 f.i.无法在 updateUI 调用中幸存。
    【解决方案2】:

    解决 ui 侦听器中的错误的另一种方法是

    • 找到监听器
    • 实现一个包装器,仅在适当的情况下委托给原始文件(此处:不适用于右键)
    • 删除原始文件并添加包装器

    与@aterai 的方法相比的轻微优势在于它独立于 LAF,也就是说,您可以以完全相同的方式对每个应用它,而不是为每个子类化 ui 委托。

    在代码中类似于:

    MouseListener[] listeners = slider.getMouseListeners();
    MouseListener uiListener = null;
    for (MouseListener l : listeners) {
        LOG.info(l.getClass().getName());
        if (l.getClass().getName().contains("Track")) {
            uiListener = l; 
            break;
        }
    }
    
    final MouseListener delegate = uiListener;
    MouseListener wrapper = new MouseListener() {
    
        @Override
        public void mouseClicked(MouseEvent e) {
            if (filter(e)) return;
            delegate.mouseClicked(e);
        }
    
        private boolean filter(MouseEvent e) {
            return SwingUtilities.isRightMouseButton(e);
        }
    
        @Override
        public void mousePressed(MouseEvent e) {
            if (filter(e)) return;
            delegate.mousePressed(e);
        }
    
        @Override
        public void mouseReleased(MouseEvent e) {
            if (filter(e)) return;
            delegate.mouseReleased(e);
        }
    
        @Override
        public void mouseEntered(MouseEvent e) {
            delegate.mouseEntered(e);
        }
    
        @Override
        public void mouseExited(MouseEvent e) {
            delegate.mouseExited(e);
        }
    
    };
    slider.removeMouseListener(uiListener);
    slider.addMouseListener(wrapper);
    

    【讨论】:

      【解决方案3】:

      我认为他没有使用 1.7 首先,您必须从滑块中删除所有 mouseListeners

      for (MouseListener ml : slider.getMouseListeners()){
          slider.removeMouseListener(ml);
      }
      

      之后,您可以实现自己的 mouseListener 并将其添加到滑块。在您的鼠标侦听器中,您必须执行计算以设置滑块的值...例如像这样的东西

      public void mouseReleased(MouseEvent e) {
      
          if (e.getButton() == java.awt.event.MouseEvent.BUTTON3) {
              //code whatever should happen on right click
          } else {
              e.getX()*slider.getMaximum()/slider.getWidth();
          }
      
      }
      

      我猜由于四舍五入等原因可以改进计算。但是这个想法应该会引导你成功

      【讨论】:

      • 是的,我明白了,但问题是 JSlider 在 mouseReleased 事件之前调用 stateChanged 事件并更改其位置。所以我想在 mouseReleased 之前禁用右键单击 JSlider。
      • 您确定在添加之前已删除所有 MouseListener 吗?
      猜你喜欢
      • 2014-05-16
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-10
      • 1970-01-01
      相关资源
      最近更新 更多