SwingWorker: Auf ende Warten

daniel_sun

Erfahrenes Mitglied
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)

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?
 
du könntest es folgendermaßen machen: Die Methode done() wird im Event Dispatcher Thread (EDT) auf alle Fälle nach doInBackground() aufgerufen. Wenn du also sichergehen willst, dass der nächste SwingWorker (SW) erst dann beginnt, wenn der vorige beendet ist, dann rufe einfach execute() für den nächsten SW innerhalb von done() auf. Z.B. so:
Java:
public class MySwingWorker extends SwingWorker<Object, Object> {

	private final SwingWorker<Object, Object> nextWorker;

	public MySwingWorker(SwingWorker<Object, Object> nextWorker) {
		this.nextWorker = nextWorker;
	}

	@Override
	protected Object doInBackground() throws Exception {
		Object ret = null;
		// do the work
		return ret;
	}

	@Override
	protected void done() {
		// do something
		// then the next worker
		nextWorker.execute();
	}

	public static class Control implements ActionListener {

		private final MySwingWorker w1;

		public Control() {
			MySwingWorker w3 = new MySwingWorker(null);
			MySwingWorker w2 = new MySwingWorker(w3);
			w1 = new MySwingWorker(w2);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			w1.execute();
		}
	}
}

Dass execute() für den nächsten SW innerhalb des EDT aufgerufen wird, ist OK, da doInBackground() in einem neuen Thread abgearbeitet wird.

Gruß
Peter
 

Neue Beiträge

Zurück