# Korrektes manipulieren der GUI aus anderen Threads heraus



## roxX0r (28. Nov 2009)

Hallo!

Ich hab zur Zeit einen richtig üblen Käfer im Programm, der wirklich sehr unregelmäßig auftritt und auch nicht immer und auch nicht bei jedem. Bei dem Bug crasht die JVM mit einem schönen Errorlog. Soweit so gut. Ich bin mir relativ sicher, dass dieser Crash von Swing herrührt, da die dll Datei, die den Crash verursacht die: "comctl32.dll" ist und diese wohl für Dialoge usw. verantwortlich ist (in Windows).

Meine generelle Frage ist jetzt: wie programmiere ich am saubersten mit Swing, wenn ich aus anderen Threads heraus, die Oberfläche aktualisieren möchte? D.h. in "Labels" neuen Text setzen, in Tabellen neue Rows hinzufügen usw. Nach meinem wissenstand sollte ein "EventQueue.invokeLater" mit den entsprechenden Befehlen ausreichen. Diesen Aufruf habe ich dann in meinem Thread drin.

Dann noch eine andere Möglichekit, wie ich was aufrufe. 
In meinem GUI Thread habe ich eine statische Funktion, die die GUI aktualisieren soll. Diese Funktion bekommt einen Wert und sagen wir ein Label bekommt diesen Wert dann als Text. Und in dieser statischen Funtkion, hab ich das EventQueue.invokeLater Konstrukt drin. D.h. mein Thread ruft diese statische Funktion hin und wieder auf, um die GUI zu aktualisieren, könnte es nun ein Problem sein, dass das EventQueue in meinem GUI Thread drin ist? Eigentlich doch nicht, EventQueue und invokeLater sind eh alles statische Funkionen..

Ich weiß nicht, vielleicht hab ich auch nen Denkfehler mit der ganzen Swing Sache. Evtl. liegts da auch garnicht dran, vielleicht dürfte die JVM garnicht crashen, auch wenn ich mit Swing schindluder treiben würde? Dann sollte es womöglich Java Exceptions geben, aber gleich die JVM abschmieren? 

Wenn mir dieses CrashLog mehr infos geben würde.... mehr Infos als Hexadezimale Speicheradressen ...

Aufjedenfall hat der Crash was mit dem AWT Thread zutun und in dieser blöden DLL Datei, die im folgenden Ordner liegt:

C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.5512_x-ww_35d4ce83\comctl32.dll

Stack: [0x03350000,0x033a0000],  sp=0x0339e7c4,  free space=313k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C  0x000c013a
C  [comctl32.dll+0x1207c]

Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j  sun.awt.windows.WToolkit.eventLoop()V+0
j  sun.awt.windows.WToolkit.run()V+69
j  java.lang.Thread.run()V+11
v  ~StubRoutines::call_stub

=>0x031b1c00 JavaThread "AWT-Windows" daemon [_thread_in_native, id=544, stack(0x03350000,0x033a0000)]



Ich bin für alle Gedanken dankbar


----------



## L-ectron-X (28. Nov 2009)

Welches Windows benutzt du?
Bringe zunächst mal deinen Grafikkartentreiber auf den aktuellen Stand.


----------



## roxX0r (28. Nov 2009)

Wie gesagt, es passiert nicht bei mir. Mein Programm nutzen ziemlich viele Leute (~300) und ich höre recht häufig von dem Problem. der eine hat XP, der andere Vista. Kann mir nicht vorstellen, dass es am System liegt. ES gibt auch das Problem, dass bei einigen das Programm abstürzt, wenn sie es hin und her schieben ... Irgendwie hat die GUI nen knacks und ich weiß nicht wodran das liegt. Das Teil crasht immer mit ner "EXCEPTION_ACCESS_VIOLATION". Irgendwie muss es den Speicher zerschießen. Dem Stacktrace nach zuurteilen muss es ja im AWT Thread passieren ...


----------



## roxX0r (15. Dez 2009)

Vielleicht wenigstens jemand ne Idee, wie ich vielleicht mehr Infos zu dem Bug bekommen könnte?

eventLoop(); im Wtoolkit ist eine native Funktion in irgendeiner DLL, da kann ma also auch nicht mal reinschauen...

irgendein logger in dem Toolkit oder sowas, irgendwie bräuchet ich mehr Infos, wann genau das passiert. Es passiert wohl recht häufig beim Minimieren des Programmes oder Verschieben, aber auch nicht immer... so ein mist!


----------



