Java / Swing : JTextArea dans un JScrollPane, comment empêcher le défilement automatique?
voici un exécutable morceau de code qui montre ce que mon "problème" est.
J'ai un JTextArea
enveloppé dans un JScrollPane
. Lorsque je modifie le texte de la JTextArea
, le JScrollPane
défile automatiquement à la fin du texte, et je n'en veux pas.
Voici mes exigences:
- l'application ne devrait pas faire défiler verticalement automatiquement mais...
- l'utilisateur devrait être en mesure de faire défiler verticalement
- l'utilisateur ne devrait pas être en mesure de faire défiler horizontalement
- l'application ne doit jamais défiler horizontalement
- le JTextArea ne doit pas être modifiable
(donc même si il n'y a plus de texte que ce qui peut tenir à l'horizontale, ni l'application, ni l'utilisateur doit être en mesure de faire défiler horizontalement. Alors que verticalement, l'utilisateur doit être en mesure de les faire défiler.)
Je ne sais pas comment "réparer" ce, faut-il être fixé à l'aide de JTextArea
ou JScrollPane
méthodes?
Noter que AFAICT c'est pas une double exemplaire à tous: JTextPane empêche de défilement dans le parent JScrollPane
Voici le marrant exemple, toutes les 200 ms, il met le nouveau texte dans le JTextArea
et vous pouvez voir la JScrollPane
toujours défiler automatiquement à la fin du texte.
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();
}
}
OriginalL'auteur SyntaxT3rr0r | 2010-10-19
Vous devez vous connecter pour publier un commentaire.
Comment mettre en DÉFILEMENT AUTOMATIQUE de JTextArea en Java GUI?
http://download.oracle.com/javase/1.5.0/docs/api/javax/swing/text/DefaultCaret.html#NEVER_UPDATE
Essayer:
Ce qui devrait éviter le curseur de faire automatiquement le document, faites défiler vers le bas.
OriginalL'auteur I82Much
Pour répondre à ma propre question: je ne suis pas sûr que c'est la meilleure façon de résoudre mon problème, mais le réglage du
JTextArea's
curseur à l'aide desetCaretPosition(0)
semble bien fonctionner:OriginalL'auteur SyntaxT3rr0r
Vous avez exécuté dans un très étrange comportement dans la mise en œuvre du Document de classes. J'utilise un DefaultStyledDocument dans un JTextPane à l'intérieur d'un JScrollPane.
Maintenant, voici la chose bizarre. Si je mettre à jour le document sur le EventQueue (comme vous le faites par la planification d'un exécutable à exécuter plus tard) le panneau défilant défile automatiquement à la fin.
Cependant, les catégories de document demande à être thread-safe et effectivement mis à jour à partir d'un autre thread. Si je fais en sorte de mise à jour sur un autre thread que EventQueue tout fonctionne bien, mais le défilement volet ne faites défiler jusqu'à la fin.
Je n'ai pas d'explication quant à pourquoi il en est ainsi, je n'ai pas regardé dans le Swing de la source. J'ai été l'exploitation de cette "fonctionnalité" depuis 2006 et il a été conforme à ce jour 🙂
OriginalL'auteur Johan M