SwingWorker abbrechen

daniel_sun

Erfahrenes Mitglied
Hallo,

Folgender SwingWorker befüllt ein Formular mit daten und Bildern aus dem Internet:

Java:
public class ImportDataSwingWorker extends SwingWorker<String, String> {

	AddFilmDialogController addFilmDialogController;


	/**
	 * Übergibt den Formularcontroler
	 * 
	 * @param addFilmDialogController
	 *            Controller
	 */
	public ImportDataSwingWorker( AddFilmDialogController addFilmDialogController ) {

		this.addFilmDialogController = addFilmDialogController;
	}


	/**
	 * Ausführung der Aufgabe
	 */
	@Override
	protected String doInBackground() throws Exception {

		addFilmDialogController.disableDialog();

		if ( addFilmDialogController.isImportFieldEmpy() ) {
			addFilmDialogController.setImportError( "Bitte geben Sie eine TMDb-ID ein!" );
		} else {
			addFilmDialogController.setImportError( "" );
			try {
				addFilmDialogController.loadMovie();
				addFilmDialogController.importData();
			} catch ( IOException | ParserConfigurationException | SAXException e ) {
				e.printStackTrace();
			}
		}

		addFilmDialogController.enableDialog();

		return null;
	}


}

Während des Ladevorgangs wird ein Ladebildschrim angezeigt. Auf diesem Befindet sich ein Button der den Ladevorgang abbrechen soll! In diesem Fall soll der Swingworker gestopt und das Formular geleert werden. Der Button ruft folgende Methode auf:

Java:
	/**
	 * Bricht den Importvorgang ab
	 */
	public void cancelImport() {

		enableDialog();
		importDataSwingWorker.cancel( true );
		addFilmDialog.clearCover();
		addFilmDialog.clearFields();
		addFilmDialog.clearTables();
		splashScreen.closeWindow();
	}

Wenn ich den Abbruchvorgang ausführe kommt folgende Konsolenausgabe:

Code:
INTERRUPTED while loading Image

Alles was bis dahin geladen wurde, wird wie gewünscht geleert. Das ist das der SwingWorker nicht stoppt! Wenn z.B. Alle Textfelder befüllt und 10 von 15 geladen sind und ich den Abbruch betätige, werden die Textfelder geleert die 10 aus der Anzeige entfernt aber der SwingWorker arbietet weiter und läd noch die 5 verbleibenden Bilder. Egal wo ich den Abbruch betätige der SwingWorker führt den Rest seint Aufgabe aus.

Ich habe bisher nur mit SwingWorkern gearbeitet, die von Anfang bis Ende laufen sollte. Das ist das erste mal das ich in einen Thread eingreifen will. Wie beende ich diesen korrekt und gehe sicher, dass das Leeren des Dialogs erst dann ausgeführt wird wenn der Worker auch korrekt beendet ist sodass auch alles gelöscht ist.

Gruß
 
Zuletzt bearbeitet:
Huhm, mein Vorschlag (müsste an und für sich einfach gehen, wenn ich das so nochmals durchlese *g*)

Du kannst in der Schleife, von welcher ich den Code hier jetzt so ned sehe :)P), ein if(running) machen (running als member boolean variable). Wichtig: Die Variable muss transient sein, damit es jeweils neu aus dem Speicher geladen wird. Das Feld kann man von aussen setzen.

Und um ganz sicher zu sein, würde ich da einen kleinen Observer machen. Also Benutzer drückt auf "Abbrechen", sagt dem SwingWorker "Stopp du mal" und wenn der SwingWorker auch wirklich gestoppt wurde (die Iteration beendet wurde), sagt der Worker dem Programm, "okay, ich bin fertig". Weil ansonsten kann es sein, dass du zwar stoppst, gleichzeitig die Felder leerst, der SwingWorker dann aber noch in einer Iteration drink steckt und noch ein Feld setzt...

Gruss
slowy
 
aus der Doku:
"This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason."

Ich nehme an, dein SwingWorker hat seine Arbeit schon erledigt, weswegen cancel(true) keinen Sinn mehr macht. Oder dauert die Arbeit so lange, dass du das definitiv ausschließen kannst? Kannst ja mal - nur zum Testen - doInBackground() mit einem Thread.sleep(...) verzögern.

Gruß
Peter
 
Zurück