Swing SwingWorker: Auf beendigung eines Formulars / einer Arbeit warten

Cromm Cruach

Mitglied
In einem Programm können mit Hilfe eines Formulars Daten in eine Datenbank eingegeben werden. Die Daten werden mit Hilfe eines SwingWorkers eingefügt. Bis hierhin ein Problem.

Nun hab ich eine Art "Stapelverarbeitung" programmiert. Die Eingaben, die der Nutz macht können auch per Datei vorliegen die in einem anderen Formular geladen werden.

Beispielszenario:

Im "Import-Formular" wählt der Nutzer die Datei aus, die die Daten enthält (z.B. 10 Einträge). Nach einem Klick auf einen Button wird das feritg ausgefüllte Formular (welches sonst auch beim manuellen hinzufügen angezeigt wird) angezeigt. Hier kann der Nutzer die Daten kontrollieren und dann der Datenbank hinzufügen. Nach dem der erste Eintrag hinzugefügt wurde soll ein neues Formular mit dem 2. eintrag angezeigt werden usw.

Das erzeugen der Formulare sowie das einfügen der Daten erfolgt auch in einem SwingWorker. Dieser aktualisiert gleichzeitig einer ProgressBar im Import-Formular die dem Nutzer anzeigt wieviele Daten (4/10 etc.) schon verarbeitet wurden.

Mein Problem ist nun das der SwingWorker des Import-Formulars auf einmal alle Formulare öffnet und die Progressbar dabei auf 100% setzt.

Was ich in der Theorie will ist, dass der SwingWorker der Import-Forumulars wartet, bis der SwingWorker des "Hininzufügen-Formular" mit dem hinzufügen der Daten fertig ist und erst dann weitermacht.

Der Import-SwingWorker bzw die Schleife dort drin müsste also für die Dauer des hinzufügens der Daten unterbrochen werden. Ich weis leider nicht wie ich das relaisieren soll.

Wird da irgendwas vom SwingWorker von "Haus" aus mitgeliefert oder wie sieht eine Realisierung in der Theorie aus?

Gruß
 
Zuletzt bearbeitet:
Klingt nach "viel auf einmal". Sind die "Formulare" modale Dialoge (oder sollten sie es vielleicht sein?) Ein KSKB wäre nicht schlecht, sofern es denn noch (das erste) "K" sein kann...
 
Ich frag mich gerade, ob ein SwingWorker das richtige dafür ist. Warum machst du es nicht manuell und zwar so, dass du den 1. Datensatz ins Formular lädst, überprüfst und evtl. abänderst, dann klickst du auf speichern, der Datensatz wird in die DB eingetragen, die Progressbar eins weiter gesetzt und der nächste Datensatz ins Formular übernommen. Solange, bis alle Datensätze abgearbeitet sind.
 
Ok funktioniert das denn aus dem "ImportFomular" hinaus? Hatte darmals dann immer das problem dass die veränderungen z.b in der progressbar immer nur dann sichbar wurden, wenn die Verarbeitung komplett zuende war.

Und dann bleibt noch meine Frage woher weis das importFormular wann das "Hinzufügen-Formular" (bzw dessen swingwoker) mit dem ersten datensatz fertig ist sodass der neue geladen werden kann.
 
Hmm, ohne den Code zu kennen, etwas schwierig. Aber es muss doch irgendeine Verbindung zwischen deinem Import-Formular und dem Hinzufügen-Formular bestehen. Sobald du im Hinzufügen-Formular den Datensatz zur Datenbank geschickt hast, holst du halt vom Import-Formular den nächsten Datensatz. Und die Progressbar muss halt auch über die Anzahl der gesamten und schon abgearbeiteten Anzahl der Datensätze informiert werden. Hört sich irgendwie so an, als müsstest du das mal mehr mit MVC umsetzen und evtl. einen Observer nehmen. Aber wie gesagt, ohne genauere Infos über die Struktur deiner Anwendung ist das nicht so einfach.
 
Die Verbingung ist, das das Import das Hinzufügen-Formular aufruft! Das hinzufügen der Daten in die DB dauert etwas so 20 Sekunden, da noch Daten aus dem Netz geladen werden ect. In der Zeit zeigt ein Ladebildschirm den Fortschritt an. Am Ende verschwindet der Ladebildschirm und das "Hinzufügen-Formular" ist wieder Freigegeben. Erst JETZT sollen die nächsten Daten ins Formular geladen werden.
 
So nun mal mit Code!

Java:
	public void actionPerformed(ActionEvent e){

		for(int i = 0; i < f.filenames.length; i++){
			new AnalyzeDataSwingWorker(f,i).execute();
		}
	}

Dieser ActionListener startet eine "Stapelverarbeitung". Für jede Datei wird ein Formular angezeigt, der Nutzer gibt Daten zu der entsprechenden Datei ein die dann Verarbeitet werden. Das ganze soll nacheinander ablaufen. Heist es wird erst das Formular für Datei1 angezeigt. Wenn der Nutzer die Daten eingegeben hat und die Daten verarbeitet wurden soll das Formular für datei2 angezeigt werden.

Mein Problem ist nun das alle Formulare gleichzeitig angezeigt werden. Da der SwingWorker bzw die Schleife ja nicht auf die Beendigung der Formulare und der darin befindenden SwingWorker wartet. Ich Suche nun nach einer Möglichkeit die Schleife zu unterbrechen und sie dann weiterlaufen zulassen, wenn die Verarbeitung der ersten Datei beendet ist.

