ejemplo - jscrollpane java netbeans
JScrollPane y JList desplazamiento automático (6)
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());
}
});
Se desplaza automáticamente hacia abajo. Pero, si trato de retroceder para volver a leer un mensaje, fuerza un desplazamiento hacia abajo. ¿Cómo puedo arreglar esto?
@question enquirer. 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());
}
});
Eso es change getMaximum()
to getValue()
Luego funciona según se requiera. getMaximum()
lleva el desplazamiento al máximo; mientras que getValue()
lleva donde sucede el evento.
Puedes evitar usar este código por completo si pones una línea
messageScrollList.setViewportView(messageList);
Eso funciona como add(component)
para jList y obtiene su comportamiento inherente.
Al agregar un nuevo mensaje, invoque scrollRectToVisible()
en la scrollRectToVisible()
utilizando un Rectangle
tenga las mismas dimensiones que el tamaño preferido de su panel de mensajes. Dada una orientación vertical, puede ser conveniente hacer que el tamaño preferido del JViewport
del JScrollPane
JViewport
un múltiplo integral de la altura del panel de mensajes. Vea también: Cómo usar los paneles de desplazamiento .
Adición: esta discusión convincente de Text Area Scrolling puede ser útil también.
Creo que lo que desea hacer es hacer que se desplace hacia abajo cuando agregue cosas a su lista de mensajes, en lugar de ajustarlas. Entonces su código podría verse así:
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, necesitaría decir si el ajuste fue causado por un cambio de modelo, o por el mouse, y mirando a través de los documentos API. No estoy seguro si hay una manera de hacerlo fácilmente. Aunque podría ver si 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í, haces el ajuste (y desarmas la variable) de lo contrario, lo ignoras. De esta forma, solo se agregará un desplazamiento hacia abajo por artículo a la lista.
Encontré esto realmente útil: http://forums.sun.com/thread.jspa?threadID=623669 (publicado por ''inopia'')
Funciona a la perfección
Como él dice: "El problema aquí es que puede ser un poco difícil encontrar un evento que se active después de que se hayan actualizado tanto ListModel, JList como JScrollPane".
Para desplazar automáticamente estoy usando un concepto muy simple de 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++);
/*
*
*/
}
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());