As bizarre as this might seem, it's actually the Look and Feel which controls this behaviour. Take a look at BasicSliderUI
, the method that you need to override is scrollDueToClickInTrack(int)
.
In order to set the value of the JSlider
to the nearest value to where the user clicked on the track, you'd need to do some fancy pants translation between the mouse coordinates from getMousePosition()
to a valid track value, taking into account the position of the Component
, it's orientation, size and distance between ticks etc. Luckily, BasicSliderUI
gives us two handy functions to do this: valueForXPosition(int xPos)
and valueForYPosition(int yPos)
:
JSlider slider = new JSlider(JSlider.HORIZONTAL);
slider.setUI(new MetalSliderUI() {
protected void scrollDueToClickInTrack(int direction) {
// this is the default behaviour, let's comment that out
//scrollByBlock(direction);
int value = slider.getValue();
if (slider.getOrientation() == JSlider.HORIZONTAL) {
value = this.valueForXPosition(slider.getMousePosition().x);
} else if (slider.getOrientation() == JSlider.VERTICAL) {
value = this.valueForYPosition(slider.getMousePosition().y);
}
slider.setValue(value);
}
});
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…