Problem mit der Synchronisierung von Threads

andreT

Aktives Mitglied
Hallo,

ich habe wohl ein Problem mit der Synchronisierung von Threads. Vorab: Ich bin ich nicht sonderlich fitt im Umgang mit Threads daher habe ich
mal eine kleine Beispielanwendung gebastelt die das Problem nachstellen kann. Die Beispielanwendung ist natürlich ggü. der echten Anwendung vereinfacht,
kann den "Fehler" aber korrekt reproduzieren.

Zum Problem : Wenn man die Anwendung startet öffnen sich 2 voneinander unabhängige Fenster die jeweils eine lange Verarbeitung simulieren.
Diese langen Verarbeitungen (Threads ... ich nenne sie auch Tasks) können jeweils über einen Cancel-Button in den Fenstern abgebrochen werden.
Wenn man nun folgende Reihenfolge GENAU einhält, kann der/mein Fehler reproduziert werden:

1.) Anwendung starten

2.) Cancel-Button von Fenster1 (LongTaskJFrame-1) anklicken und den Cancel-Dialog STEHENLASSEN!
- Die Verarbeitung wird im Hintergrund korrekt angehalten. Soweit so gut.

3.) Cancel-Button von Fenster2 (LongTaskJFrame-2) anklicken und den Cancel-Dialog ebenfalls STEHENLASSEN!
- Die Verarbeitung wird im Hintergrund auch hier korrekt angehalten.
- MERKE : Würde man jetzt YES oder NO dieses Cancel-Dialog anklicken, würde kein Fehler auftreten. Wir müssen aber hier jetzt mit 4.) weitermachen damit der "Fehler" reproduziert werden kann.

4.) Jetzt den YES oder NO Button vom Cancel-Dialog von Fenster1(!!!) anklicken -> Jetzt müsste je nach Auswahl der Thread/Task von Fenster1 beendet werden oder weiterlaufen. Hier tut sich nun aber überhaupt nichts mehr!
Warum das? Ich hätte jetzt erwartet daß Fenster1 nun beendet oder weiter aktualisiert wird?! Was mache ich hier falsch?

Zur Info : Das Anhalten und Abbrechen der Threads/Tasks findet maßgeblich in den Methoden
Task.checkPaused()
Task.proceed()
LongTaskJFrame -> siehe Konstruktor -> Anonymer ActionListener des Cancel-Buttons
LongTask.run() -> for-Schleife

Sorry für soviel Code, aber wenn man genau hinschaut ist das meiste eigtl. nur 'ne Menge Doku und Swing-Kram :oops:

Die Klassen :

Task.java
Java:
/**
 * Diese Klasse realisiert einen Thread (wir nennen dieses Objekt hier auch Task!) der angehalten und abgebrochen werden kann.
 */
public abstract class Task extends Thread {	
	// Kann von aussen gesetzt werden um den Thread/Task anzuhalten.
	private boolean paused = false;
	// Kann von aussen gesetzt werden um den Thread/Task abzubrechen.
	private boolean canceled = false;
	
	/**
	 * 
	 */
	public Task() {
		super();
	}

	/**
	 * Hiermit kann der Thread/Task angehalten werden.
	 */
	public final void pause() {
		paused = true;			 	
	}
	
	/**
	 * Hiermit kann ermittelt werden ob der Thread/Task angehalten wurde.
	 */
	public final boolean isPaused() {
		return paused;			
	}

	/**
	 * Hiermit kann der Thread/Task abgebrochen werden.
	 */
	public final void cancel() {
		canceled = true;	
	}
	
	/**
	 * Hiermit kann ermittelt werden ob der Thread/Task abgebrochen wurde.
	 */
	public final boolean isCanceled() {
		return canceled;	
	}
	
	/**
	 * Hiermit kann der Thread/Task, sofern das Pause Flag gesetzt (true) wurde, angehalten werden.
	 */
	protected final synchronized void checkPaused() {		
		if(isPaused()) {
           	try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
        }               
	}
	
	/**
	 * Hiermit kann der ggf. angehaltene Thread/Task fortgesetzt werden.
	 */
	public final synchronized void proceed() {
		if(isPaused()) {
			paused = false;
			notify();
		}
	}
	
	/**
	 * Wird angestossen wenn der Thread/Task gestartet wird.
	 */
	public abstract void run();
}