## André Uhres (15. Dez 2009)

Sag den Leuten, sie sollen erstmal das aktuelle Java installieren: Download Free Java Software - Sun Microsystems


----------



## Wildcard (15. Dez 2009)

Zunächst mal, ein VM Crash ist niemals ein Programmierfehler, sondern ein Bug in der VM oder einer nativen Bibliothek (entweder selbst geladen, durch die VM, oder das OS).
That said kann ein Programmierfehler dafür verantwortlich sein das dieser Bug getriggert wird. 
Zum richtigen Threading in Swing:
invokeLater ist das richtige Stichwort. Man muss hier allerdings vorsichtig sein, denn manchmal ändert man die GUI aus dem falschen Thread ohne sich dessen bewusst zu sein und auch diese Zugriffe müssen synchronisiert werden. Beispiel:
Du hast ein Modell. Ein Controller (oder View) platziert einen Listener auf dem Modell um die GUI zu aktualisieren wenn sich das Modell ändert. 
-Ein Background Thread ändert das Modell
-Die Listener werden informiert
-Der Controller empfängt das Event
-Der Controller aktualisiert die GUI
-BOOM du warst im falschen Thread

SWT geht da geschickter vor und wirft in diesem Fall direkt eine Exception, Swing schluckt es und verschluckt sich dann später an anderer Stelle, crashed die VM oder malt deine Taskleiste plötzlich karriert, das ist undefiniert.
Bau an den kritischen Stellen erstmal eine Threadprüfung und wirf gegebenfalls direkt eine Exception um dem Problem auf die Schliche zu kommen.
SwingUtilities#isEventDispatchThread hilft dir dabei.


----------



## Ebenius (16. Dez 2009)

Wildcard hat gesagt.:


> [...] Swing schluckt es und verschluckt sich dann später an anderer Stelle, crashed die VM oder malt deine Taskleiste plötzlich karriert, das ist undefiniert.


Etwas übertrieben.  Die VM darf nicht crashen. Und die Taskleiste darf auch nicht kariert gemalt werden. Deine Anwendung gerät aber tatsächlich in einen undefinierten Zustand.



Wildcard hat gesagt.:


> Bau an den kritischen Stellen erstmal eine Threadprüfung und wirf gegebenfalls direkt eine Exception um dem Problem auf die Schliche zu kommen.
> SwingUtilities#isEventDispatchThread hilft dir dabei.


Die Prüfung machst Du am besten so: 
	
	
	
	





```
assert SwingUtilities.isEventDispatchThread();
```
Dann startest Du die Applikation zum Test mit Assertions (VM-Schalter [c]-ea[/c]). So kann die Prüfung immer im Code bleiben. Wenn die Assertions eingeschaltet sind (in Testumgebungen), fliegt ein AssertionError wenn die Methode von einem anderen Thread als dem EDT aufgerufen wird. Wenn die Assertions ausgeschaltet sind (also auf Produktivsystemen), wird die Prüfung nicht gemacht.



Wildcard hat gesagt.:


> -Ein Background Thread ändert das Modell
> -Die Listener werden informiert


Der Fehler liegt in diesem Beispiel übrigens in einem dieser beiden Punkte. Entweder ist das Modell nicht Thread-save; dann darf kein Background-Thread das Modell verändern. Oder das Modell ist Thread-save, dann muss es die Listener über den EDT benachrichtigen.

Ebenius


----------



## Marco13 (16. Dez 2009)

Es gibt theoretisch auch Möglichkeiten, die Einhaltung der Regel automatisch zu überprüfen - sowas wie Java theory and practice: Testing with leverage, Part 3 oder The Java Code Monkey: Using AspectJ to detect violations of the Swing single thread rule. ... hab' das aber noch nicht selbst getestet.




Ebenius hat gesagt.:


> Der Fehler liegt in diesem Beispiel übrigens in einem dieser beiden Punkte. Entweder ist das Modell nicht Thread-save; dann darf kein Background-Thread das Modell verändern. Oder das Modell ist Thread-save, dann muss es die Listener über den EDT benachrichtigen.



