2009-02-05 12 views
13

Cada vez que hago clic en un JSlider, se coloca un Tick principal en la dirección del clic en lugar de saltar al punto en el que hago clic. (Si el control deslizante está en el punto 47 y hago clic en 5, saltará a 37 en lugar de 5). ¿Hay alguna manera de cambiar esto al usar JSliders, o tengo que usar otra estructura de datos?Pregunta de JSlider: Posición después del clic izquierdo

Respuesta

16

Por extraño que parezca, en realidad es el Look and Feel el que controla este comportamiento. Eche un vistazo al BasicSliderUI, el método que debe sobrescribir es scrollDueToClickInTrack(int).

Con el fin de establecer el valor de la JSlider al valor más cercano a donde el usuario hace clic en la pista, que había necesidad de hacer alguna traducción pantalones de fantasía entre las coordenadas del ratón de getMousePosition() a un valor válido pista, teniendo en tenga en cuenta la posición del Component, su orientación, tamaño y distancia entre los ticks etc.. Por suerte, BasicSliderUI nos da dos funciones útiles para hacer esto: valueForXPosition(int xPos) y 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); 
    } 
}); 
+0

Eso es sorta extraño, buena captura. Tratando de descubrir cómo se crea la entrada a scrollDue .. (int). Para que se determine la dirección, debe haber alguna comprobación en la que haga clic en comparación con la posición del deslizador. Para que eso se determine, ¿algún método no necesita saber exactamente en qué parte del control deslizante hago clic? –

+0

en realidad, la dirección es fácil: para una pista horizontal solo necesita saber que la coordenada x del clic del mouse es menor o mayor que la coordenada x del control deslizante. – ninesided

+0

Sí, pero para saber si es menor o mayor que la coordenada X, ¿no necesita saber en qué control deslizante hace clic para hacer la comparación? Si el control deslizante está en 50, necesita saber dónde hace clic para ver si esa posición es> o <50, ¿no? –

0

Este comportamiento se deriva del sistema operativo. ¿Seguro que quieres redefinirlo y confundir a los usuarios? No lo creo. ;)

4

Esta pregunta es un poco antigua, pero acabo de encontrarme con este problema. Esta es mi solución:

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); 
    } 
}; 
+0

¿esta solución no significa que ya no puede usar una rueda de desplazamiento para mover el control deslizante? – ninesided

+0

+1, hice un ligero cambio para eliminar y agregar MouseMotionListener. Esto proporciona un pequeño cambio cosmético en el sentido de que el mouse permanecerá centrado en el control deslizante mientras arrastra el pulgar en lugar de saltar al borde izquierdo del pulgar. – camickr

Cuestiones relacionadas