LongTask.java
Java:
/**
 * Diese Klasse realisiert nur einen langen ThreadTask/ der angehalten und abgebrochen werden kann.
 * Siehe dazu auch die entsprechenden Methoden der Superklasse. 
 */
public final class LongTask extends Task {
	private LongTaskJFrame frame = null;
	
	/**
	 * Erzeugt einen langen Thread/Task.
	 * Der Name wird nur benötigt damit eine Fortschrittsanzeige (ProgressMessage) entsprechend aufbereitet werden kann.
	 * Wir benötigen hier noch das Fenster weil wir dort die Fortschrittsanzeige anzeigen wollen. zwar nicht sehr elegant 
	 * hier, aber es erfüllt hier seinen Zweck. Normalerweise wird dies über einen Listener o.ä. realisiert. Whatever ...
	 */
	public LongTask(String name, LongTaskJFrame frame) {
		super();
		setName(name);
		this.frame = frame;
	}

	/**
	 * 
	 */
	public void run() {
		try {
			// Lange Verarbeitung hier jetzt erzeugen.
			int maximum = Integer.MAX_VALUE / 70;
			for (int i = 0; i < maximum; i++) {
				// Ggf. wird hier jetzt angehalten/pausiert.
				// Siehe Superklasse !!!
				checkPaused();
				// Ggf. wird hier jetzt abgebrochen.
				// Siehe Superklasse !!!
				if (isCanceled()) {
					break;
				}

				// Fortschrittsanzeige aufbereitet anzeigen.
				frame.setProgressMessage(getName() + " - > ProgressMessage = " + i);
			}
			
			// Fortschrittsanzeige -> ENDE.
			frame.setProgressMessage(getName() + " - > FINISHED");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

LongTaskJFrame.java
Java:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * Diese Klasse realisiert eigentlich nur ein Fenster das den Fortschritt eines langen Threads/Tasks anzeigen 
 * soll. Mit einem Cancel-Button kann der Thread/Task dann angehalten und abgebrochen werden. 
 * 
 * Wir starten den langen Thread/Task hier in dieser Klasse. Zwar nicht sehr schick, erfüllt aber hier seinen Zweck.
 */
public final class LongTaskJFrame extends JFrame {
	// Ein Label das eine Fortschrittsanzeige (ProgressMessage) anzeigen kann.
	private JLabel progressLabel = null;
	// Ein Cancel-Button mit dem man den langen Thread/Task anhalten und abbrechen kann.
	private JButton cancelButton = null;
	// Der lange Thread/Task
	private LongTask longTask = null;
	
	/**
	 * 
	 */
	public LongTaskJFrame(String title) {
		super(title);
		progressLabel = new JLabel("");
		getContentPane().add(progressLabel, BorderLayout.NORTH);
		
		// Cancel-Button mit ActionListener erzeugen.
		cancelButton = new JButton("Cancel");
		cancelButton.addActionListener(new ActionListener() {
			// Es wurd auf den Cancel-Button geklickt.
			public void actionPerformed(ActionEvent arg0) {
				// 1.) Thread/Task anhalten
				longTask.pause();
				// 2.) Fragen ob abgebrochen werden soll.
				ConfirmDialog confirmDialog = new ConfirmDialog(LongTaskJFrame.this, "Cancel?");
				confirmDialog.setVisible(true);				
				boolean selectedOption = confirmDialog.getSelectedOption();
				
				// Wenn ja Thread/Task abbrechen und dieses Fenster schliessen. 
				if(selectedOption) {
					longTask.cancel();
					dispose();
				}
				// Andernfalls den Thread/Task weiterlaufen lassen.
				else {					
					longTask.proceed();
				}
			}
		});
		getContentPane().add(cancelButton, BorderLayout.SOUTH);
		
		// Den langen Thread/Task erzeugen.
		longTask = new LongTask("LongTask (" + getTitle() + ")", this);
		
		// Anzeige des Fensters.
		setMinimumSize(new Dimension(400, 100));
		setPreferredSize(new Dimension(400, 100));
	}
	
	/**
	 * Damit der lange Thread/Task extern gestartet werden kann. 
	 */
	public void startLongTask() {		
		longTask.start();
	}	
	
	/**
	 *  
	 */
	public void setProgressMessage(String progressMessage) {
		progressLabel.setText(progressMessage);
	}
}

ConfirmDialog.java
Java:
import java.awt.BorderLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;

/**
 * Diese Klasse realisiert nur einen modalen YES/NO Dialog.
 * Die Methode <code>boolean getSelectedOption()</code> liefert dann das Ergebnis. 
 */
public final class ConfirmDialog extends JDialog {
	private boolean selectedOption = false;
	
	/**
	 * 
	 */
	public ConfirmDialog(Window owner, String title) {
		super(owner);
		setTitle(title);
		
		JButton yesButton = new JButton("Yes");
		yesButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectedOption = true;
				dispose();
			}
		});
		getContentPane().add(yesButton, BorderLayout.WEST);
		
		JButton noButton = new JButton("No");
		noButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				selectedOption = false;
				dispose();
			}
		});
		getContentPane().add(noButton, BorderLayout.EAST);
		
		setModal(true);
		setModalityType(ModalityType.DOCUMENT_MODAL);
		pack();		
		setLocationRelativeTo(getOwner());
	}
	
	/**
	 * 
	 */	
	public boolean getSelectedOption() {
		return selectedOption;
	}
}