Habs schon mit Thread.sleep sowie wait und notify von SwingWorker versucht. Entwerder blockiert mein System komplett oder es wird die erste Datei verarbeitet (wait scheint da zu funktionieren) aber das die weiteren werden nicht Verarbeitet (notify klappt also nicht).

Hier funktioniert die Verarbeitung einer Datei (nur einer die anderen werden nicht angezeigt)

Ich steuer den Swingworker das MainWindow welches alle Komponenten verbindet
Java:
	public void actionPerformed(ActionEvent e){

			f.owner.ads = new AnalyzeDataSwingWorker(f);
			f.owner.ads.execute();
	}

Mein SwingWorker
Java:
public class AnalyzeDataSwingWorker extends SwingWorker<Void, Void>{

	FileAnalysis f = null;
	
    public AnalyzeDataSwingWorker(FileAnalysis f){
        this.f = f;
    }

    @Override
    public Void doInBackground() throws Exception {
    	for(int i = 0; i < f.filenames.length; i++){
    		
    		f.owner.wait= true;
    		
			StringTokenizer t = new StringTokenizer(f.filenames[i], "[].", false);
			
			String quality = t.nextToken();
			String title = t.nextToken();
			
			MovieDataForm mdf = new MovieDataForm(f, "Daten hinzufügen");
			MovieSearch ms = new MovieSearch(mdf);
			
			ms.searchPanel.searchField.setText(title);
			ms.searchPanel.searchButton.doClick();
			
			mdf.tabPane.fileInfoPanel.qualityCombo.setSelectedItem(quality);
			mdf.tabPane.fileInfoPanel.sizeField.setText(f.size[i]);
			mdf.tabPane.setSelectedComponent(mdf.tabPane.picturePanel);
			
			f.owner.ads.wait();
    	}
			
    	
    	return null;
    }
}

Am ende der Datenverarbeitung soll mittes einer boolscher Variable darauf aufmerksam gemacht werden das ein SwingWoker wartet und dann fortgesetzt werden.

Java:
		if(f.owner.wait){
                        System.out.println("SwingWorker wird fortgesetzt");
			f.owner.wait = false;
			f.owner.ads.notify();
		}

Er Spring auf jedenfall in die Schleife (konsolenausgabe SwingWorker wird fotgesetzt kommt) leider hat das notyfy keine wirkung und auch notyfiAll bringt nichts.

Einer ne idee?
 
Überschreibe doch die Methode
Java:
protected void done()
in deinem AnalyzeDataSwingWorker und mache erst einen neuen SwingWorker wenn der alte signalisiert, das er fertig ist.
 
verstehe nicht genau die die methode dann aussehen soll / muss. Bzw. was sie mir bringt? Denn der SwingWorker soll ja warten bis die Verarbeitung der daten im anderen formular (dauert etwa 20 sekunden) beendet ist und erst dann soll ein neues formual angezeigt werden.

Ich brächte also in der Scheife irgend eine art von passivem warten?!
 
Zuletzt bearbeitet:
Der AnalyseDataSwingWorker ist ja nur zum anzeigen der Formuare da und die done() wird aufgerufen sobald ein Formular angezeigt wird.

Ich hab iwie das gefühl das ich um das passive Warten auf die Beendigung der mdf-Formulars nicht herum komme. Aber wie schon gesagt funktioniert
Code:
wait()
und
Code:
notify
bzw.
Code:
notifyAll()
aus mir unerklärlichen gründen nicht.

Bzw. das Warten klappt ja schon. Wenn ich das fortsetzten des SwingWorkers hinbekommen würde wäre das problem schon gelöst!
 
Dieser ActionListener startet eine "Stapelverarbeitung". Für jede Datei wird ein Formular angezeigt, der Nutzer gibt Daten zu der entsprechenden Datei ein die dann Verarbeitet werden. Das ganze soll nacheinander ablaufen. Heist es wird erst das Formular für Datei1 angezeigt. Wenn der Nutzer die Daten eingegeben hat und die Daten verarbeitet wurden soll das Formular für datei2 angezeigt werden.

Mein Problem ist nun das alle Formulare gleichzeitig angezeigt werden. Da der SwingWorker bzw die Schleife ja nicht auf die Beendigung der Formulare und der darin befindenden SwingWorker wartet. Ich Suche nun nach einer Möglichkeit die Schleife zu unterbrechen und sie dann weiterlaufen zulassen, wenn die Verarbeitung der ersten Datei beendet ist.

Für jede Datei wird ein Formular angezeigt? Oder meintest du, dass es 1 Formular gibt und immer nur die Daten ausgetauscht werden? Wenn du mit MVC arbeitest, dann ist das Formular deine View, die Daten liegen im Model und über die Control speicherst du die Daten ab und holst den nächsten Datensatz.

Wenn du alles in einem SwingWorker laufen lässt, dann läuft das eben alles in einem Prozzess durch. Evtl. könntest du für jede Datei einen SwingWorker nehmen und starten. Aber wie schon gesagt: du solltest dir immer erst den nächsten Datensatz ins Formular holen, wenn der vorherige mit Klick auf Button abgespeichert wurde. Du kannst ja zu Beginn alle Dateien/Datensätze einlesen. Sobald dies geschehen ist, wird der erste Datensatz im Formular angezeigt, Klick auf Button, danach der nächste Datensatz usw.
 

Zurück
Oben