Hmm... Ich denke, dass ein Modell seine Listener NICHT über den EDT benachrichtigen sollte. Ein Modell sollte ja (theoretisch, in gewissen Grenzen) nicht mal wissen, dass es ein GUI gibt. Vielleicht hängt noch eine andere Modellklasse als Listener daran, und DIE sollte sicher nicht über den EDT benachrichtigt werden. Ich würde den Listener direkt benachrichtigen. Bei Swing Models ist es so, dass nichtmal in der Doku eine Aussage darüber gemacht wird, auf welchem Thread die Listener benachrichtigt werden - tatsächlich ist es aber afaik immer(!) der Thread, der auch die Änderung vorgenommen hat. FALLS einer der Listener einer ist, der gerne an einer Swing-Component was ändern will, dann sollte _der_ sich darum kümmern, die Änderung auf dem EDT zu machen, oder man sollte einfordern, dass das Modell auch nur über den EDT verändert werden darf. (Das ist bei Swing etwas versteckt - aber da potentiell JEDE Änderung am Modell auch "...might affect or depend on the state of that component"... dürfen eben auch die Modelle nur über den EDT geändert werden)


----------



## Ebenius (16. Dez 2009)

Marco13 hat gesagt.:


> (Das ist bei Swing etwas versteckt - aber da potentiell JEDE Änderung am Modell auch "...might affect or depend on the state of that component"... dürfen eben auch die Modelle nur über den EDT geändert werden)


Ein Swing-Modell muss (in der Regel -- Ausnahme zum Beispiel Document) seine Zuhörer auf dem EDT benachrichtigen, da sich alle Komponenten (ausgenommen JTextComponent) darauf verlassen. Im Regelfall überlässt die Modellimplementation diese Aufgabe dem Aufrufenden. Alle DefaultXYZModel-Implementierungen tun dies. Spezielle Implementierungen können das aber auch anders regeln. Wichtig ist dabei, dass das Modell sowohl seine eigene Zuständsänderung synchron zum EDT ausführt als auch die Zuhörer auf dem EDT benachrichtigt.

Ein nicht unübliches Beispiel eines Modelles das selbst multi-threaded arbeitet und seinen eigenen Zustand synchron zum EDT ändert, wäre ein Modell eines Verzeichnisbaums, der erst auf Anfrage die Kinder eines Knotens vom Dateisystem liest. Das Modell würde die Anzahl der Kinder eines Verzeichnisknotens (also die Anzahl der Sub-Dirs) mit [c]0[/c] zurückliefern und gleichzeitig einen anderen Thread anstoßen der das Dateisystem ausliest. Wenn die Ergebnisse der Abfrage vorliegen werden sie synchron zum EDT in einen Cache eingetragen und die Zuhörer über hinzugefügte Knoten benachrichtigt. Ein ähnliches Beispiel ist die (normale) ListModel-Implementierung des JFileChooser; [c]javax.swing.plaf.basic.BasicDirectoryModel[/c].

Ob ein Modell selbständig multi-threaded arbeitet und synchronisiert, oder ob es von außen herbeigeführte Statusänderungen selber zum EDT synchronisiert, oder ob es das Problem allen anderen überlässt hängt maßgeblich vom jeweiligen Zweck der Modellimplementierung ab.

Ebenius


----------



## Marco13 (16. Dez 2009)

Ich stimme dir da so weit zu, dass ich befürchte, dass meine Aussage vielleicht falsch interpretiert wurde 

Ich wollte andeuten, dass man nicht _pauschal_ sowas machen sollte wie

```
class SimpleListModel implements ListModel
{
    private List data;
    private List listeners = ...

    public void addElement(Object element)
    {
        data.add(element);

        SwingUtilities.invokeLater(new Runnable() // DAS HIER NICHT!
        {
            public void run() 
            {
                for (ListDataListener listener : listeners) listener.contentsChanged(...);
            }
        });
    }

}
```
sondern stattdessen

```
/** ... only call this on EDT... */
    public void addElement(Object element)
    {
        data.add(element);
        for (ListDataListener listener : listeners) listener.contentsChanged(...);
    }
```

Außer wenn man schreiben will

```
/** ... this is thread-safe.... */
    public void addElement(Object element)
    {
        // So wie im ersten Beispiel, ggf. noch mit einer "...isEventDispatchThread()" Abfrage...
    }
```


----------



## Ebenius (16. Dez 2009)

Marco13 hat gesagt.:


> Ich stimme dir da so weit zu, dass ich befürchte, dass meine Aussage vielleicht falsch interpretiert wurde


Oder ich zuvor. 



Marco13 hat gesagt.:


> Ich wollte andeuten, dass man nicht _pauschal_ sowas machen sollte wie [...]