Main.java
Java:
import java.awt.Point;

/**
 * Startklasse der Beispielanwendung.
 */
public class Main {

	/**
	 * Es werden 2 Fenster gestartet die jeweils ein lange (voneinander UNABHÄNGIGE) Verarbeitung simulieren sollen. 
	 * Die Verarbeitung kann jeweils über einen Cancel-Button abgebrochen werden. Damit die Fenster (und ihre 
	 * Cancel-Dialoge) unabhängig voneinander gestartet werden können, wird hier jedes Fenster jeweils in einem
	 * eigenem Thread gestartet. Würden wir dies hier nicht tun, kommt es seitens Swing zu "fragwürdigem" Verhalten
	 * bei den modalen Cancel-Dialogen. Wie auch immer, soweit alles (noch) kein Problem.
	 * 
	 * Spannend wird es wenn wir nun folgendes GENAU IN DER REIHENFOLGE ANKLICKEN :
	 * 
	 * 1.) Cancel-Button von Fenster1 (LongTaskJFrame-1) anklicken und Cancel-Dialog STEHENLASSEN!
	 * 	   - Die Verarbeitung wird im Hintergrund korrekt angehalten. Soweit so gut.
	 * 
	 * 2.) Cancel-Button von Fenster2 (LongTaskJFrame-2) anklicken und Cancel-Dialog ebenfalls STEHENLASSEN!
	 *     - Die Verarbeitung wird im Hintergrund auch hier korrekt angehalten.
	 *     - MERKE : Würde man jetzt YES oder NO dieses Cancel-Dialog anklicken, würde kein Fehler auftreten. Wir
	 *       müssen aber hier jetzt mit 3.) weitermachen damit der Fehler auftritt.
	 *     
	 * 3.) Jetzt den YES oder NO Button vom Cancel-Dialog von Fenster1(!!!) anklicken -> Jetzt müsste je nach Auswahl 
	 * der Thread/Task von Fenster1 beendet werden oder weiterlaufen. Hier tut sich aber nun nichts mehr!
	 * Warum das? Ich hätte jetzt erwartet daß Fenster1 nun beendet oder weiter aktualisiert wird?!
	 * 
	 * Erst wenn der Cancel-Dialog von Fenster2 ebenfalls weggeklickt wurde, nimmt auch der Thread/Task von Fenster1 
	 * wieder seine Arbeit auf.  
	 * 
	 * Was mache ich hier falsch? 
	 *   
	 */
	public static void main(String[] args) {
		class Thread1 extends Thread {
			public void run() {
				// Erstes Fenster erzeugen ...
				LongTaskJFrame frame1 = new LongTaskJFrame("LongTaskJFrame-1");
				frame1.setLocation(new Point(100, 100));
				// ... und anzeigen.
				frame1.setVisible(true);
				// Lange Verarbeitung jetzt starten.
				frame1.startLongTask();
			}
		}
		Thread1 thread1 = new Thread1();
		thread1.start();
				
		class Thread2 extends Thread {
			public void run() {
				// Zweites Fenster erzeugen ...
				LongTaskJFrame frame2 = new LongTaskJFrame("LongTaskJFrame-2");
				frame2.setLocation(new Point(100, 300));
				// ... und anzeigen.
				frame2.setVisible(true);
				// Lange Verarbeitung jetzt starten.
				frame2.startLongTask();
			}
		}
		Thread2 thread2 = new Thread2();
		thread2.start();
	}
}
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Allgemein:
- booleans, die von einem Thread geschrieben und vom anderen gelesen werden sollen, und bei denen diese Änderungen NICHT in synchronized-Blöcken stattfinden, müssen volatile sein. (Ob das hier durch die übrigen syncronized's vielleicht überflüssig wäre, habe ich nicht im Detail nachvollzogen)
- ALLE Operationen, die das Aussehen von GUI-Components verändern oder darauf zugreifen, müssen im Event-Dispatch-Thread stattfinden. Das bezieht sich auch auf das Erstellen der beiden Frames.
- Sowas wie das "setProgressMessage", was direkt aus einen Fremd-Thread bis zum JLabel durchreicht, kann der Killer sein: Bei mir reagiert der Cancel-Button erstmal ein paar Sekunden lang nicht, weil er damit beschäftigt ist, viele hunderttausend mal pro Sekunde (auf dem falschen Thread!) den Label-Text zu ändern

Speziell zum Problem:
Hab mal ein bißchen rumprobiert, aber bin auch auf keinen grünen Zweig gekommen... Das Problem tritt ja wirklich nur GANZ spezifisch bei dem beschrieben Ablauf auf. Durch Debuggen und ein paar System.out's sieht man, dass er in den anonymen ActionListenern vom Cancel-Button hängt - und zwar auch im ersten Dialog so lange, BIS der zweite Beendet wird. Es scheint fast, als würde da was mit dem Modality Type nicht stimmen, aber ... erstens habe ich die noch nicht im Detail verwendet, und zweitens wüßte ich jetzt beim Nachlesen nicht, WAS da falsch sein sollte. Das, was bei einem modalen Dialog in Dialog#show passierte, war schon mit der alten Modality schwarze Magie, aber mit der neuen ist es :autsch: ... (Kommentare wie
[c]// add all blockers' blockers to blockers :)[/c]
... ja, lustig ;) ). Jedenfalls hat auch einiges an Referenzensuche im Debugger keine Einsichten gebracht.

