# SWT - TextFeld automatisch aktualisieren



## gigalogisch (10. Nov 2008)

Hallo!

Ich bin richtig froh, mal auf ein Forum gestoßen zu sein, das sich auch mit SWT beschäftigt! 

Eine GUI soll Werte aus einer Datenbank anzeigen - wäre eigentlich kein Problem, allerdings aktualisieren sich die Werte in der DB im Schnitt jede Sekunde.
Mit der genauen Funktionsweise will ich euch auch gar nicht belasten. Im Moment bin ich nämlich noch am Testen zwischen der Performance von Swing und der von SWT.
Im Moment geht es mir nur darum, welches von beiden (Swing, SWT) 300 Textfelder schneller aktualisieren kann. (Und das halt nicht nur einmal, sondern z. B. 1000 mal um die Zeit zu messen)
Das heißt ich habe eine Schleife in der von 0 - 1000 gezählt wird und darin noch einmal eine Schleife, die mir jedes Textfeld mit einer Zufallszahl aktualisiert.

Welche GUI das dann schneller bewerkstelligen kann, hat "gewonnen" ;-)
In Swing habe ich diese GUI schon fertig und läuft auch einwandfrei, nur in SWT bereitet sie mir arg Probleme.

Ich bringe es einfach nicht zum laufen, dass ein TextFeld ständig aktualisert wird.

Vielleicht hat jemand von euch eine Idee?
Mir wäre schon sehr geholfen, wenn mir jemand eine Schleife liefern könnte, die von 1 bis 1000000 zählt und wo ich die Zahl des jeweiligen Schleifendurchlaufs in einem TextFeld hoch sausen sehen kann.
Denn es muss doch gehen, nur bekomme ich es in SWT einfach nicht hin. Habe schon einige Tage damit gespielt, bekomme aber alle möglichen Ergebnisse, nur nicht das was ich will. Z. B. Zählt er bei mir im Hintergrund hoch und zeigt die Zahl 1000000 erst dann an - ich will aber jede Zahl einzeln sehen.

Vielen, vielen Dank!!!

Willi


----------



## Wildcard (10. Nov 2008)

Wo ist das Problem? Ein Thread der Display.getDefault().asyncExec aufruft und dort dann text.setText(deinCounter)


----------



## gigalogisch (10. Nov 2008)

Hallo nochmal,

hab mir da jetzt mal ein bisschen was zusammengesucht.


```
Thread someThread = new Thread() {
		    public void run() {
		    	Display.getDefault().asyncExec(???) {
							// Daten für den gegebenen Namen aus ArrayList holen
		    				Text TextFeldObj = this.nativeGet(3); //hier findet er meine Methode nativeGet nicht mehr (The method is undefined for the Type newThread)
		    				// Schreibt Zufallszahl in Textfeld
		    				TextFeldObj.setText(Model.getValue());
		                }
		    	}
			};
		}
```

Die Frage ist, was ich hinter asyncExec in die Klammern schreiben muss, und warum er mein nativeGet nicht mehr findet.
Muss ich diesen Block innerhalb einer Methode schreiben oder außerhalb?

Vielen Dank und sorry, mit Threads kenn ich mich leider überhaupt nicht aus.

Willi


----------



## Wildcard (10. Nov 2008)

da schreibst du new Runnable rein. this bezieht sich dann auf das Runnable und das hat keine solche Methode. Klassenname.this.nativeGet(3)


----------



## gigalogisch (10. Nov 2008)

Hallo Wildcard,

vielen Dank für deine schnelle Antwort!
Hab wieder ein bisschen "rumgedoktort" und bekomme den Fehler "Cannot instantiate the type Runnable" nicht weg...

Hier mein Code:

```
Thread someThread = new Thread() {
	    public void run() {
	    	Display.getDefault().asyncExec(new Runnable()); {
				// Daten für den gegebenen Namen aus ArrayList holen
	    		Label TextFeldObj = SWTView.this.nativeGet(3);
	    		// Schreibt Zufallszahl in Textfeld
	    		TextFeldObj.setText(Model.getValue());
	    	}
		}
	};
```

Diesen Code habe ich innerhalb einer Klasse, aber nicht innerhalb einer Methode eingesetzt. Das stimmt so, oder?

Vielen Dank nochmal

Willi


----------



## Wildcard (10. Nov 2008)

```
Display.getDefault().asyncExec(new Runnable() {
            // Daten für den gegebenen Namen aus ArrayList holen
             Label TextFeldObj = SWTView.this.nativeGet(3);
             // Schreibt Zufallszahl in Textfeld
             TextFeldObj.setText(Model.getValue());
          });
```
Der äussere Thread ist sinnlos.


----------



## Guest (10. Nov 2008)

Hallo Wildcard,

habe deine Version genommen - allerdings schmiss mir Eclipse da auch wieder Fehler, habe ein bisschen rumprobiert und noch "public void run() {" eingebaut - jetzt schmeißt mir zumindest Eclipse keine Fehler mehr.

Jetzt müsste ich nur noch in diese run()-Methode "reinkommen".

Ein Methodenaufruf einfach nur mit run(); funktioniert nicht (is undefined)

Hier nochmal der Codeschnippsel:

```
//Aktualisiert bereits vorhandene TextFelder beliebig oft
	public void UpdateTextFelder(String wastun) {
		System.out.println("LULU");

		Display.getDefault().asyncExec(new Runnable() {
			public void run() {
				System.out.println("HUHU");

				// x = bestimmtes TextFeld
				for (int x = 0; x < SWTView.this.getSizeOfArrayList(); x++) {
    				// Daten für den gegebenen Namen aus ArrayList holen
    				Label TextFeldObj = SWTView.this.nativeGet(x);
    				// Schreibt Zufallszahl in Textfeld
    				TextFeldObj.setText(Model.getValue());
				}
			}
		});
	}
```

So wie hier codiert schmeißt (zumindest) Eclipse keine Fehler mehr.
Wenn ich die Methode UpdateTextFelder aufrufe wird LULU ausgegeben, HUHU aber nicht - ist auch logisch, weil die Methode run() nicht aufgerufen wurde. Nur wie rufe ich die auf?

Danke!!


----------



## Wildcard (10. Nov 2008)

Richtig, hatte das run vergessen (run wird automatisch aufgerufen). Deine Schleife macht so allerdings keinen Sinn, da alles der Code des Runnables vom UI Thread aufgerufen wird. Du würdest den Thread also eine Weile blockieren und dann wird der letzte Zustand angezeigt.


----------



## gigalogisch (10. Nov 2008)

Hallo,

kannst du mir das bitte noch einmal erklären?
Hab das leider nicht verstanden :-/
Was macht wo keinen Sinn? Was kann ich dagegen machen?

Vielen Dank!

Willi


----------



## Wildcard (10. Nov 2008)

Ach moment.. hatte mich verlesen. DU iterierst ja über Textfelder, nicht über Werte.
Müsste also funktionieren.


----------



## gigalogisch (11. Nov 2008)

... aber wie rufe ich dieses Teil jetzt auf, so das auch was passiert damit?  

Danke


----------



## Wildcard (11. Nov 2008)

Es wird in Display.asyncExec ausgeführt.
Hast du denn eine funktionierende SWT Anwendung?


----------



## Guest (11. Nov 2008)

Oh - hab vergessen noch diesen Code mit einzubauen


```
display.readAndDispatch();
		 try {
		 Thread.sleep(250);
		 } catch (InterruptedException e) {
		
		 }
```

Nichts desto trotz hauts einfach nicht hin. Bzw. es haut nun schon hin - allerdings nur mit Labels (Ich wollte aber Text), und auch nur mit dem FillLayout Manager - egal welchen anderen LayoutManager ich ausprobiert habe wurde mir nichts angezeigt.
Schreibe ich alles in Text (also für TextFelder) um, so wird mir nur das Endergebnis präsentiert. D. h. er werkelt vor sich hin und erst wenn er fertig ist, bekomme ich in meinem TextFeld die letzte generierte Zufallszahl zu sehen. Ich will aber jede Zufallszahl in jedem Schleifendurchlauf sehen. Mit Labels funktionierts komischerweise. Auch ein shell.redraw() in der Schleife hilft nichts.

Und was mich auch sehr verdutzt, SWT (mit Labels) braucht mehr als doppelt solange wie Swing die Zufallszahlen anzuzeigen. Wobei man ja generell sagt, SWT sollte schneller sein.

Ich bin am verzweifeln. Es kann doch nicht so schwierig sein, einfach mal ein TextFeld anzuzeigen, dass immer aktualisiert den Text anzeigt, den der Zufallszahlgenerator generiert.

In Swing ist das überhaupt kein Problem und mit SWT ärgere ich mich schon seit Tagen und habe noch überhaupt keine Aussichten auf Erfolg.

Willi


----------



## Wildcard (11. Nov 2008)

Der Code ist so nicht richtig.

```
while (!shell.isDisposed ()) {
		if (!display.readAndDispatch ()) display.sleep ();
	}
```



> Schreibe ich alles in Text (also für TextFelder) um, so wird mir nur das Endergebnis präsentiert. D. h. er werkelt vor sich hin und erst wenn er fertig ist


Dann würde ich sagen, verwendest du die Threads falsch. Hast du denn nun einen Background Thread der die Daten besorgt und mit asyncExec an die GUI übergibt?


> In Swing ist das überhaupt kein Problem und mit SWT ärgere ich mich schon seit Tagen und habe noch überhaupt keine Aussichten auf Erfolg.


SWT ist nicht schwieriger als Swing, aber manchmal muss man sich eben etwas einlesen bevor man Code Zeilen runterklopft. Das asyncExec Konzept ist ebenfalls identisch mit Swing (invokeLater). Wenn dir das nichts sagt, ist auch deine Swing GUI nicht korrekt.


----------



## gigalogisch (13. Nov 2008)

Warum ist der Code so nicht richtig? Genau so steht er in den meisten Tutorials die es zu SWT gibt?



> Dann würde ich sagen, verwendest du die Threads falsch.



Aber vor ein paar Tagen hast du noch geschrieben:


> Der äussere Thread ist sinnlos.



Was mach ich denn verkehrt?

Danke


----------



## Wildcard (13. Nov 2008)

> Warum ist der Code so nicht richtig? Genau so steht er in den meisten Tutorials die es zu SWT gibt?


250 Millisekunden erscheint mir elend lang für einen UI Thread. Ich kenne nur die Display#sleep Variante.
Du brauchst einen anderen Thread, der muss aber nebenläufig sein und nicht einfach um das Runnable rum.
Ein Thread ist der UI Thread, der mit readAndDispatch und einer liest Daten, und schreibt sie über Display#asyncExec in die Widgets.


----------