Stimme zu. Wenn, dann muss Zeile 8 auch noch 6 Zeilen runter! Ansonsten ist das Modell zu seinen Nachrichten inkonsistent. Außerdem sollte man in diesem Fall nicht [c]invokeLater()[/c] benutzen, sonden Fallunterscheidung: Wenn auf dem EDT, dann direkt ausführen + Nachrichten schicken, anderenfalls mit die Methode selbst nochmals mit [c]invokeAndWait()[/c] aufrufen.

Ebenius


----------



## roxX0r (16. Dez 2009)

danke für die vielen Anwtorten, ich werde mein Modell jetzt mal überprüfung, ob es dort kritische Stellen gibt. Ich habe meistens nur irgendwelche JTable Models, die im EDT definiert sind und auf die ich dann über andere Threads zugreife, um dort neue Zeilen hinzuzufügen. Oder ich setze ein neues Textelement im EDT über einen anderen Thread.

Werde sicherlich hier nochmal was posten, wenn ich das verstanden hab, was ihr hier alle schreibt und ich meinen Code dann überprüft hab 


Nur noch eine Frage schonmal vorweg: Nehmen wir mal an mein Code hat solche Schwachstellen, kann das der Grund sein, wieso sich die JVM (sehr sehr unregelmäßig) verabschiedet und im Errorlog dann die comctl32.dll als Bösewicht genannt wird? Diese DLL zeichnet wohl Oberflächen Elemente, könnte also schon was mit Swing zu tun haben?


----------



## Wildcard (16. Dez 2009)

Ebenius hat gesagt.:


> Der Fehler liegt in diesem Beispiel übrigens in einem dieser beiden Punkte. Entweder ist das Modell nicht Thread-save; dann darf kein Background-Thread das Modell verändern. Oder das Modell ist Thread-save, dann muss es die Listener über den EDT benachrichtigen.
> 
> Ebenius


Da muss ich energisch widersprechen 
Dein Datenmodell ist der Kern, die Heilige Kuh deiner Anwendung. Du willst keinesfalls das dein Modell so etwas wie den EDT überhaupt kennt. Was ist wenn dein Modell headless verwendet wird? Was ist wenn dein Modell plötzlich eine SWT oder Web-Anwendung speisen soll?
Ein Modell kennt keine View, der Adapter/Controler der Modell mit View verknüpft muss sich um UI spezifisches threading kümmern, nicht das Modell.
Du beziehst dich später auf Swing Modelle (TableModel, ListModel,...). Diese Modelle sind in meinen Augen ein konzeptioneller Fehler in Swing, aber da muss man mit leben...
Diese Modelle sollten jedoch nicht das Business-Modell deiner Anwendung bilden da sie Toolkit spezifisch sind. Das Business Modell wird entweder in ein Swing Modell überführt, oder darauf adaptiert. In letzterem Fall ist dann diese Adapter Schicht dafür zuständig die Change Events Swing spezifisch aufzuarbeiten und das threading zu regeln, *nicht das Business Modell*


----------



## Marco13 (16. Dez 2009)

Ja, darauf wollte ich eigentlich auch raus - aber ob die Swing Modelle nun ein konzeptieller Fehler sind? Man kann ja (wie schon angedeutet) einfach postulieren, dass sowas wie ein TableModel (wenn es in einer JTable verwendet wird - was ja nicht notwendigerweise aber üblicherweise der Fall ist) eben nur über den EDT verändert werden darf, genauso wie man bei seinen "Business-Modellen" beliebige Threadanforderungen stellen darf... Also, man verwendet die Swing-Modelle ja nicht direkt als Business-Modelle, von daher wäre da eine Implementierung, die Events auf dem EDT feuert, ja OK...


----------



## Wildcard (16. Dez 2009)

Marco13 hat gesagt.:


> Ja, darauf wollte ich eigentlich auch raus - aber ob die Swing Modelle nun ein konzeptieller Fehler sind?


Swing legt es nahe Daten in designierte Swing Modelle zu packen weil die Interfaces zu komplex sind um sie immer selbst passend zu implementieren. Sobald man allerdings Daten in Swing Modelle packt muss man zwischen Domain Modell und Swing Modell synchronisieren und belegt mehr Speicher.
Nach einer Umgewöhnungsphase empfinde ich den JFace Ansatz als den sinnigeren, MVA statt MVC. 
Viewer arbeiten generisch auf einem Modell vom Typ Object und treffen keine weiteren Annahmen über den Inhalt. Der Inhalt wird nach dem Pull Prinzip aus dem Object extrahiert mit einem jeweils passenden Adapter für das Modell (ContentProvider). Das Rendering geschieht analog in einem LabelProvider.
Der Vorteil ist, die Interfaces sind sehr schmal, man benötigt keine Zwischenmodelle, es wird nur wenig Speicher benötigt, die Einzelteile sind wiederverwendbar, der Code ist sauber entkoppelt und flexibel


