JSlider question: Position après LeftClick
-
21-08-2019 - |
Question
Chaque fois que je clique sur un JSlider il se positionne un majorTick dans la direction du clic au lieu de sauter à l'endroit que je fait clic. (Si curseur est au point 47 et je clique sur 5, il va passer à 37 au lieu de 5). Est-il possible de changer cela en utilisant JSliders, ou dois-je utiliser une autre structure de données?
La solution
Aussi bizarre que cela puisse paraître, il est en fait le look and feel qui contrôle ce comportement. Jetez un oeil à BasicSliderUI
, la méthode que vous devez remplacer est scrollDueToClickInTrack(int)
.
Pour définir la valeur de la valeur à la JSlider
le plus proche de l'endroit où l'utilisateur a cliqué sur la piste, vous aurez besoin de faire une traduction pantalon de fantaisie entre coordonnées de la souris de valeur à une getMousePosition()
de piste en cours de validité , compte tenu de la position de la Component
, il est l'orientation, la taille et la distance entre les tiques etc . Heureusement, nous donne deux valueForXPosition(int xPos)
fonctions pratiques pour le faire: valueForYPosition(int yPos)
et <=> :
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);
}
});
Autres conseils
Cette question est un peu vieux, mais je me couru sur ce problème. Ceci est ma solution:
JSlider slider = new JSlider(/* your options here if desired */) {
{
MouseListener[] listeners = getMouseListeners();
for (MouseListener l : listeners)
removeMouseListener(l); // remove UI-installed TrackListener
final BasicSliderUI ui = (BasicSliderUI) getUI();
BasicSliderUI.TrackListener tl = ui.new TrackListener() {
// this is where we jump to absolute value of click
@Override public void mouseClicked(MouseEvent e) {
Point p = e.getPoint();
int value = ui.valueForXPosition(p.x);
setValue(value);
}
// disable check that will invoke scrollDueToClickInTrack
@Override public boolean shouldScroll(int dir) {
return false;
}
};
addMouseListener(tl);
}
};
Ce comportement est dérivé du système d'exploitation. Etes-vous sûr de vouloir redéfinir et dérouter les utilisateurs? Je ne le pense pas. ;)