„90 Prozent der Amerikaner zweifeln an Evolutionstheorie“

… die anderen haben in der Schule aufgepaßt 🙂

Update: 21.2.2014

So angebracht der Witz auch ist, leider sind wir Deutschen nicht vor solchen Problemen gefeit. In Baden-Würtemberg soll jetzt der Biologie Unterricht eingestellt werden und in einem Mix-Fach aus Technik und Biologie aufgehen. Da dort keine Biologen unterrichten würden, meinen Experten, daß dies von den Schülern ( zurecht ) nicht für „voll“ genommen wird. Um jeglicher Diskussion und ggf. Einmischung aus dem Weg zu gehen, wurden alle betroffenen Lehrer und Dozenten vom Ministerium mit einem Maulkorb versehen und Ihnen bei Zuwiderhandlung mit Kündigung gedroht. Zum Glück gibt es standhafte Menschen in allen Positionen, die sich so was in einer freien Gesellschaft nicht gefallen lassen.

Hier eine klare Ansage an alle Politiker: Wir wollen für unsere Kinder und uns keine amerikanischen Verhältnisse!

Java Swing und das Repainten von Komponenten

Von Zeit zu Zeit muß man Dinge tun, welche die Entwickler von Swing nicht vorgesehen hatten. Da wäre z.B. das Updaten einer JTextArea, während das Programm läuft.

Kleines Beispiel:

        for(int i=0;i<names.length;i++ ) {
            infotext = "Uploading file ... "+names[i];
            if ( infotext.length()> 55 ) 
                    infotext = infotext.substring(0, 55);
            updateInfo( infotext );
            String link = p.uploadFile(names[i].trim(),"/");
            result += "File: "+names[i].trim()+"\nShare: "+link+"\n";
        }
    JTextArea text = new JTextArea("");

    public void updateInfo(String text) {
            this.text.setText(text);
    }

Jetzt sollte man annehmen, daß die JTextArea jeweil nach dem setText() den neuen Text anzeigt. Tut sie aber nicht und das betrifft nicht nur JTextArea, sondern so ziemlich alle Komponenten von Swing.

Warum ist das so ?

Swing cacht quasi die ganzen Änderungen und führt diese erst durch, wenn Ruhe eingekehrt ist, d.b. wenn das Programm wartet. Das passiert z.b. wenn eine Dialogbox angezeigt wird. Die Verarbeitung des Programms ist dann eingestellt und es wartet z.B. auf das Drücken des OK Buttons in einem InfoRequester.

Solange das Programm aktiv läuft, gibt es keine Updates, weil das Rechenleistung kostet und sich mit der Zeit einige Inhalteänderungen ergeben haben können, die man dann gemeinsam durchführen kann. So spart das Guisystem Zeit und Resourcen.

Nun ist das Delay einer solchen Sparmaßnahme natürlich kontraproduktiv, wenn es um die kontinuierliche Anzeige neuer Inhalte geht, wie z.b. einem Progressbar oder eben einem textlichen Infofeld wie einer JTextArea.

Die Swing API bietet für Komponenten nun eine Methode repaint() an, die Swing mitteilt, daß die Komponente sich geändert hat und neu gezeichnet werden muß. Soweit, so gut. Leider wird der Rendercall wie schon erwähnt irgendwann gemacht und damit kann man repaint() solange aufrufen, bis man schwarz wird.

Dies Problem haben viele Javaentwickler. Auf den diversen Hilfeseiten findet man die wildesten und vor allem komplett falschen Lösungen für das Problem, in dem Mantraähnlich repaint() oder validate() empfohlen wird.

Alles falsch Leute, die Lösung sieht so aus:

	
        public void updateInfo(String text) {
			this.text.setText(text);
			this.paintComponents( this.getGraphics() );
	}

this bezieht sich dabei auf den eigentlichen Frame z.B. das Panel in dem die Komponente untergebracht ist. paintComponents(g) zeichnet alles neu und damit auch den aktualisierten Text der Area. Der Grund wieso Swing mit Delays arbeitet zeigt sich deutlich, wenn man mehrfach pro Sekunde paintComponents(g) aufruft. Nicht nur daß man die Updates im Viewport sehen kann, es dauert auch so lange, daß man tatsächlich Performanceeinbrüche haben kann. Damit wäre geklärt, wieso es normalerweise delayed ist.

Fazit: Swing ist eindeutig zu langsam konstruiert.