----------



## Ebenius (17. Dez 2009)

Wildcard hat gesagt.:


> Da muss ich energisch widersprechen


Re. 



Wildcard hat gesagt.:


> Du beziehst dich später auf Swing Modelle (TableModel, ListModel,...).


Nur um das klarzustellen: Ich bezog mich die ganze Zeit auf Swing und natürlich Modelle im Zusammenhang mit Swing. Vielleicht hab ich irgendwas im Thema oben verpasst, aber dem Themeneröffner geht es doch explizit um Swing. Vielleicht hätte ich hier deutlicher auf Swing-Komponentenmodelle hinweisen sollen.

Allgemeiner gesehen beziehe ich mich auf Modelle im MVC-Kontext. Die Bezeichnung "Business Modell" finde ich unschön. Soweit ich weiß bezeichnet man im MVC das Modell bewusst als Datenmodell. Darüber hinaus ist die Bezeichnung "das Modell" (gern auch "das Datenmodell") ohne weitere Einschränkung ohnehin schwer zu deuten. Betrachtet man eine gesamte GUI-Anwendung, bezeichnet "das Datenmodell" jedwede Datenhaltung und gewisse Geschäftslogik.

Ein Komponentenmodell wie in Swing -- ob es nun als Instanz Daten selbst hält oder transient auf andere Modellbausteine eine spezielle Sicht bildet spielt keine Rolle -- gehört zum Datenmodell. Es hat den Zweck einer bestimmten Art Präsentation in einem bestimmten Kontext Daten mundgerecht zur Verfügung zu stellen. Ein solches Modell kann sich darauf verlassen, nicht Headless zu laufen, da es ohne GUI jedweder Existenzgrundlage beraubt ist. Ein Komponentenmodell muss alle von der Komponente gestellten Anforderungen erfüllen.

Wenn Threading hierbei ein Thema ist, dann muss sich das Komponentenmodell eben darum kümmern. Selbst wenn eine extra Adapterklasse (MVC, nicht MVA!) zwischen einem Modellbaustein und einem Komponentenmodell hängt, zwischen beiden Daten transferiert und sich um das UI-spezifische Threading kümmert, gerhört dieser Adapter im MVC zum Datenmodell und nicht etwa zum Controller.



Wildcard hat gesagt.:


> Ein Modell kennt keine View, der Adapter/Controler der Modell mit View verknüpft muss sich um UI spezifisches threading kümmern, nicht das Modell.


Hier hast Du glaub ich was vermischt. In MVA kennt eine View das Modell nicht. Es greift per Adapter auf Daten des Datenmodells zu. Der Adapter hätte die Möglichkeit Daten aus dem Modell aufzubereiten. In MVC schaut die View direkt aufs Modell; der Controller *kann* sich überhaupt nicht um UI-spezifisches Threading für die Datenschnittstelle der View kümmern! Der Controller hat den einzigen Zweck, Eingaben aus der View entgegen zu nehmen und (ohne weiter aufs Detail einzugehen) zu verarbeiten. Ein Controller ist *nicht* dafür zuständig Daten zu manipulieren, übersetzen, etc.

Ich lasse mich gern eines Besseren belehren, dann aber bitte mit Quellenangabe. 



Wildcard hat gesagt.:


> Swing legt es nahe Daten in designierte Swing Modelle zu packen weil die Interfaces zu komplex sind um sie immer selbst passend zu implementieren. Sobald man allerdings Daten in Swing Modelle packt muss man zwischen Domain Modell und Swing Modell synchronisieren und belegt mehr Speicher.


Das sehe ich nicht so. Ich baue häufiger eigene Swing-Modelle und die Modelle finde ich in der Regel nicht zu kompliziert. Ich mag die Swing-Modelle, aber diese Diskussion ist ein Glaubenskrieg, also verzichte ich hier mal drauf.  :-D

Ebenius


----------



## André Uhres (17. Dez 2009)

Nur so nebenbei: beim *modifizierten MVC* steht der Kontroller zwischen View und Model, wodurch eine bessere Trennung zwischen View und Model erreicht wird. Der Kontroller übersetzt Benutzeraktionen in Aktionen, die das Model auszuführen hat. Zudem informiert der Kontroller die View über Änderungen im Model.


