6

As explained in the title, i made a simple JSlider, and i successfully setted a minimum and maximum value, and a minor tick spacing, then i setted the "setSnapToTicks" to true. No problem with that part, my knob move on the closest tick when the user release the mouse, it can't be easier.

But now i want to get this effect without release the mouse, the knob have to move tick by tick without paying any attention on the values between those ticks, i want it to "jump" only on ticks values. I just made many searches, and i didn't find the answer, i just eard about "setExtent", which is supposed to set the sort of step i'm searching for, but it didn't work after some debugging. Here is my simple declaration of the JSlider :

sliderFlightLevel = new JSlider();
sliderFlightLevel.setValue(100);
sliderFlightLevel.setMinorTickSpacing(100);
sliderFlightLevel.setMinimum(100);
sliderFlightLevel.setMaximum(50000);
GridBagConstraints gbcSliderFlightLevel = new GridBagConstraints();
gbcSliderFlightLevel.gridwidth = 3;
gbcSliderFlightLevel.insets = new Insets(0, 10, 5, 10);
gbcSliderFlightLevel.fill = GridBagConstraints.HORIZONTAL;
gbcSliderFlightLevel.gridx = 0;
gbcSliderFlightLevel.gridy = 1;
mainPanel.add(sliderFlightLevel, gbcSliderFlightLevel);

Thanks for reading, i hope i'll get some help :)

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • As mentioned in my answer, the snapping behavior certainly depends on the look & feel you are using. Could you tell us which one you are using ? – barjak Mar 08 '13 at 12:24
  • It looks like the metal core on the link you posted. This is what you need to know ? (i'm sorry but i'm working on an existing big project and i didn't take care of all the graphics specifications which are already developed in) –  Mar 08 '13 at 13:32
  • Yes, this is the info I need. It makes sense, because Metal is the default (but unfortunately ugly !) look & feel. – barjak Mar 08 '13 at 13:39
  • The problem is that i'm not allowed to modify that look and feel for now, but i'm still searching on the web and reading your link, thanks for your help, i'll post what i found ;) –  Mar 08 '13 at 13:52
  • I tested the Nimbus, Metal, Motif and Gtk look & feels. They all behave the same. It seems to me that your only option will be to cutomize the UI delegate (or find a clever hack). – barjak Mar 08 '13 at 14:00
  • Seems the same to me, thanks for all ! –  Mar 08 '13 at 14:02

1 Answers1

2

I think this behavior is controlled by the UI delegate of the component (SliderUI). You can try another look & feel, or you can try to configure the one you use.

You can also install another UI delegate on your component.

See this real world example of customizing the behavior of a swing component.

Edit

I came up with a ugly hack that does the job. This code is completely dependant on the implementation details of the class BasicSliderUI (which is used by most look & feels).

import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JSlider;
import javax.swing.plaf.metal.MetalSliderUI;

public class MetalSnapSliderUI extends MetalSliderUI {

    private MouseMotionListener myMouseMotionListener = new MouseMotionListener() {

        public void mouseDragged(MouseEvent e) {
            trackListener.mouseDragged(e);
            calculateThumbLocation();
            slider.repaint();
        }

        public void mouseMoved(MouseEvent e) {
            trackListener.mouseMoved(e);
        }

    };

    @Override
    protected void installListeners(JSlider slider) {
        super.installListeners(slider);
        slider.removeMouseMotionListener(trackListener);
        slider.addMouseMotionListener(myMouseMotionListener);
    }

    @Override
    protected void uninstallListeners(JSlider slider) {
        super.uninstallListeners(slider);
        slider.removeMouseMotionListener(myMouseMotionListener);
    }

}

You will need to install this UI on the JSlider :

    JSlider s = new JSlider();
    s.setUI(new MetalSnapSliderUI());
barjak
  • 10,842
  • 3
  • 33
  • 47