aquí hay un fragmento de código ejecutable que muestra cuál es mi "problema".Java/Swing: JTextArea en un JScrollPane, ¿cómo evitar el desplazamiento automático?
Tengo un JTextArea
envuelto en un JScrollPane
. Cuando cambio el texto de JTextArea
, el JScrollPane
se desplaza automáticamente hasta el final del texto y no quiero eso.
Éstos son mis requisitos:
- la aplicación no debe de desplazamiento vertical de forma automática, pero ...
- el usuario debe ser capaz de desplazarse verticalmente
- el usuario no debe ser capaz de desplazarse horizontalmente
- la aplicación nunca debería desplazamiento horizontal
- la JTextArea no debe ser editable
(por lo que incluso si hay más texto de lo que se puede encajar en posición horizontal, ni la aplicación ni el usuario debe ser capaz de desplazarse horizontalmente. Mientras que verticalmente, solo el usuario debería ser capaz de desplazarse.)
No sé cómo "arreglar" esto: ¿debería ser arreglado usando los métodos JTextArea
o JScrollPane
?
Tenga en cuenta que AFAICT esto es no un duplicado a todos: JTextPane prevents scrolling in the parent JScrollPane
Aquí está el ejemplo un poco divertido, cada 200 ms se pone nuevo texto en el JTextArea
y se puede ver la JScrollPane
siempre desplazándose automáticamente a la fin 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();
}
}
nota para todos: los comentarios sobre el bloque * catch * vacío y el uso de * final * se pueden enviar a */dev/null *, de esto no se trata en realidad esta pregunta;) – SyntaxT3rr0r