----------



## Wildcard (17. Dez 2009)

Ebenius hat gesagt.:


> Ein Komponentenmodell wie in Swing -- ob es nun als Instanz Daten selbst hält oder transient auf andere Modellbausteine eine spezielle Sicht bildet spielt keine Rolle -- gehört zum Datenmodell. Es hat den Zweck einer bestimmten Art Präsentation in einem bestimmten Kontext Daten mundgerecht zur Verfügung zu stellen. Ein solches Modell kann sich darauf verlassen, nicht Headless zu laufen, da es ohne GUI jedweder Existenzgrundlage beraubt ist. Ein Komponentenmodell muss alle von der Komponente gestellten Anforderungen erfüllen.
> Wenn Threading hierbei ein Thema ist, dann muss sich das Komponentenmodell eben darum kümmern. Selbst wenn eine extra Adapterklasse (MVC, nicht MVA!) zwischen einem Modellbaustein und einem Komponentenmodell hängt, zwischen beiden Daten transferiert und sich um das UI-spezifische Threading kümmert, gerhört dieser Adapter im MVC zum Datenmodell und nicht etwa zum Controller.


Ich Quote mal Wikipedia zum Thema MVC:


> Model–View–Controller (MVC) is an architectural pattern used in software engineering. The pattern *isolates "domain logic"* (the application logic for the user), *from input and presentation* (GUI), permitting independent development, testing and maintenance of each.



Wenn das Modell dafür zuständig ist notifications in einen GUI Thread zu verschieben, dann ist Modell automatisch an ein spezifisches UI Toolkit gebunden und genau das versucht man mit MVC doch zu verhindern.



> Hier hast Du glaub ich was vermischt. In MVA kennt eine View das Modell nicht. Es greift per Adapter auf Daten des Datenmodells zu. Der Adapter hätte die Möglichkeit Daten aus dem Modell aufzubereiten. In MVC schaut die View direkt aufs Modell; der Controller kann sich überhaupt nicht um UI-spezifisches Threading für die Datenschnittstelle der View kümmern!


In der Variante das die View direkt als Observer auf dem Modell liegt muss sich die View darum kümmern das die Benachrichtigung aus einem anderen Thread kommen kann, denn das Modell darf keine Annahme über die Art wie es angezeigt wird treffen.
In Swing ist übrigens die View kein Listener auf dem Modell, denn die View sind nur die Renderer.

Vielleicht haben wir einfach andere Begriffsdefinitionen vor Augen. Für mich ist das Modell der Business/Domain Zustand der Anwendung. Sei es selbst geschrieben, mit EMF, JaxB, oder UML Tools generiert, in jedem Fall aber völlig UI unabhängig. Ob Swing oder ein anderes Toolkit dann noch eine art derived model benötigt um diese Daten dazustellen steht auf einem anderen Blatt, aber in einer Anwendung würde ein Backgroundthread meiner Meinung nach nicht das intermediate Swing Model verändern, sondern die Business Daten, das 'headless' Model. Dein Glue Code/UI Binding muss diese Daten dann toolkitspezifisch aufbereiten.


> Das sehe ich nicht so. Ich baue häufiger eigene Swing-Modelle und die Modelle finde ich in der Regel nicht zu kompliziert. Ich mag die Swing-Modelle, aber diese Diskussion ist ein Glaubenskrieg, also verzichte ich hier mal drauf.


Richtig, lassen wir das lieber


----------



## André Uhres (18. Dez 2009)

roxX0r hat gesagt.:


> Nehmen wir mal an mein Code hat solche Schwachstellen, kann das der Grund sein, wieso sich die JVM (sehr sehr unregelmäßig) verabschiedet


Theoretisch könnte es ja auch ein OS oder JVM Problem sein. Daher mein obiger Vorschlag, erstmal die aktuelle JVM von Sun zu installieren. Vielleicht könnte man zuerst auch noch festhalten, bei welchen OS/JVM Versionen das Problem auftritt und bei welchen nicht.


----------



## user124 (18. Dez 2009)

vielleicht ein wenig ot aber ein einfaches awt-beispielprogramm hat es reproduzierbar geschafft meinen x-server zu zerschießen - beim vergrößern/verkleinern des fensters mit der maus -> grafikchaos auf dem desktop bis zum kompletten lock.

abhilfe schaffte den nvidia-treiber zu updaten. evtl wäre es interressant zu wissen welche grafikkarten die user benutzen bei denen das problem auftritt.


----------

