Java / Swing: JTextArea en un JScrollPane, ¿cómo evitar el desplazamiento automático?
Aquí hay un código ejecutable que muestra cuál es mi "problema".
tengo unJTextArea
envuelto en unJScrollPane
. Cuando cambio el texto de laJTextArea
, elJScrollPane
se desplaza automáticamente hasta el final del texto y no quiero eso.
Aquí están mis requisitos:
la aplicaciónno debería desplazarse verticalmente automáticamente pero ...el usuariodebería ser capaz de desplazarse verticalmenteel usuariono debería ser capaz de desplazarse horizontalmentela aplicaciónnunca debería desplazarse horizontalmenteJTextArea no debe ser editable(por lo tanto, incluso si hay más texto del que puede caber horizontalmente, ni la aplicación ni el usuario deberían poder desplazarse horizontalmente. Mientras que verticalmente, solo el usuario debería poder desplazarse).
No sé cómo "arreglar" esto: si esto se soluciona usandoJTextArea
oJScrollPane
métodos?
Tenga en cuenta que AFAICT esto esno un duplicado en absoluto de:JTextPane evita el desplazamiento en el JScrollPane padre
Aquí está el ejemplo un poco divertido, cada 200 ms pone texto nuevo en elJTextArea
y puedes ver elJScrollPane
siempre desplazándose automáticamente al final del texto.
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public final class TextInScrollPane extends JFrame {
private static final Random r = new Random( 42 );
public static void main( final String[] args ) {
final JFrame f = new JFrame();
f.setDefaultCloseOperation( EXIT_ON_CLOSE );
f.setLayout(new BorderLayout());
final JTextArea jta = new JTextArea( "Some text", 30, 30 );
jta.setEditable( false ); // This must not be editable
final JScrollPane jsp = new JScrollPane( jta );
jsp.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
jsp.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );
f.add( jsp, BorderLayout.CENTER );
f.pack();
f.setLocationRelativeTo( null );
f.setVisible(true);
final Thread t = new Thread( new Runnable() {
public void run() {
while ( true ) {
try {Thread.sleep( 200 );} catch ( InterruptedException e ) {}
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < 50 + r.nextInt( 75 ); i++) {
for (int j = 0; j < r.nextInt(120); j++) {
sb.append( (char) 'a' + r.nextInt(26) );
}
sb.append( '\n' );
}
SwingUtilities.invokeLater( new Runnable() {
public void run() {
jta.setText( sb.toString() );
}
} );
}
}
});
t.start();
}
}