如何在鼠标右键上禁用JSlider的位置更改

如何在鼠标右键上禁用JSlider的位置更改

问题描述:

我在我的应用程序中使用JSlider。我只想点击左键滑动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 
     } 

    } 
}); 

我使用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); 
    } 
} 
+0

成像是+1 – mKorbel 2012-03-16 11:52:57

+0

Thaks,但是这是一个现有的应用程序,我使用JAVA 6.我们有Java 6中解..? – ajkush 2012-03-16 12:28:20

+0

它的工作原理。谢谢 – ajkush 2012-03-16 13:23:24

我情况下,他没有与1.7 工作首先,您必须从您的滑块中删除所有的mouseListeners

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

之后,您可以实现自己的mouseListener并将其添加到滑块。在您的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(); 
    } 

} 

我猜可能计算由于四舍五入等方面加以改进。但这个想法应该引领你走向成功

+0

是的,我明白了,但问题是JSlider在mouseReleased事件之前调用stateChanged事件并更改其位置。因此,我希望在mouseReleased之前禁用右键单击JSlider。 – ajkush 2012-03-16 12:51:58

+0

你确定在添加你之前删除了所有MouseListeners吗? – Vossi 2012-03-16 13:05:06

另一种方法来解决漏洞在用户界面的听众是

  • 找到听众
  • 实现的包装委托给原来只有合适的话(这里:不正确的按钮)
  • 重移动原始,并添加包装

的微弱优势与@ 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); 
+0

+1非常有趣 – aterai 2012-03-16 14:49:16