Vom Bauchgefühl her würde ich sagen: Das ist ein Bug. Hab's mal als KSKB zusammengefasst:

Java:
package javaforum.threadsync;

import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

public class DocumentModalTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
    
    private static void createAndShowGUI()
    {
        createFrame("0", 0);
        createFrame("1", 200);
    }
    
    private static void createFrame(final String suffix, int y)
    {
        final JFrame frame = new JFrame("Frame"+suffix);
        frame.getContentPane().setLayout(new FlowLayout());
        JLabel label = new JLabel("<html>"+
            "- Press 'Show Dialog0'" + "<br />" +
            "- Press 'Show Dialog1'" + "<br />" +
            "- Press 'Close Dialog0'" + "<br />" +
            "- The message 'Closed Dialog0' is NOT printed!" + "<br />" +
            "- Press 'Close Dialog1'" + "<br />" +
            "- The message 'Closed Dialog0' AND 'Closed Dialog1' are printed" + "<br />");
        frame.getContentPane().add(label);
        
        JButton showButton = new JButton("Show Dialog"+suffix);
        frame.getContentPane().add(showButton);
        showButton.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                TestDialog testDialog0 = new TestDialog(frame, "Dialog"+suffix);
                System.out.println("Showing Dialog"+suffix);
                testDialog0.setVisible(true);
                System.out.println("Closed  Dialog"+suffix);
            }
        });
        frame.setBounds(0,y,450,200);
        frame.setVisible(true);
    }
    
    
    private static class TestDialog extends JDialog 
    {
        public TestDialog(Window owner, String title) 
        {
            super(owner, ModalityType.DOCUMENT_MODAL);
            setTitle(title);
            JButton closeButton = new JButton("Close "+title);
            closeButton.addActionListener(new ActionListener() 
            {
                @Override
                public void actionPerformed(ActionEvent e) {
                    setVisible(false);
                    dispose();
                }
            });
            getContentPane().add(closeButton);
            setLocationRelativeTo(owner);
            pack();
        }        
    }
    
}

Fände es interessant, wenn das jemand bei Sun posten könnte, würde mich jetzt auch mal interessieren...
 

andreT

Aktives Mitglied
Danke schonmal vorab!

