Pregunta

Tengo el siguiente código:

    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());  
        }
    }); 

automóviles desplaza hacia abajo. Pero, si trato de desplazarse hacia atrás hasta volver a leer un mensaje, que obliga a un desplazamiento hacia abajo. ¿Cómo puedo solucionar este problema?

¿Fue útil?

Solución

Al agregar un nuevo mensaje, invoke scrollRectToVisible() en la JList usando un Rectangle tener las mismas dimensiones que el tamaño preferido del panel de mensajes. Dada una orientación vertical, puede ser conveniente para que el tamaño preferido de la JScrollPane 's JViewport un múltiplo entero de la altura del panel de mensajes. Véase también: ¿Cómo utilizar el Desplazamiento Panes .

Adición: Esta discusión convincente de Área de texto de desplazamiento puede ser útil, también.

Otros consejos

Me encontraron esta 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 encontrar un evento que se activa después tanto el ListModel, JList y JScrollPane han sido actualizados."

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());

@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() toma el scroller a su máximo; mientras getValue() lleva a donde quiera evento ocurre.

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.

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++);
     /*
     *
     */


    }

utiliza JScrollPane con JTextArea. Evité de desplazamiento de fuerza por el desplazamiento sólo cuando el valor JScrollBar max cambió:

        JScrollPane scrollPane = new JScrollPane(jTextArea);

        verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
        scrollPane.getVerticalScrollBar().addAdjustmentListener(
                e -> {
                    if ((verticalScrollBarMaximumValue - e.getAdjustable().getMaximum()) == 0)
                        return;
                    e.getAdjustable().setValue(e.getAdjustable().getMaximum());
                    verticalScrollBarMaximumValue = scrollPane.getVerticalScrollBar().getMaximum();
                });

supongo, hay una mejor solución a los eventos de filtro sin variables adicionales, y agradecería si alguien posterior a él.

Creo que lo que quiere hacer es tener que desplazarse hacia abajo cuando se agrega cosas a su messageList, en lugar de sobre el ajuste. 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 hacerlo con facilidad. Aunque se puede ver si el AdjustmentEvent.getAdjustmentType() devuelve valores diferentes en esos casos, si eso es cierto, entonces usted podría tener una sentencia if en su clase interna anónima.

Otra cosa que podría intentar sería tener una variable booleana en alguna parte que consigue el sistema cuando se agrega algo a la lista. Luego, en el controlador de comprobar para ver si se establece la variable. Si es así, lo hace el ajuste (y desactivar la variable) de lo contrario, usted lo ignora. De esta manera, sólo habrá de ser añadido a la lista un desplazamiento hacia abajo por artículo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top