Java 单击时停止jslider的移动

Java 单击时停止jslider的移动,java,swing,slider,jslider,Java,Swing,Slider,Jslider,单击jslider时,是否可以阻止它移动或更改值?我只希望我的jslider在拖动时移动。当我点击它时,我不想它做任何事情。 有人能帮我做这个吗 不幸的是,经过大量的测试,我找不到任何方法或事件侦听器的组合可以解决这个问题。我得到的最接近的结果是禁用对滑块值的所有修改,无论它如何更改: import javax.swing.JFrame; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.

单击jslider时,是否可以阻止它移动或更改值?我只希望我的jslider在拖动时移动。当我点击它时,我不想它做任何事情。
有人能帮我做这个吗

不幸的是,经过大量的测试,我找不到任何方法或事件侦听器的组合可以解决这个问题。我得到的最接近的结果是禁用对滑块值的所有修改,无论它如何更改:

import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class App {
    public static void main(String[] args) {
        final JFrame jframe = new JFrame("Demo");

        final JSlider jslider = new JSlider();

        // Limit user access
        new SliderLocker(jslider).preventSlide = true;

        jslider.setMajorTickSpacing(10);
        jslider.setPaintTicks(true);
        jframe.getContentPane().add(jslider);

        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jframe.setSize(400, 400);
        jframe.setResizable(false);
        jframe.setVisible(true);
    }

    // Create custom event handler to restore to original value with event system
    private static class SliderLocker implements ChangeListener {
        public boolean preventSlide = false;
        private int oldVal;
        private final JSlider comp;

        public SliderLocker(JSlider c){
            comp = c;
            oldVal = c.getValue();

            c.addChangeListener(this);
        }

        @Override
        public void stateChanged(ChangeEvent ev){
            if(preventSlide){
                comp.setValue(oldVal);
            }
        }
    }
}
基本上,它创建了一个新的
SliderLocker
,它有一个公共标志
.preventSlide
。当设置为
true
时,它将阻止所有用户交互(甚至代码触发的交互,例如
.setValue()


我以前的代码中包含一些鼠标侦听器,这些侦听器会尝试检查滑块是否“滑动”(通过实际的鼠标拖动进行更改),但我后来发现,按住滑块按钮外的鼠标并拖动会损坏处理程序。

还有一些其他示例:

  • slider1
    :覆盖
    TrackListener#应该滚动(…)
    方法以始终返回
    false
  • slider2
    :使用
    JLayer
    将按下的鼠标左键
    MouseEvent
    更改为右键
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入javax.swing.plaf.*;
导入javax.swing.plaf.metal.metalsiderui;
公共类主面板{
公共JComponent makeUI(){
JSlider slider0=新的JSlider();
JSlider slider1=新的JSlider(){
@重写公共void updateUI(){
super.updateUI();
setUI(新的MetalSliderUI(){
@覆盖受保护的TrackListener createTrackListener(JSlider滑块){
返回新的TrackListener(){
@覆盖公共布尔值shouldScroll(int方向){
返回false;
}
};
}
});
}
};
//http://stackoverflow.com/questions/9736237/how-to-disable-position-change-of-jslider-on-mouse-right-click
UIManager.put(“Slider.onlyLeftMouseButtonDrag”,false);
JSlider slider2=新的JSlider();
Box=Box.createVerticalBox();
box.setBorder(BorderFactory.createEmptyByOrder(20,0,20,20));
添加(makeTitledPanel(“默认”,滑块0));
框。添加(框。创建垂直支柱(20));
box.add(makeTitledPanel(
“覆盖TrackListener#shouldScroll(…):false”,slider1);
框。添加(框。创建垂直支柱(20));
box.add(makeTitledPanel(
“JLayer+Slider.onlyLeftMouseButtonDrag:false”,
新的JLayer(slider2,新的禁用LeftPressedLayerUI());
添加(box.createVerticalGlue());
返回框;
}
私有静态JComponent makeTitledPanel(字符串标题,JComponent c){
JPanel p=newjpanel(newborderlayout());
p、 setboorder(BorderFactory.createTitledBorder(title));
p、 添加(c,边界布局。北);
返回p;
}
公共静态void main(字符串…参数){
EventQueue.invokeLater(()->{
JFrame f=新的JFrame();
f、 setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f、 getContentPane().add(新建主面板().makeUI());
f、 设置大小(320240);
f、 setLocationRelativeTo(空);
f、 setVisible(真);
});
}
}
类DisableLeftPressedLayerUI扩展LayerUI{
@覆盖公共void installUI(JComponent c){
super.installUI(c);
if(JLayer的c实例){
((JLayer)c).setlayerventmask(AWTEvent.MOUSE\u EVENT\u MASK);
}
}
@覆盖公共用户界面(JComponent c){
if(JLayer的c实例){
((JLayer)c).SetLayerReventMask(0);
}
super.ui(c);
}

@重写受保护的void进程mouseevent(MouseEvent e,如果您单击滑块旋钮,JLayerIt不应更改值。@FredK是的,但如果您单击滑块上的任何其他位置,它会将旋钮拉向您单击的位置,这就是我要停止的,这就是JSlider的工作方式。如果您尝试以其他方式开始工作,您将极大地混淆和困扰任何of你的用户。@FredK好的。收到了谢谢你的努力。我想这给了我一个如何进行的想法。非常感谢。我想这一定会解决我的问题
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
import javax.swing.plaf.metal.MetalSliderUI;

public class MainPanel {
  public JComponent makeUI() {
    JSlider slider0 = new JSlider();

    JSlider slider1 = new JSlider() {
      @Override public void updateUI() {
        super.updateUI();
        setUI(new MetalSliderUI() {
          @Override protected TrackListener createTrackListener(JSlider slider) {
            return new TrackListener() {
              @Override public boolean shouldScroll(int direction) {
                return false;
              }
            };
          }
        });
      }
    };

    //http://stackoverflow.com/questions/9736237/how-to-disable-position-change-of-jslider-on-mouse-right-click
    UIManager.put("Slider.onlyLeftMouseButtonDrag", false);
    JSlider slider2 = new JSlider();

    Box box = Box.createVerticalBox();
    box.setBorder(BorderFactory.createEmptyBorder(20, 0, 20, 20));
    box.add(makeTitledPanel("Default", slider0));
    box.add(Box.createVerticalStrut(20));
    box.add(makeTitledPanel(
        "Override TrackListener#shouldScroll(...): false",  slider1));
    box.add(Box.createVerticalStrut(20));
    box.add(makeTitledPanel(
        "JLayer + Slider.onlyLeftMouseButtonDrag: false",
        new JLayer<JSlider>(slider2, new DisableLeftPressedLayerUI())));
    box.add(Box.createVerticalGlue());

    return box;
  }
  private static JComponent makeTitledPanel(String title, JComponent c) {
    JPanel p = new JPanel(new BorderLayout());
    p.setBorder(BorderFactory.createTitledBorder(title));
    p.add(c, BorderLayout.NORTH);
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new MainPanel().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class DisableLeftPressedLayerUI extends LayerUI<JSlider> {
  @Override public void installUI(JComponent c) {
    super.installUI(c);
    if (c instanceof JLayer) {
      ((JLayer) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK);
    }
  }
  @Override public void uninstallUI(JComponent c) {
    if (c instanceof JLayer) {
      ((JLayer) c).setLayerEventMask(0);
    }
    super.uninstallUI(c);
  }
  @Override protected void processMouseEvent(MouseEvent e, JLayer<? extends JSlider> l) {
    if (e.getID() == MouseEvent.MOUSE_PRESSED && SwingUtilities.isLeftMouseButton(e)) {
      JSlider slider = (JSlider) e.getComponent();
      MouseEvent me = new MouseEvent(
        slider,
        e.getID(), e.getWhen(),
        InputEvent.BUTTON3_DOWN_MASK, //e.getModifiers(),
        e.getX(), e.getY(),
        e.getXOnScreen(), e.getYOnScreen(),
        e.getClickCount(),
        e.isPopupTrigger(),
        MouseEvent.BUTTON3); //e.getButton());
      e.consume();
      slider.dispatchEvent(me);
    }
  }
}