JSlider : can't make the knob move on the closest tick during drag
Asked Answered
G

1

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

Garrygarson answered 8/3, 2013 at 11:11 Comment(6)
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 ?Paedogenesis
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)Garrygarson
Yes, this is the info I need. It makes sense, because Metal is the default (but unfortunately ugly !) look & feel.Paedogenesis
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 ;)Garrygarson
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).Paedogenesis
Seems the same to me, thanks for all !Garrygarson
P
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());
Paedogenesis answered 8/3, 2013 at 11:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.