Natülich ist das in der Anwendung alles etwas sauberer. Da werden die Fortschrittsmeldungen aus einem anderen Thread auch direkt von den Threads/Tasks gelesen und korrekt im EDT in die GUI gesetzt. Da hängt noch so ein Mini-Batch System und ähnliche "Sauereien" dran. Das hab ich aber alles nicht mehr nachbilden wollen.
Du hast das Problem aber offensichtlich schonmal auf das Modality-Zeugs reduzieren können. Das nimmt mir schonmal echt eine ganze Last von den Schultern da das Threadhandling in der Anwendung schon recht grundlegend ist. Hätte ich da jetzt ein Problem ... :shock:

Wie läuft denn das? Wer kann denn bei Oracle/Sun Bugs posten? Jeder? im Zweifel meld' ich mich dann da an o.ä.?!? Hat jemand einen entsprechenden Account?
 

Marco13

Top Contributor
Es kommt sehr selten vor, dass ich wirklich glaube, dass so ein Verhalten wirklich ein Bug ist - bisher eigentlich noch nie.

Deswegen würde ich auch nochmal abwarten, ob sich vielleicht jemand meldet, der sagt: "Auf Linux funktioniert's" oder "Ihr hättet den ModalExclusionType auf 'Magic' setzen müssen" (ich hab' mit der "new modality API noch nicht viel gemacht). Mit dem KSKB ist die Hürde, das auszuprobieren, ja vielleicht auch geringer ;)

Ich glaube, einen Account braucht man nichtmal: Grundsätzlich sollte man wohl ausgehend von Report a Bug or Request a Feature solche Bugs reporten können. Man sollte aber SEHR sorgfältig sein und genau beachten, was dort vorgegeben ist, um sich nicht zum **** zu machen ;) :
- Nochmal mit der neuesten Version testen (ich hab's mit einer 6er-Version gecheckt, vielleicht funktioniert's bei Java 7u5 ja schon!?!),
- Nochmal das gepostete KSKB verifizieren, ob es wirklich so passt
- Die BugDatabase durchsuchen, ob es nicht doch schon irgendwo reportet ist...
- Sich genau an Sun SDN Article - How to Write a Helpful Bug Report halten...
 

andreT

Aktives Mitglied
Ich bin einigermaßen fit in den Swing-Sachen und würde mich jetzt doch sehr wundern wenn so ein Verhalten wirklich so gewollt ist. Verdächtig finde ich übrigens in diesem Zusammenhang auch, daß wenn der Modalitytype nicht via Konstruktor übergeben wird, AUCH NUR DANN richtig angezogen wird wenn dieser NACH dem Aufruf von setModal(boolean) gesetzt wird. Siehe Bsp. hier : http://www.java-forum.org/awt-swing-swt/139476-jdialog-modal-blockiert-alle-fenster.html
Ich habe ja auch erst seit 2 Tagen mit der neuen Vorgehensweise (Modality / Java7) Bekanntschaft gemacht, aber ich würde jetzt wirklich auf einen BUG o.ä. tippen.
Whatever ... ich werde mich da nochmal reinfuchsen und dein KSKB ggf. bei SUN einstellen. Sollen sie mich halt steinigen :D
 

Mujahiddin

Top Contributor
Hi,
hab mal dein KSKB ausprobiert und mir ist Folgendes aufgefallen.
Du erstellst beide Dialogs aus dem selben Thread.
Sprich, wenn du den ersten Dialog öffnest, wird er angezeigt. und der Thread (EventQueue) wartet darauf, dass der Dialog geschlossen wird.
Falls du dann noch einen zweiten Dialog hinzufügst mit dem selben Thread, wartet dieser nun auf den zweiten Dialog (keine Ahnung warum keine Exception geschmissen wird und warum ein Thread, der "geblockt" wird, weiter Operationen ausführen kann. Diese werden aber anscheinend gestackt und solange der oberste nicht gelöst ist, werden alle unteren geblockt.)
Wenn man das Öffnen in einen eigenen Thread schiebt, klappt's problemfrei. Allerdings sei dahingestellt, ob das die beste Lösung ist:

Java:
showButton.addActionListener(new ActionListener() {
	@Override
	public void actionPerformed(ActionEvent e) {
		new Thread(new Runnable(){
			public void run(){
				TestDialog testDialog0 = new TestDialog(frame, "Dialog"
						+ suffix);
				System.out.println("Showing Dialog" + suffix);
				testDialog0.setVisible(true);
				System.out.println("Closed  Dialog" + suffix);
			}
		}).start();
	}
});

