2012-07-09 26 views
5

Tengo un JScrollPane cuyo panel de contenido es una JXList. Cuando uso la rueda del mouse en la lista, la lista pasa tres (3) elementos a la vez. Esto también funciona para una tabla, independientemente de la altura de la fila. ¿Cómo puedo cambiar esto para que, independientemente de la plataforma, tanto para la lista como para la tabla, la distancia de desplazamiento sea exactamente 1 elemento? El incremento del bloque de configuración no lo corta porque algunas filas en la tabla tienen una altura diferente.¿Cómo hacer que JScrollPane recorra 1 línea por cada paso de la rueda del mouse?

+0

@trashgod no había mirado por un tiempo: la rueda realmente parece corresponderse con la unidad Increment de alguna manera, y maneja alturas de fila individuales, por lo que estaba equivocado con mi duda. Ajustar la implementación desplazable puede ayudar, después de todo :-) – kleopatra

+2

Ver camickr's [Mouse Wheel Controller] (http://tips4java.wordpress.com/2010/01/10/mouse-wheel-controller/) – aterai

+0

@aterai hach ​​.. se olvidó de eso :-) Definitivamente el camino a seguir, considere hacer una respuesta a su comentario, para obtener algunos votos reales. – kleopatra

Respuesta

7

Como curiosidad pura (y un poco de aburrimiento) He creado un ejemplo de trabajo:

/** 
* Scrolls exactly one Item a time. Works for JTable and JList. 
* 
* @author Lukas Knuth 
* @version 1.0 
*/ 
public class Main { 

    private JTable table; 
    private JList list; 
    private JFrame frame; 

    private final String[] data; 

    /** 
    * This is where the magic with the "just one item per scroll" happens! 
    */ 
    private final AdjustmentListener singleItemScroll = new AdjustmentListener() { 
     @Override 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      // The user scrolled the List (using the bar, mouse wheel or something else): 
      if (e.getAdjustmentType() == AdjustmentEvent.TRACK){ 
       // Jump to the next "block" (which is a row". 
       e.getAdjustable().setBlockIncrement(1); 
      } 
     } 
    }; 

    public Main(){ 
     // Place some random data: 
     Random rnd = new Random(); 
     data = new String[120]; 
     for (int i = 0; i < data.length; i++) 
      data[i] = "Set "+i+" for: "+rnd.nextInt(); 
     for (int i = 0; i < data.length; i+=10) 
      data[i] = "<html>"+data[i]+"<br>Spacer!</html>"; 
     // Create the GUI: 
     setupGui(); 
     // Show: 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private void setupGui(){ 
     frame = new JFrame("Single Scroll in Swing"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); 
     frame.add(split); 

     // Add Data to the table: 
     table = new JTable(new AbstractTableModel() { 
      @Override 
      public int getRowCount() { 
       return data.length; 
      } 

      @Override 
      public int getColumnCount() { 
       return 1; 
      } 

      @Override 
      public Object getValueAt(int rowIndex, int columnIndex) { 
       return data[rowIndex]; 
      } 
     }); 
     for (int i = 0; i < data.length; i+=10) 
      table.setRowHeight(i, 30); 
     JScrollPane scroll = new JScrollPane(table); 
     // Add out custom AdjustmentListener to jump only one row per scroll: 
     scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll); 
     split.add(scroll); 

     list = new JList<String>(data); 
     scroll = new JScrollPane(list); 
     // Add out custom AdjustmentListener to jump only one row per scroll: 
     scroll.getVerticalScrollBar().addAdjustmentListener(singleItemScroll); 
     split.add(scroll); 
    } 

    public static void main(String[] agrs){ 
     new Main(); 
    } 
} 

La magia real se realiza en la costumbre AdjustmentListener, dónde vamos y aumentar la corriente de "scroll-posición" por un solo bloque por tiempo Esto funciona hacia arriba y hacia abajo y con diferentes tamaños de fila, como se muestra en el ejemplo.


Como @kleopatra mencionado en los comentarios, también se puede utilizar una única MouseWheelListener a redefinir el comportamiento de la rueda del ratón.

Consulte el tutorial oficial here.

+0

Esto es bastante increíble. ¡Un millón de gracias! Quiero decir, claro, allí/podría/ser .setScrollIncrement (int i) en alguna parte, pero de esta manera también funciona. Solo un pequeño aparte: Este código hace que la característica de la página de la barra de desplazamiento (haciendo clic en la barra fuera del mango) recorra pequeños pasos, lo cual no es muy extraño teniendo en cuenta que su código establece el incremento de bloque en 1 "globalmente". ¿Hay alguna manera de simplemente cambiar el tamaño del paso de la rueda del mouse? Además, ¿puedes recomendar un libro sobre Swing? – xmjx

+0

Ah, tengo que comentar un poco más. Tenía curiosidad de por qué se debe llamar a setBlockIncrement (1) cada vez que se llama al AdjustmentListener, por lo que desactivé el oyente y llamé a setBlockIncrement (1) una vez al momento de crear el panel de desplazamiento. ¡Mirad! Esto funciona, también, con el mismo efecto secundario no deseado. No recuerdo cuál fue el efecto de esto en la máquina de mi oficina, así que lo probaré en el trabajo mañana. A veces no me gusta Swing. ;-) – xmjx

+0

@xmjx para swing, solo lee los tutoriales proporcionados por sun/oracle. No leí un libro dedicado para eso. Swing es bastante poderoso, pero tampoco es el marco de GUI más pequeño. –

Cuestiones relacionadas