Is it possible to stop a jslider from moving or changing values when it is clicked on? I want my jslider only to move when it is dragged. I don't want it to do anything at all when I click on it. Would someone please help me with this one.
Asked
Active
Viewed 1,041 times
3
-
It should not change value if you click on the slider knob. – FredK Oct 06 '16 at 19:52
-
@FredK yes but if you click anywhere else on the slider it draws the knob some steps towards where you clicked and that's what i want to stop – user6866106 Oct 06 '16 at 19:56
-
1That is how a JSlider is supposed to work. If you try to get to work in some other way, you will greatly confuse and annoy any of your users. – FredK Oct 06 '16 at 20:20
-
@FredK alright.. got it – user6866106 Oct 06 '16 at 20:22
2 Answers
1
There are a few other examples:
slider1
: OverrideTrackListener#shouldScroll(...)
method to always returnfalse
.slider2
: Change the left mouse button pressedMouseEvent
as a right button by usingJLayer
.
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);
}
}
}

aterai
- 9,658
- 4
- 35
- 44
-
thank you so much .. i think this will definitely solve my problem – user6866106 Oct 07 '16 at 17:59
0
Unfortunately, after a fair amount of testing, I could not find any method nor combination of event listeners that could solve this problem. The closest I got was disabling all modifications to slider value, no matter how it was changed:
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);
}
}
}
}
Basically it creates a new SliderLocker
which has a public flag .preventSlide
. When set to true
, it will prevent all user interactions (and even code-triggred interactions, such as .setValue()
).
My previous code had included some mouse listeners that would attempt to check if the slider was being 'slid' (changed with actual mouse drag) but I later found out that holding down mouse out of slider button and dragging broke the handler.
-
thank you for the effort.. i think this gives me an idea on how i should go about it. – user6866106 Oct 06 '16 at 21:35