Hallo,
ich stehe mal wieder auf dem Schlauch:
Also in meinem Hauptprogramm kommen folgende Zeilen vor:
1
Runnable task1 = new ps90Suchen();
2
SwingUtilities.invokeLater(task1);
Jetzt möchte ich irgendwie eine Rückmeldung, wenn task1 durchgelaufen
ist. Ich habe es schon mit variablen versucht, aber das klappt nicht.
invokeAndWait ebenfalls nicht...
Wie kann ich das Problem lösen?
Holger
Was willst du den genau tun? Dein Task ist "fertig" wenn von ps90Suchen
die run Methode durchlaufen wurde, irgendwie hört sich das aber nicht so
an als ob du das im GUI-Thread machen wollen würdest, für
Hintergrundarbeiten die bei Beendigung die GUI aktualisieren sollen gibt
es die SwingWorker Klasse und dort dann die done() Methode.
Hallo,
also ich arbeite mit einem COM-Port und rxtccmm. ps9suchen sucht die
COM-Ports nach dem Gerät durch. Das soll nebenbei laufen. ps90suchen
greift aber auch auf die gui zu. Z.B. PS90 an COM1 gefunden in einem
jtetxfield.
rxtxcomm und Swing ist ein ziemlicher Krampf aber ich habe es nun für
mich perfekt hinbekommen.
Nun möchte ich, nachdem pc90suchen durch ist, ein zweites Gerät suchen.
Und der Suchvorgang soll auch "nebenbei" laufen, aber erst, wenn ps90
abgearbeitet ist.
Holger
Naja, zum Krampf wird es halt wenn man es "irgendwie" macht ;-)
Leider schwirren auch einige mäßig gute Beispiel im Netz herum.
Ahnungsloser schrieb:> Das soll nebenbei laufen
Dann ist invokeLater der völlig falsche Weg, das führt nicht dazu das
es nebenbei läuft, sondern das du sämliche UI blockierst bis dein Task
abgearbeitet wurde!
Mach dir für dein suchen zwei SwingWorker, pc90 und ps90,
doInBackground() enthält dabei die Hintergrundarbeit, über publish
kannst du Nachrichten an die GUI geben, das Ergbnis ist dein Returnwert.
Diese Nachrichten verarbeitest du in der process() methode verarbeiten,
das Ergebnis der Hintergrundarbeit in done() mittesl der get() methode
abfragen.
Dein zweiter Worker benötigt nun eine referenz auf den ersten, und fragt
in seiner doInBackground() methode das isDone() Flag ab, und legt sich
bei negativem Ergebnis erst mal schlafen... alternativ startet der erste
Worker den zweiten solabd er fertig ist.
Das alles ließe sich allerdings an einem Konkretem Codebeispiel sehr
viel besser erläutern.
Läubi .. schrieb:> Dann ist invokeLater der völlig falsche Weg, das führt nicht dazu das> es nebenbei läuft, sondern das du sämliche UI blockierst bis dein Task> abgearbeitet wurde!
Moin,
also: GUI wird aufgebaut. Es erscheint: Gerät wird gesucht ...
Dann wird ein Gerät gesucht. Während dieser Zeit ist sowieso nichts mit
Bedienung der GUI. Während des Suchvorganges werden die
Schnittsellenbezeichnungen angezeigt. Wenn das Gerät gefunden wurde,
dann wird die Schnittstelle belegt und dies wird angezeigt. Es läuft in
vielen Programmen so. Wenn das Gerät aus welchen Gründen nicht gefunden
wird, dann wird z.B. eine Combobox zur Auswahl der Schnittstelle
freigegeben.
Aber nun habe ich zum ersten Mal zwei Geräte ...
Holger
Das mag ja alles sein das es "erstmal" so geht, aber du tust das
a) an der falschen Stelle
b) nicht wie gedacht im Hintergrund
Aber da dich das scheinbar eh nicht stört:
SwingUtilities.invokeLater(task1);
SwingUtilities.invokeLater(task2);
Führt Task2 dann aus wenn Task1 abgeschlossen ist (oder etwas später).
Aber wie gesagt: schlechtes Design und früher oder später kommt man
damit in die Bedrulie....
Ahnungsloser Holger schrieb:> Während dieser Zeit ist sowieso nichts> mit Bedienung der GUI
Auch das Neuzeichen geht nicht, ggf. blockierst du sogar das Beenden des
Programms... in kleinem Rahmen mag das gehen, wozu dann aber explizit
zwei Tasks wenn eh beide nacheinander ablaufen sollen?
Moin,
nun lass es mal egals sein was nun richtig oder falsch ist und ob es
funktioniert oder nicht oder sonst was.
Die Frage ist ja, wie bekomme ich folgendes hin, wobei task1 beendet
sein muss bevor task2 starten darf:
Schreib ich doch oben, das macht genau das, erst wird Task1
abgearbeitet, dann Task2.
Wie ich oben schon schrieb startest du damit keinen Hintergrundthread,
sondern reihst deine Aufgabe nur in die "Abarbeitungsqueue" des
GUI-Threads ein, der all diese Aufgaben nacheinander abarbeitet (deshalb
kann es sein, dass nach task1 noch andere Aufgaben anstehen die erst
ausgeführt werden, es wird aber auf jedenfall erst Task2 abgearbeitet
nachdem Task1 abgeschlossen ist).
Falls das "nicht so funktioniert" wie du dir das denkst müsste man mehr
Code sehen. Wenn da z.B. Callbacks im Spiel sind müsste ggf. Task1 den
Task2 als Konstruktorparameter kriegen und "am Ende" starten.
Läubi .. schrieb:> Dein zweiter Worker benötigt nun eine referenz auf den ersten, und fragt> in seiner doInBackground() methode das isDone() Flag ab, und legt sich> bei negativem Ergebnis erst mal schlafen... alternativ startet der erste> Worker den zweiten solabd er fertig ist.
Moin,
so, habe jetzt mal auf SwingWorker umgestellt;-) Danke!
Nun habe ich noch eine Frage: Wie mache ich das mit der Referenz?
Gruß
Ahnungsloser Holger
Bernd schrieb:> Da kann man sich benachrichtigen lassen wenn der> Task abgearbeitet wurde
Referenz? Man kann dort auch mit Futures arbeiten, was aber keine
Benachrichtigung enthält... ansonsten ist ein SwingWorker (auch) ein
Future...