Il est resté bloqué et a été époustouflé pendant quelques heures, donc au lieu d'un mémo. Quiconque utilise Swing semble avoir échoué une fois.
J'essayais de créer quelque chose comme un shell auto-créé en Java, et j'essayais de faire défiler automatiquement JScrollPane. C'est le code source que j'ai écrit lors de la vérification.
MyShell.java
class MyShell extends JFrame implements ActionListener{
MyShell{
//(Omis)
String now = new File(".").getAbsoluteFile().getParent().toLowerCase();//Répertoire actuel
JTextField text = new JTextField();//Zone de saisie
text.addActionListener( this );
JTextArea area = new JTextArea(now+"->");//Zone d'affichage
JScrollPane scrollpane = new JScrollPane(area);
JPanel p = new JPanel()
p.add(text,BorderLayout.SOUTH);
p.add(scrollpane);
//(Omis)
}
public void actionPerformed(ActionEvent e){
String input = text.getText().toLowerCase();
if(input.equals("exit")){System.exit(0);}//Pour résiliation forcée
area.append(text.getText()+"\nPC->"+mani(input.split(" "))+"\n\n"+now+"->");//Ajouté à la zone de dessin
text.setText("");//Effacer le contenu de la zone de saisie
JScrollBar scrollBar = scrollpane.getVerticalScrollBar();
scrollBar.setValue(scrollBar.getMaximum());
}
public String mani(String[] input){
//Fonction d'interprétation des commandes
}
//(Omis)
}
Pour le moment, actionPerformed est appelée lorsque la touche Entrée est enfoncée dans le champ de saisie de texte (lien de référence) ). Ensuite, immédiatement après avoir appuyé sur la touche Entrée, la commande est interprétée et ajoutée à la zone de dessin. Après cela, il a été défilé par la hauteur de la barre de défilement, et le bas de JTextArea a été affiché ...
En conclusion, le processus enregistré comme gestionnaire d'événements est dessiné une fois tous les processus terminés. En d'autres termes, la taille qui peut être obtenue avec
scrollBar.getMaximum () '' est la taille avant de redessiner, donc vous ne pouvez aller qu'au bas de JTextArea avant de redessiner. Si vous insérez également Thread.sleep (1000)
dans la dernière ligne de ʻactionPerformed`, vous pouvez bien voir le comportement.
Eh bien, si vous y réfléchissez bien, il vaut mieux faire le processus de dessin le moins de fois possible, et bien sûr, c'est naturel.
(Si vous recherchez correctement sur le net, vous pouvez obtenir autant d'informations que vous le souhaitez ...)
Pensez à un seul gestionnaire d'événements comme n'autorisant que les changements d'état et un seul appel de repeindre. Même si vous appelez repaint plusieurs fois, la méthode paintComponent ne sera appelée qu'une seule fois. Source: https://teratail.com/questions/75183
Après une enquête plus approfondie, cet article est ... Certaines personnes étaient coincées avec la même chose ... J'ai mis le code de cet article dans ʻactionPerformed` et cela a bien fonctionné.
De plus, Swing semblait être une conception à un seul fil.
La méthode invokeLater () ... se déclenche après que tous les événements AWT en attente ont été traités
Source: http://wisdom.sakura.ne.jp/system/java/swing/swing4.html
En passant, j'ai également essayé d'utiliser «paintImmediately». Apparemment, seul le processus de dessin est utilisé et les autres valeurs numériques sont mises à jour après la fin du gestionnaire d'événements.
MyShell.java
actionPerformed(ActionEvent e){
System.out.println(scrollbar.getValue()+"#"+scrollbar.getMaximum()+"#"+area.getHeight());
p.paintImmediately(0,0,5000,5000);
System.out.println(scrollbar.getValue()+"#"+scrollbar.getMaximum()+"#"+area.getHeight());
}