[JAVA] Als ich versuchte, mit JScrollBar automatisch zu scrollen, wurde der Ereignishandler nur einmal gezeichnet.

Es blieb stecken und wurde für ein paar Stunden weggeblasen, also statt eines Memos. Jeder, der Swing benutzt, scheint einmal gescheitert zu sein.

Was wurde gemacht

Ich habe versucht, so etwas wie eine selbst erstellte Shell in Java zu erstellen, und ich habe versucht, JScrollPane automatisch zu scrollen. Dies ist der Quellcode, den ich beim Überprüfen geschrieben habe.

MyShell.java


class MyShell extends JFrame implements ActionListener{
    MyShell{
//(Weggelassen)
    String now = new File(".").getAbsoluteFile().getParent().toLowerCase();//Aktuelles Verzeichnis

    JTextField text = new JTextField();//Eingabebereich
    text.addActionListener( this );
    JTextArea area = new JTextArea(now+"->");//Anzeigebereich
    JScrollPane scrollpane = new JScrollPane(area);

    JPanel p = new JPanel()
    p.add(text,BorderLayout.SOUTH);
    p.add(scrollpane);
//(Weggelassen)
    }
    public void actionPerformed(ActionEvent e){
  	    String input = text.getText().toLowerCase();
  	    if(input.equals("exit")){System.exit(0);}//Zur erzwungenen Kündigung
        area.append(text.getText()+"\nPC->"+mani(input.split(" "))+"\n\n"+now+"->");//Zum Zeichenbereich hinzugefügt
        text.setText("");//Löschen Sie den Inhalt des Eingabebereichs

        JScrollBar scrollBar = scrollpane.getVerticalScrollBar();
        scrollBar.setValue(scrollBar.getMaximum());
    }
    public String mani(String[] input){
        //Befehlsinterpretationsfunktion
    }
//(Weggelassen)
}