EDIT:
Gerade nachgeguckt:
"Close Button" wird aus dem EventQueue ausgelöst, also scheint diese Methode akzeptabel.
Evtl kann man noch sowas hier draus machen:

Java:
showButton.addActionListener(new ActionListener() {
	@Override
	public void actionPerformed(ActionEvent e) {
		final TestDialog testDialog0 = new TestDialog(frame, "Dialog" + suffix);
		System.out.println("Showing Dialog" + suffix);
		new Thread(new Runnable() {
			public void run() {
				testDialog0.setVisible(true);
				System.out.println("Closed  Dialog" + suffix);
			}
		}).start();
	}
});
 
Zuletzt bearbeitet:

andreT

Aktives Mitglied
Super! Das hat mir bei dem Problem jetzt kurzfristig wirklich geholfen. Auch in der Zielanwendung klappt das so! Ggf. werde ich das KSKB noch bei SUN posten, weil das ja eigtl. auch innerhalb eines Threads klappen sollte, aber da mache ich micht erst noch etwas schlauer.
Aber wenigstens kann ich jetzt hier weiter entwickeln :toll:

Dank und Gruß
Andre
 

Marco13

Top Contributor
@Mujahiddin: Das verstößt eben gegen die "Single Thread Rule" (zumindest das Erstellen des Dialogs sollte nur auf dem EDT gemacht werden). Als Workaround ist es vielleicht OK, aber es sollte IMHO nicht notwendig sein.
... warum ein Thread, der "geblockt" wird, weiter Operationen ausführen kann
Das ist die angesprochene "Magie" aus dem Dialog#show für modale Dialoge ;) Was dort gemacht wird ist total cranker shyce, ... es wird sozusagen so getan, als würde für den Dialog ein zweiter EDT gestartet (ich meine sogar, dass das früher mal wirklich so WAR, aber jetzt scheint es nicht mehr so zu sein - die "new modality API" hat da aber auch etliches geändert).
 

Mujahiddin

Top Contributor
Die Frage ist halt auch, wie oft man in einer Anwendung doppelte modale Dialoge benötigt? Mal abgesehen davon, ob sowas überhaupt sinnvoll ist.
Ja, es gibt nur einen EDT und wenn der doppelt geblockt wird, wird's brenzlig.
Das einzige, was mich wie gesagt wundert ist, dass der EDT, obwohl er eben geblockt ist, weiterhin Sachen macht. Wobei man ansonsten wahrscheinlich selbst bei einfach geblockten Dialogen Probleme geben würde.
Aber im Grunde genommen ist sowas IMHO ein Ausnahmefall. Zwei modale Dialoge sind nicht gerade die Regel und man kann sicher zum Entschluss kommen, dass man gut damit wegkommt, wenn man die Dialoge nicht modal macht. Aber sollte man unbedingt modale Dialoge benötigen, dann kommt man (zumindest momentan) nicht drum rum, das mit einem anderen Thread zu handhaben.

Evtl kann man ja einen Kompromiss mit SwingWorker finden...
 

Marco13

Top Contributor
Hm. Mir erschien der Anwendungsfall im ersten Moment zumindest plausibel: Mehrere Tasks, die einzeln und unabhängig voneinander abgebrochen werden können (und jeweils ihren eigenen modalen Dialog brauchen). Um das zu unterstützen gibt es ja gerade "DOCUMENT_MODAL". Bei genauer Betrachtung frage ich mich schon, wie die konkrete Anwendung aussehen sollte - also, wo man diese Funktionalität, dass ein Dialog den anderen "überlebt" wirklich BRAUCHT, und es nicht EIN modaler Dialog tun würde, aber ... das muss der TO wissen ;)
 

andreT

Aktives Mitglied
Ich mache öfter mal Swing Projekte für Unternehmen und eigtl. ist der Anwendungsfall gar nicht so selten. Die Anwendungen haben oftmals mehrere JFrames parallel geöffnet die unabhängig voneinander bestimmte Verarbeitungen ermöglichen sollen/können/müssen. Natürlich kann es dann auch zu Fehlermeldungen (und damit dann zu modalen Dialogen) kommen.
Bei Weboberflächen werden solche Verarbeitungen ja generell anders gelöst, aber bei Swing GUIs ist der Anwendungsfall nach meinen Erfahrungen nicht so selten. Whatever ... mit dem Workaround klappts soweit ganz gut. Wenn ich in den nächsten Tagen Zeit finde, stelle ich das Bsp. aber noch bei Sun/Oracle ein.
 

