SWT GUI Freeze ("EDT" bei SWT?)

hdi

Top Contributor
Hey, ich hab ne SWT Composite mit einem kleinen FillLayout (Vertical). Diese Fläche soll mir als eine Art Log dienen, ich schiebe während eines Prozesses Nachrichten da rein in Form von Labels, die ich adde.

Problem: Die GUI hängt bis der Prozess vollständig ist, oder stürzt während dessen ab. Außerdem wird am Ende nur das erste und letzte Label angezeigt, weitere dazwischen nicht.
Mein Prozess der diese Logs da reinschiebt wird auch direkt aus einer handleEvent-Methode aufgerufen, nicht in nem neuen Thread, von daher ist dieses Verhalten also nicht verwunderlich.

Jetzt wollte ich das nun in einen neuen Thread packen, bekomm dann aber Abstürze sobald ich auf meine Composite zugreifen will. Hab schon mal gehört dass SWT da gleich blockiert.

Die Frage ist nun: Was ist das SWT-Gegenstück zu "EventQueue.invokeLater" ? Die Zugriffe auf die GUI Komponenten darf ich ja scheinbar nicht aus nem neuen Thread heraus machen.

Thx
 
T

Tomate_Salat

Gast
Bei SWT gibt es eine nette funktion:

Java:
Display.getCurrent().asyncExec(runnable);

das sollte dien Problem lösen.

Und wieso machst du da Labels rein? Wäre ein Table nicht einfacher?! (Handhabe ich zumindest mit meiner Console so)

Ein Beispiel:

Java:
Display.getCurrent().asyncExec(new Runnable()
{
        @Override
        public void run() 
        {
             shell.setText("Manager - Completed");                
        }
});

Anmerkung natürlich kannst du die asyncExec auch über deine Display-Referenz aufrufen, aber wenn man die nicht immer zur stelle hat, geht es so wie oben beschrieben

MFG

Tomate_Salat
 
Zuletzt bearbeitet von einem Moderator:

hdi

Top Contributor
Hey danke für die Hilfe. Geht aber irgendwie noch nicht:

Java:
    @Override
    public void handleEvent(Event e) {
	Runnable job = new Runnable() {
	    @Override
	    public void run() {
		log.clear(); // "log" vom Typ Log, eine eigene Klasse
	    }
	};
	new Thread(job).start();
    }

die clear-Methode aus Log:
Java:
    public void clear() {
	Display.getCurrent().asyncExec(new Runnable() {
	    public void run() {
		for (Control c : composite.getChildren()) {
		    c.dispose();
		}
		composite.redraw();
	    }
	});
    }

Beim Starten:
Exception in thread "Thread-5" org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:3884)
at org.eclipse.swt.SWT.error(SWT.java:3799)
at org.eclipse.swt.SWT.error(SWT.java:3770)
at org.eclipse.swt.widgets.Widget.error(Widget.java:463)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:355)
at org.eclipse.swt.widgets.Composite.getChildren(Composite.java:411)
at epf_xpdl_import.Log.clear(Log.java:26)
at epf_xpdl_import.ImportProcess$1.run(ImportProcess.java:31)
at java.lang.Thread.run(Unknown Source)
 
T

Tomate_Salat

Gast
Java:
    @Override
    public void handleEvent(Event e) {
	Runnable job = new Runnable() {
	    @Override
	    public void run() {
		log.clear(); // "log" vom Typ Log, eine eigene Klasse
	    }
	};
	new Thread(job).start();
    }

wieso das ganze in einen eigenen Thread? Versuche es vllt mal mit:

Java:
    @Override
    public void handleEvent(Event e) {
           log.clear(); // "log" vom Typ Log, eine eigene Klasse
    }

Eventuell stört Ihn der eigene Thread. Die Fehlermeldung kommt mir bekannt vor, durch diese Art von Meldungen bin ich ja auf die asyncExcec gekommen. Und ich verwende die Ja auch in dem Stil:

Java:
@Override
    public void downloadStart(DownloadEvent evt) 
    {
        display.asyncExec(new Runnable()
        {
            @Override
            public void run() 
            {
                shell.setText("Manager - Started");                
            }
        });        
    }

das wäre ohne diesen asynchronen Zugang sonst nicht Möglich. Und mit Display.getCurrent().asyncExcec müsste es auch gehen. Zuhause, meine ich das für ietwas mal so verwendet haben zu müssen :-/.

MFG

Tomate_Salat

Edit Hmm oder versuch es mal mit: [c]Display.getDefault().asyncExec(runnable);[/c]
 
Zuletzt bearbeitet von einem Moderator:

hdi

Top Contributor
wieso das ganze in einen eigenen Thread?
Naja weil die handleEvent-Methode ja eben vom SWT-EDT aufgerufen wird und meine GUI blockiert solange der Prozess läuft. Eig. will ich das auch da der User nix machen können soll, aber dann kann er ja auch nicht die Log-Anzeige updaten.

