Pregunta

He incrustado un JTextArea en un JScrollPane y estoy usando ese JTextArea para la salida.

Quiero que cada vez que la salida supere el tamaño de JTextArea, JTextArea se desplace automáticamente para que el usuario no tenga que desplazarse manualmente hacia abajo para ver la salida reciente.

¿Cómo puedo hacer eso?

Ya configuré la propiedad de desplazamiento automático de JTextArea y JScrollPane en true.

¿Fue útil?

Solución

Cuando use JDK1.4.2 (o anterior), la sugerencia más común que encontrará en los foros es usar código como el siguiente:

textArea.append(...);
textArea.setCaretPosition(textArea.getDocument().getLength());

Sin embargo, acabo de darme cuenta de que en JDK5 este problema se resolvió realmente mediante un cambio de API. Ahora puede controlar este comportamiento estableciendo una propiedad en DefaultCaret del área de texto. Usando este enfoque, el código sería:

JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);

Nota:

La sugerencia anterior para establecer la política de actualización de caret no funciona.

En su lugar, puede consultar Smart Scrolling que le da al usuario la capacidad de determinar cuándo el desplazamiento debe ser automático o no.

Se puede encontrar una descripción más detallada del desplazamiento automático en un área de texto aquí: Desplazamiento del área de texto

Otros consejos

    JScrollBar vbar = scrollPane.getVerticalScrollBar();

    for (int i = 0; i < 20; i++) {

        myJTxt.append("This is text " + i + "\n");
        vbar.setValue(vbar.getMaximum());
        vbar.paint(vbar.getGraphics());
        myJTxt.scrollRectToVisible(myJTxt.getVisibleRect());
        myJTxt.paint(myJTxt.getGraphics());
        try {
            Thread.sleep(250);
        } catch (InterruptedException ex) {
            Logger.getLogger(ScrollTextView.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

Cuando hace clic en cualquier lugar sobre JTextArea, se puede detener el desplazamiento automático. Debido a que la posición de caret una vez cambió, el punto de vista también cambió. En este momento, debe establecer la posición de intercalación cuando agrega o agrega texto. En mi camino, hice un método que incluía establecer la posición del cursor, y luego lo utilicé para agregar o agregar algo.

    JTextArea jTextArea = new JTextArea();
    DefaultCaret caret = (DefaultCaret)jTextArea.getCaret();
    caret.setUpdatePolicy(DefaultCaret.OUT_BOTTOM);

Intenté la mayoría de las sugerencias pero tuve problemas cuando el contenido de JTextArea se hizo grande (varios MB). Finalmente, lo siguiente mostró el mejor rendimiento:

myTextArea.append( someText );
myTextArea.getCaret().setDot( Integer.MAX_VALUE );

Por supuesto, cualquier selección que el usuario haya hecho se pierde. Por lo tanto, solo se puede usar para una pantalla de solo visualización uso del área de texto.

Aún así, en mi instalación, si el contenido de JTextArea supera los 9 MB, se vuelve inutilizable (interfaz gráfica de usuario muy lenta o casi congelada).

Un fenómeno similar ocurre cuando el texto contiene caracteres representados por dos caracteres (dos unidades de 16 bits) en la codificación UTF-16 (los llamados pares sustitutos, como este: this). Tengo una solución para filtrar, pero quizás un tema diferente.

Use esto en su lugar

JTextArea textArea = new JTextArea();
DefaultCaret caret = (DefaultCaret)textArea.getCaret();
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
scrollPane = new JScrollPane();
scrollPane.add(textArea);
scrollPane.setViewportView(textArea);

Prueba esto:

JTextArea jTextArea = new JTextArea();
JScrollPane jScrollPane = new JScrollPane();
jScrollPane.setViewport(jTextArea);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top