Marco13

Top Contributor
Ahja, stimmt, Dispatched heißt wohl erstmal nur, dass er irgendjemandem zum Nachvollziehen weitergeleitet wurde. Bin mal gespannt was da noch rauskommt.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
A Problem mit Synchronisierung Allgemeine Java-Themen 10
krgewb Problem mit Umlauten und Eszett bei InputStream Allgemeine Java-Themen 3
Max246Sch Backtracking Problem Box Filler Allgemeine Java-Themen 6
NightVision402 VisualVM Startskript Problem Allgemeine Java-Themen 3
javaBoon86 Email Server Connection Problem Allgemeine Java-Themen 1
F Problem mit PDFBOX Library Allgemeine Java-Themen 1
A Java modul Problem Allgemeine Java-Themen 4
D Read JSON File Problem Allgemeine Java-Themen 9
urmelausdemeis Exception in thread "main" java.lang.Error: Unresolved compilation problem: Allgemeine Java-Themen 7
J Problem mit JasperReports Allgemeine Java-Themen 8
M log4j Problem mit jlink Allgemeine Java-Themen 19
8u3631984 Problem beim Mocken von Record Klassen Allgemeine Java-Themen 4
torresbig Website login Problem - Jsoup, wie bisher, klappt nicht! Allgemeine Java-Themen 31
P Selenium . getText Problem Allgemeine Java-Themen 9
A Jar zu Exe Problem Allgemeine Java-Themen 13
sserio Variablen Liste erstellt und ein Problem mit dem Index Allgemeine Java-Themen 6
S Folgendes Problem bei einem Programm Allgemeine Java-Themen 1
stormyark Problem beim Klassen erstellen Allgemeine Java-Themen 1
A Thread.sleep Problem Allgemeine Java-Themen 2
A Problem bei der Nachbarschafttest Allgemeine Java-Themen 11
Splayfer Problem: no main manifest attribute Allgemeine Java-Themen 3
G javamail Problem beim Empfangen von Nachrichten Allgemeine Java-Themen 3
Splayfer JDA Problem mit MessageCounter Allgemeine Java-Themen 0
Splayfer Problem mit BufferedWriter Allgemeine Java-Themen 3
F Streams als Alternative für dieses Problem ? Allgemeine Java-Themen 15
N Maven Problem mit Datenbanktreiber (H2 Embedded) Allgemeine Java-Themen 12
T Problem beim Umwandeln in eine Jar-Datei Allgemeine Java-Themen 3
B Einfach Elemente zweier Arraylisten kreuz und quer vergleichen, min und max Problem? Allgemeine Java-Themen 16
C ArrayList Problem Allgemeine Java-Themen 3
kev34 nim-Spiel problem Allgemeine Java-Themen 1
D Firebase retrieve data Problem, Child Element wird nicht angesprochen Allgemeine Java-Themen 0
G Welches Problem besteht bei den Typparametern? Allgemeine Java-Themen 5
temi Problem mit Aufrufreihenfolge bei Vererbung Allgemeine Java-Themen 3
Sumo_ow "ArrayIndexOutofBoundsException: 2" Array Problem Allgemeine Java-Themen 6
T PIM basierend auf netbeans via AnyDesk Problem Allgemeine Java-Themen 3
xGh0st2014 Problem mit Java Array Allgemeine Java-Themen 1
Kirby.exe Verständnis Problem bei Rucksack Problem Allgemeine Java-Themen 6
B Eclipse-Lombok-Problem Allgemeine Java-Themen 19
I Input/Output ObjectOutputStream - Problem Allgemeine Java-Themen 7
1 Multiple Choice Knapsack- Problem Allgemeine Java-Themen 2
kodela Problem mit strukturiertem Array Allgemeine Java-Themen 18
E Problem mit Gridlayout und Button Allgemeine Java-Themen 2
A Array Problem Allgemeine Java-Themen 8
bueseb84 Problem Allgemeine Java-Themen 0
S Problem mit Arrays Allgemeine Java-Themen 1
D Nullpointer Exception Problem Allgemeine Java-Themen 5
B Problem mit meinen Klassen Allgemeine Java-Themen 6
A HashMap Methode "get()"-Problem Allgemeine Java-Themen 28
J Problem beim Umstellen auf Java jdk 13 Allgemeine Java-Themen 3
J Problem bei Install java 13 Allgemeine Java-Themen 3
X Profitable Reise Problem Allgemeine Java-Themen 32
A Problem beim öffnen von Java-Installern Allgemeine Java-Themen 1
Dann07 Problem mit JavaMail API Allgemeine Java-Themen 26
J Problem beim Generischen Klassen und Interfaces Allgemeine Java-Themen 2
L Klassen Algorithmus für das folgende Problem entwickeln? Allgemeine Java-Themen 30
J Clear-Problem Allgemeine Java-Themen 10
B Problem zu einem Java Projekt Allgemeine Java-Themen 6
S JFileChooser Problem Allgemeine Java-Themen 4
M Traveling Salesman - MST Heuristik Problem Allgemeine Java-Themen 4
J Traveling Salesman Problem Allgemeine Java-Themen 14
E Java Editor Problem mit 2er Exceptions Allgemeine Java-Themen 12
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
M Salesman Problem - Bruteforce Algorithmus Allgemeine Java-Themen 23
S Methoden Problem mit NullPointerException Allgemeine Java-Themen 9
Javafan02 Problem mit if-clause Allgemeine Java-Themen 17
J Lombok Problem mit Konstruktoren bei Verberbung Allgemeine Java-Themen 1
kodela Event Handling Problem mit der Alt-Taste Allgemeine Java-Themen 16
W Threads Problem Allgemeine Java-Themen 15
D (Verständnis-)Problem mit Unterklasse Allgemeine Java-Themen 4
S Problem mit Generic bei unmodifiableCollection Allgemeine Java-Themen 4
S jserialcomm Problem Allgemeine Java-Themen 1
Flynn Thread-Problem... Allgemeine Java-Themen 2
J Generische Interface - Problem Allgemeine Java-Themen 3
G Problem beim GUI Allgemeine Java-Themen 9
L Applet Problem "security: Trusted libraries list file not found" ? Allgemeine Java-Themen 7
A OOP Problem beim Berechnen der größten Fläche eines Ringes Allgemeine Java-Themen 19
T Problem mit externen Datenbankzugriff über SSH Tunnel Allgemeine Java-Themen 4
F Problem beim Einlesen einer Textdatei Allgemeine Java-Themen 12
S Java OpenOffice Problem mit Windows-Benutzerwechsel Allgemeine Java-Themen 19
K Threads RAM Problem Allgemeine Java-Themen 20
P Operatoren Problem mit Zähler in recursiver Schleife Allgemeine Java-Themen 2
C Int Problem Allgemeine Java-Themen 8
C J2V8 NodeJs Java Bride Problem und Frage!?!? Allgemeine Java-Themen 1
J Problem bei Hashmap Key-Abfrage Allgemeine Java-Themen 4
C Webseiten Programm problem Allgemeine Java-Themen 5
M LocalDate Problem Allgemeine Java-Themen 4
J "Problem Objektorientierung" Allgemeine Java-Themen 20
geekex Problem Meldung! Was tun?! Allgemeine Java-Themen 19
T Klassen Override Problem Allgemeine Java-Themen 7
L Unbekanntes Problem Allgemeine Java-Themen 1
FrittenFritze Problem mit einer JComboBox, Event temporär deaktivieren Allgemeine Java-Themen 11
Blender3D Java Swing Programm Windows 10 Autostart Problem Allgemeine Java-Themen 2
F HTTPS Zertifikat Problem Allgemeine Java-Themen 3
M OpenCV KNearest Problem Allgemeine Java-Themen 0
Tommy Nightmare Project Euler: Problem 22 Allgemeine Java-Themen 2
C Abstrakte Klasse, lokale Variable-Problem Allgemeine Java-Themen 1
N Vererbung Design-Problem mit vorhandenen, von der Klasse unabhängigen Methoden Allgemeine Java-Themen 12
P Eclipse Projekt anlegen macht Problem Allgemeine Java-Themen 1
RalleYTN META-INF/services Problem Allgemeine Java-Themen 3
F Java Mail Problem: Authentifizierung wird nicht immer mitgeschickt Allgemeine Java-Themen 1

Ähnliche Java Themen

Neue Themen


Oben