Wenn ich das log.clear() direkt starte ist es das selbe.
 
T

Tomate_Salat

Gast
Bin noch nicht sooo vertraut mit SWT aber wie oben im Edit beschrieben. Versuche es entweder mal mit getDefault anstatt getCurrent oder mal direkt mit der display-referenz.
 

hdi

Top Contributor
Ne macht auch keinen Unterschied. Also sobald ich meinen Prozess in nem neuen Thread starte krieg ich diese Fehlermeldung beim Zugriff auf die Composite mit den Labels. Wenn ich den Thread weglasse funktioniert es halt nicht weil der EDT blockiert ist. Das mit asnych() scheint irgendwie hier nicht zu funktionieren :bahnhof:

Oder liegt es vllt tatsächlich daran dass SWT nich tin der Lage ist soviele Komponenten in so kurzer Zeit zu adden? Nicht wirklich oder
 
Zuletzt bearbeitet:
T

Tomate_Salat

Gast
Das muss funktionieren. Vllt entfernst du mit c.dispose(); zuviel oder so...ka. Ich finde in für einen Log würde sich btw eh eine Tabelle besser anbieten.

Wenn du willst, kann ich dir mal mein aktuelles Projekt mit source in eine JAR packen. Da ist auch eine SWTConsole drin, welche ich als fertig ansehe. (Wird so eine Art kleines Utility-Framework was ich, wenn es fertig werden sollte iwann :D, eh als open source veröffentlichen möchte)

Ansonsten: Vllt mal mehr Quellcode oder ein kskb :)lol: soweit wie möglich halt^^) posten
 

hdi

Top Contributor
Hey, ja also ich bin halt total neu in SWT deshalb hab ich jetzt einfach so ein Label-Composite gemacht. Klar wenns mit ner Tabelle besser ist gerne xD
Ich brauch einfach nur ne Liste von Messages also Strings. Allerdings wäre es schön wenn man die Farbe pro Eintrag bestimmen kann, d.h. manche Messages in Rot, machne in Gelb usw.

Ja und man muss das halt eben auch wieder "clearen" können also alle Messages löschen.
Wär sau nice wenn du mir da n kleines Exempel posten könntest :)
 
T

Tomate_Salat

Gast
Hey, ja also ich bin halt total neu in SWT deshalb hab ich jetzt einfach so ein Label-Composite gemacht. Klar wenns mit ner Tabelle besser ist gerne xD

hehe, ich auch^^. Mir gefällt Swing einfach nicht, zuviele Ecken und Kanten da hab ich mir iwann SWT angeschaut und es hat doch viele Vorteile und das obwohl ich erst seit kurzem dabei bin

Ich brauch einfach nur ne Liste von Messages also Strings. Allerdings wäre es schön wenn man die Farbe pro Eintrag bestimmen kann, d.h. manche Messages in Rot, machne in Gelb usw.

Man merkt du kommst aus der Swing-Gegend ;-) geht mit SWT super einfach.

Hier mal ein Ausschnitt wie ich Einträge setze und du siehst wie einfach es ist
Java:
// Tabelle initalisieren
					Table table				= CONSOLE.tabelle;
		    		
                                        // evt => ConsolenEvent, ein von mir definiertes Event
					// Entry bekommen
					ConsolenEntry entry		= evt.getEntry();
					
					java.awt.Color AC		= entry.getType().getColor();
					Color background		= new Color(CONSOLE.display, AC.getRed(), AC.getGreen(), AC.getBlue()); // Hier konvertiere ich einfach awt.Color nach swt.Color
					
					// Eintrag setzen
					String data[]			= 
					{
						entry.getZeit(),
						entry.getThreadInfo(),
						entry.getType().name(),
						entry.getMessage()
					};
					
					TableItem item			= new TableItem(table, SWT.NONE);
					item.setText( data );
					item.setBackground( background );
					
					table.setTopIndex( table.getItemCount() ); // Scroltl immer nach unten

Ja und man muss das halt eben auch wieder "clearen" können also alle Messages löschen.
Wär sau nice wenn du mir da n kleines Exempel posten könntest :)

NP:
Java:
tabelle.removeAll();
 

hdi

Top Contributor
Sau nice dank dir! Mit dem Table funktioniert es jetzt auch zur Laufzeit einwandfrei! Bei Table scheint wohl ein MVC-Konzept integriert zu sein was bei Labels so wohl nicht der Fall ist..

Thema geklärt! :toll:
 
T

Tomate_Salat

Gast
Sau nice dank dir! Mit dem Table funktioniert es jetzt auch zur Laufzeit einwandfrei! Bei Table scheint wohl ein MVC-Konzept integriert zu sein was bei Labels so wohl nicht der Fall ist..

Thema geklärt! :toll:

Ja gut, du hast die Labels eigentl. schon Zweckenfremdet für dein Vorhaben xD. Also HF noch mit deim Projekt ;-) freut mich wenn ich helfen konnte :p
 

Ähnliche Java Themen

Neue Themen


Oben