Question

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 :)

Was it helpful?

Solution

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());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top