2010-10-19 12 views
8

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

} 
+0

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

Respuesta

22

How to set AUTO-SCROLLING of JTextArea in Java GUI?

http://download.oracle.com/javase/1.5.0/docs/api/javax/swing/text/DefaultCaret.html#NEVER_UPDATE

Probar:

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

Esto debería evitar que el cursor desplace automáticamente el documento hacia la parte inferior.

+0

I82Much: ¡me gusta esa política de actualización! Funciona perfectamente también y es mejor que mi hack-answer (donde siempre reinicio la posición de intercalación a cero). – SyntaxT3rr0r

1

responder a mi propia pregunta: No estoy exactamente seguro de que esta es la mejor manera de resolver mi problema, pero estableciendo el símbolo de intercalación JTextArea's usando setCaretPosition(0) parece funcionar bien:

jta.setText(sb.toString()); 
jta.jta.setCaretPosition(0); 
1

Se ha encontrado con un comportamiento muy extraño en la implementación de las clases de documento. Uso un DefaultStyledDocument en un JTextPane dentro de un JScrollPane.

Ahora, aquí está lo extraño. Si actualizo el documento en la EventQueue (como lo hace al programar un ejecutable para ejecutarlo más tarde), el panel de desplazamiento se desplaza automáticamente hasta el final.

Sin embargo, las clases de documentos afirman ser seguros para subprocesos y realmente actualizable desde otro subproceso.Si me aseguro de actualizar en otro subproceso que en EventQueue todo funciona bien, pero el panel de desplazamiento NO se desplaza hasta el final.

No tengo ninguna explicación de por qué esto es así, no he buscado en la fuente de Swing. He estado explotando esta "característica" desde 2006 y ha sido consistente hasta ahora :-)

Cuestiones relacionadas