Derzeit wird actionPerformed aufgerufen, wenn die Eingabetaste im Eingabetextfeld [(Referenzlink)] gedrückt wird (https://www.javadrive.jp/tutorial/event/index2.html). ). Unmittelbar nach dem Drücken der Eingabetaste wird der Befehl interpretiert und dem Zeichenbereich hinzugefügt. Danach wurde es um die Höhe der Bildlaufleiste gescrollt und der untere Rand der JTextArea wurde angezeigt ...

Was schief gelaufen ist

Abschließend wird der als Ereignishandler registrierte Prozess gezeichnet, nachdem alle Prozesse abgeschlossen wurden. Mit anderen Worten, die Größe, die mit `scrollBar.getMaximum ()` erhalten werden kann, ist die Größe vor dem Neuzeichnen, sodass Sie vor dem Neuzeichnen nur zum Ende der JTextArea gehen können. Wenn Sie versuchen, "Thread.sleep (1000)" in die letzte Zeile von "actionPerformed" einzufügen, können Sie das Verhalten gut erkennen. Wenn Sie sorgfältig darüber nachdenken, ist es besser, den Zeichenvorgang so oft wie möglich durchzuführen, und natürlich ist es natürlich.

Lösung

(Wenn Sie das Internet richtig durchsuchen, können Sie so viele Informationen erhalten, wie Sie möchten ...)

Stellen Sie sich einen einzelnen Ereignishandler vor, der nur Statusänderungen und einen einzelnen Repaint-Aufruf zulässt. Selbst wenn Sie repaint mehrmals aufrufen, wird die paintComponent-Methode nur einmal aufgerufen. Quelle: https://teratail.com/questions/75183

Nach weiteren Untersuchungen ist dieser Artikel ... Einige Leute saßen mit der gleichen Sache fest ... Ich habe den Code in diesem Artikel in "actionPerformed" eingefügt und es hat gut funktioniert.

Außerdem schien Swing ein Single-Thread-Design zu sein.

Die invokeLater () -Methode ... wird ausgelöst, nachdem alle ausstehenden AWT-Ereignisse verarbeitet wurden

Quelle: http://wisdom.sakura.ne.jp/system/java/swing/swing4.html

Zusammenfassung

  1. Versuchen Sie nicht, mit einem Ereignishandler etwas zu tun
  2. Grundsätzlich führt der Ereignishandler die Zeichnungsverarbeitung am Ende nur einmal durch.
  3. Wenn Sie eine Zeichnungsverarbeitung von einem anderen als dem Event-Handler-Thread in Swing ausführen möchten, verwenden Sie invokeLater ()

Beiseite

Nebenbei habe ich auch versucht, paintImmed sofort zu verwenden. Anscheinend wird nur der Zeichenprozess verwendet, und andere numerische Werte werden nach dem Ende des Ereignishandlers aktualisiert.

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

das ist alles.

Recommended Posts

Als ich versuchte, mit JScrollBar automatisch zu scrollen, wurde der Ereignishandler nur einmal gezeichnet.
Probleme, denen ich beim Erstellen der Digdag-Umgebung mit Docker verfallen war
Eine Geschichte, nach der ich süchtig war, als ich einen Schlüssel bekam, der automatisch auf MyBatis ausprobiert wurde
Wovon ich bei der Einführung der JNI-Bibliothek süchtig war
Ich habe versucht, die Verarbeitungsgeschwindigkeit mit spiritueller Technik zu erhöhen
Was ich mit der Redmine REST API süchtig gemacht habe
Als ich versuchte, Azure Kinect DK mit Docker auszuführen, wurde es von EULA blockiert
Die Geschichte, nach der ich beim Einrichten von STS süchtig war
Ich habe versucht, das Problem der "mehrstufigen Auswahl" mit Ruby zu lösen
Ich habe versucht, mit Docker eine Plant UML Server-Umgebung zu erstellen
Ich habe versucht, die Bildvorschau mit Rails / jQuery zu implementieren
Ich habe versucht, die Fehlermeldung beim Ausführen von Eclipse (Java) zu übersetzen.
Wovon ich süchtig war, als ich die Google-Authentifizierung mit Rails implementierte
Ich habe nachgesehen, weil die Antwort beim Debuggen mit Tomcat 8 seltsam war
Ich habe versucht, den Betrieb des gRPC-Servers mit grpcurl zu überprüfen
Scrollen Sie automatisch mit libGDX durch den Hintergrund
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, die Methode zu erklären
Ich habe versucht, den Ablauf bei der Bildanalyse mit Vision Framework und Core ML herauszufinden
[Rails] Ich war süchtig nach den Nginx-Einstellungen, als ich Action Cable verwendete.
Eine Geschichte, der ich beim Testen der API mit MockMVC verfallen war
Ich habe versucht, das Problem der Tribonacci-Sequenz in Ruby mit Wiederholung zu lösen.
Ich habe versucht, den Zugriff von Lambda → Athena mit AWS X-Ray zu visualisieren
Ich war süchtig nach Unit-Tests mit dem Pufferoperator in RxJava
Beim Formatieren mit SimpleDateFormat blieb ich beim Umgang mit Zeitzonen
Ich habe versucht, die Geschwindigkeit von Graal VM mit JMH zu messen und zu vergleichen
Wenn ich versuche, mich bei devise anzumelden, wird automatisch zu root_path umgeleitet
Ich habe versucht, die verwendeten Methoden zusammenzufassen
Da der Befehl du, der bei voller Kapazität verwendet wird, schwierig zu verwenden ist, habe ich versucht, ihn mit Rubin zu umwickeln
Ich habe versucht, mit Web Assembly zu beginnen
Ich war süchtig nach der Rollmethode
Ich habe versucht, das Iterator-Muster zu implementieren
Ich war süchtig nach dem Spring-Batch-Test
Ich habe versucht, die Stream-API zusammenzufassen
Was ich versucht habe, als ich alle Felder einer Bohne bekommen wollte
Ich habe versucht, die Infrastrukturtechnologie der Ingenieure heutzutage mit dem Kochen zu vergleichen.
Ich versuchte noch einmal zusammenzufassen, was auf den ersten Blick schwierig war
[JavaScript] Der stärkste Fall, als ich versuchte, die Teile zusammenzufassen, die ich nicht verstehe
Ich habe versucht, automatisch eine Klasse zu generieren, um sie mit APT von einer Datenklasse in ein Bundle zu konvertieren
Ich habe versucht, AdoptOpenJDK 11 (11.0.2) mit dem Docker-Image zu überprüfen
Ich habe versucht, eine Standardauthentifizierung mit Java durchzuführen
Ich habe versucht, die Federbeinkonfiguration mit Coggle zu verwalten
[Rails] Ich habe versucht, die Version von Rails von 5.0 auf 5.2 zu erhöhen
Ich habe versucht, die Sitzung in Rails zu organisieren
Ich war süchtig danach, onActivityResult () mit DialogFragment zu machen
Ich habe versucht, Tomcat so einzustellen, dass das Servlet ausgeführt wird.
Ich habe versucht, den Block mit Java zu brechen (1)
Wovon ich süchtig war, als ich eine Spring Boot-Anwendung mit VS Code entwickelte
Beachten Sie, dass ich süchtig nach Stapelverarbeitung mit Spring Boot war
Bei der Erstellung der Top-Seite war ich mit dem Umgang mit Bildern beschäftigt (Super-Anfänger)