Thread(s) in SWT Applikation - planlos....

Ronin-Jay

Erfahrenes Mitglied
Hallo zusammen,

ich arbeite gerade an einer SWT-Applikation. Ich habe eine GUI und die öffnet einen Dialog, der zwischen 2 Benutzergruppen differenzieren muß [m. / o. Transponder]. Leute die einen Transponder haben, sollen diesen an ein Lesegerät halten und es öffnet sich die entsprechende GUI (Dialog schließt sich). Ohne Transponder haben die User die Möglichkeit im Dialog auf einen Button zu klicken. Auch dann soll sich der Dialog schließen und eine (andere) GUI-Oberfläche erscheinen..... soweit so gut. Nur wie realisiere ich das am besten mit Threads. Stehe diesbzgl. etwas auf dem Schlauch....

Jemand mit Transponder hat einen eindeutigen Transponderkey, ohne Transponder kann ich nur auf den Button reagieren und im Hintergrund darf nicht mehr nach dem Transponder gehorcht werden, um evtl. Einflüsse in der Interaktion mit dem User zu vermeiden. Erst wenn der User fertig ist, soll wieder der LoginDialog gezeigt werden, der auf Transponder oder Button reagiert.....

Wäre für Hinweise auf einen Weg dankbar.
 
Okay wenn du den Dialog öffnest machst du auch einen Thread an in welchem du auf Transponder-Nachrichten horchst.

Sobald du eine korrekte Nachricht bekommst rufst du aus diesem Thread eine entsprechende Methode auf die die richtige GUI öffnet. An dieser Stelle musst du aufpassen da du nur aus dem SWT-Hauptthread SWT-GUI Elemente ansprechen darfst. Dies ist aber auch sehr einfach umzusetzen in dem du den Code dann in display.asyncExec/syncExec (Runnable). Den Thread der auf den Transponder horcht kannst du dann prinizpiell beenden denn er wird neu aufgerufen wenn der Dialog wieder aufgeht.
 
Hallo Zeja, vielen Dank schon mal für Deine Unterstützung.
Ja ok, soweit die Theorie.... Hatte es auch schon mal versucht aus dem Hauptthread nen Thread zu starten, der auf den Transponder horcht, doch leider schieße ich mir damit immer ins eigene Knie, weil er dadurch nicht mehr die GUI richtig vollständig aufbaut. Wo muß ich das display.asyncExec anwenden?
 
Hast du denn auch Thread.start und nicht run benutzt? Klingt mir danach dass es nicht korrekt als Thread gestartet wurde, denn sonst sollte es damit keine Probleme geben.

Hier ist ein Beispiel wie man mit SWT eine Tabelle aus einem Thread heraus aktualsiert.

Ansonsten muss du mal ein wenig Code posten der zeigt was nicht geht und wo du nicht weiterkommst.
 
Hallo,

ich hab leider noch nicht so viel mit SWT gemacht. Was ich aber weiß ist, dass wenn Theads irgendwas mit der GUI zu tun haben sollte man
Code:
display.asyncExec(Runnable r);
benutzen. Es kann sogar sein, dass du jeden Thread bei SWT so starten solltest. Du übergibst dort einfach deinen Thread und dann müsste es funktionieren.

MFG

zEriX
 
Hallo,

ich hab leider noch nicht so viel mit SWT gemacht. Was ich aber weiß ist, dass wenn Theads irgendwas mit der GUI zu tun haben sollte man
Code:
display.asyncExec(Runnable r);
benutzen. Es kann sogar sein, dass du jeden Thread bei SWT so starten solltest. Du übergibst dort einfach deinen Thread und dann müsste es funktionieren.

Neeein, Neeeein, Neeeeein ;)

Das ist komplett falsch. Dann würdest du alles zum Stillstand bringen, denn alles was du mit ayncExex oder syncExec ausführst wird in den SWT-Thread eingehängt:

Wenn das der SWT-Thread ist so, tut er grob immer nur folgendes:
GUIaktualisieren GUIaktualisieren GUIaktualsieren


Durch ein syncExec oder asyncExec werden die übergebenen Teile direkt in diesen Thread eingehängt:

GUIaktualisieren GUIaktualisieren [syncExec(meineAufgabe] GUIaktualsieren

Was passiert wenn man dort länger dauernde Aufgabe übergibt kann man sich nun hoffentlich in etwa vorstellen: Die GUI ist nicht mehr ansprechbar!

Daher nur minimalen Code in ein syncExec oder asyncExec packen. Berechnungen vorher durchführen und nur die Ergebnisse benutzen um ausschliesslich GUI aktualisierungen vorzunehmen bei denen die Berechnungen aus einem anderen Thread kommen.
 
Wie gesagt, hab noch nicht so viel mit SWT gemacht. Arbeite mehr mit Swing.
Also wieder mal was gelernt. :)

MFG

zEriX
 
So, im Anhang mal die entsprechenden Source-Dateien. Es fehlt SWT und Common Configurations..

Wäre schön,. wenn ich einen Tipp für die Unterbringung der Threads bekommen könnte, da ich noch nicht in der Hinsicht und auch noch nicht sehr oft mit JAVA gearbeitet habe.

Ich muß doch sicherlich die GUI in einen eigenen Thread packen oder?
 

Anhänge

  • ECM.zip
    83,4 KB · Aufrufe: 37
Hi,

habe deinen Code jetzt so grob nicht zum kompilieren bekommen, kann es aber ja so oder so nicht testen. Also nur mal so reingeschaut:

In createContentsExternal: Statt alles direkt auf die Shell zu legen, leg es lieber auf ein extra Composite.
Das hat den vorteil dass du dann nur dieses Composite disposen musst und nicht alle Komponenten einzeln

Genau genommen würde ich davon sogar eine eigene Klasse machen, die dir ein solches Composite mit den Element darauf erstellt. Dann auch an GUI-Elementen ist es nicht schön alles in eine Klasse zu schreiben.

Du hast schon ein Haufen Speicherlecks bei dir eingebaut.
Fonts, Colors, Images sind alles Sachen die in SWT wieder disposed werden müssen wenn sie nicht mehr benötigt werden.

In Zeile 104 und 321 der Klasse TSGUI kommt Code doppelt vor. Mach doch eine eigene Methode openDialog davon.

Da du das ganze mit javax.comm über Listener machst, brauchst du gar keinen Thread. Du musst nur in deiner Klasse Transpondern noch Methoden wie addTransponderListener(TransponderListener) und removeTransondernListener(TransonderListener) hinzufügen. Aus LoginDialog rufst du dann transponder.addTransponderListener(this) auf.

Das interface TransponderLister extends EventListener muss dann eine Methode wie gotKey(TransponderEvent) anbieten. Diese implementiert du in der LoginDialog Klasse und in der Klasse Transponder rufst du diese Methode der registrierten Listener auf sobald du den richtigen Key ausgelesen hast.

Im LoginDialog setzt du dann das Ergebnis und disposed die Sehll des Dialogs. Dadurch wird der Dialog beendet und das Ergebnis zurückgegeben.
 
Zurück