2010-01-25 24 views
13

Tengo el siguiente código:JScrollPane y JList desplazamiento automático

listModel = new DefaultListModel(); 
    listModel.addElement(dateFormat.format(new Date()) + ": Msg1"); 
    messageList = new JList(listModel); 
    messageList.setLayoutOrientation(JList.VERTICAL); 

    messageScrollList = new JScrollPane(messageList); 
    messageScrollList.setPreferredSize(new Dimension(500, 200)); 

    messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getMaximum()); 
     } 
    }); 

se desplaza hacia abajo de automóviles. Pero, si trato de retroceder para volver a leer un mensaje, fuerza un desplazamiento hacia abajo. ¿Cómo puedo solucionar esto?

Respuesta

10

Al agregar un mensaje nuevo, invoque scrollRectToVisible() en el JList utilizando un Rectangle que tenga las mismas dimensiones que el tamaño preferido del panel de mensajes. Dada una orientación vertical, puede ser conveniente hacer que el tamaño preferido del JScrollPaneJViewport sea un múltiplo entero de la altura del panel de mensajes. Vea también: How to Use Scroll Panes.

Adición: Esta discusión convincente de Text Area Scrolling puede ser útil también.

-1

Creo que lo que quiere hacer es hacer que se desplace hacia abajo cuando agrega cosas a su lista de mensajes, en lugar de ajustarlas. Así que el código podría tener este aspecto:

Adjustable sb = messageScrollList.getVerticalScrollBar() 
boolean onBottom = sb.getValue() == sb.getMaximum(); 
// 
// add your message to the JList. 
// 
if(onBottom) sb.setValue(sb.getMaximum()); 

De lo contrario, tendría que decir si el ajuste se debe a un cambio de modelo, o mediante el ratón, y mirando a través de los documentos de la API no estoy seguro de si hay una manera de hacer eso fácilmente Aunque podría ver si el AdjustmentEvent.getAdjustmentType() devuelve valores diferentes en esos casos, si eso es cierto, entonces podría tener una instrucción if en su clase interna anónima.

Otra cosa que podría intentar sería tener una variable booleana en algún lugar que se establece cuando agrega algo a la lista. Luego, en su controlador, verifique si la variable está configurada. Si es así, usted realiza el ajuste (y desarma la variable) de lo contrario, lo ignora. De esta forma, solo se agregará un desplazamiento hacia abajo por artículo a la lista.

+0

El tipo de ajuste es el mismo en ambos casos. He intentado esto para desplazarme hacia abajo si se agrega un mensaje. Pero si lo hago, el último mensaje agregado no es visible. No se desplaza lo suficiente hacia abajo. ¿Cómo puedo resolver eso? – dododedodonl

+0

Hmm ... Bueno, una cosa que podrías hacer sería tener una variable booleana en algún lugar que se configure cuando agregas algo a la lista. Luego, en su controlador, verifique si la variable está configurada. Si es así, usted realiza el ajuste (y desarma la variable) de lo contrario, lo ignora. De esta forma, solo se agregará un desplazamiento hacia abajo por artículo a la lista. –

1
this.list = blah blah... 
this.list.setSelectedValue(whatever); 
final JScrollPane sp = new JScrollPane(this.list); // needs to be after the parent is the sp 
this.list.ensureIndexIsVisible(this.list.getSelectedIndex()); 
1

yo encontramos este realmente útil: http://forums.sun.com/thread.jspa?threadID=623669 (mensaje por 'inopia')
Funciona perfectamente

Como él dice: "El problema aquí es que puede ser un poco difícil de encontrar un evento que se dispara después de que se hayan actualizado tanto ListModel, JList como JScrollPane ".

+0

El enlace está muerto. ¿Puedes actualizarlo? –

0

Para el desplazamiento automático estoy usando un concepto muy simple de la variable estática y list.makeVisible (int index)

public class autoScrollExample 
    { 
    static int index=0; 
    private void someFunction() 
    /* 
    * 
    */ 
    list1.add("element1"); 
    list1.makeVisible(index++); 
    /* 
    * 
    */ 

    private void someOtherFunction() 
    /* 
    * 
    */ 
    list1.add("element2"); 
    list1.makeVisible(index++); 
    /* 
    * 
    */ 


    } 
1

@question investigador. Por favor, cambie su código de

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getMaximum()); 
     } 
    }); 

a

messageScrollList.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
     public void adjustmentValueChanged(AdjustmentEvent e) { 
      e.getAdjustable().setValue(e.getAdjustable().getValue()); 
     } 
    }); 

Ese es el cambio getMaximum() a getValue() entonces funciona como se requiere. getMaximum() lleva el desplazamiento al máximo; mientras que getValue() lo lleva a donde sea que ocurra un evento.

Usted puede evitar el uso de este pedazo de código por completo si se pone una línea

messageScrollList.setViewportView(messageList); 

que funciona como add(component) para JList y obtiene su comportamiento inherente.

Cuestiones relacionadas