# Swing: ContentPane von JDialog ist transparent (Fehler)



## Kaffeemaschinist (12. Mrz 2009)

Ich hab versucht, einen einfachen Frame/Dialog zu erstellen, in dem nichts anderes angezeigt werden soll als ein JProgressBar und eine Nachricht. Nun hab ich das Stück Code mal darauf abstrahiert, dass nur eine Nachricht im Frame angezeigt wird.

Ergebnis: Der Dialog/Frame wird zwar angezeigt, die ContentPane bleibt aber komplett transparent (sieht aus, wie wenn manchmal irgendwas abschmiert, dann sieht man den Hintergrund, den das Fenster beim Abschmieren angenommen hat, auch die gesamte Zeit durch).


```
private static 		JDialog					PROGRESS_FRAME = null;

public static void showProgressWindow () {

		if (PROGRESS_FRAME==null) {
			
			Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 
			
			PROGRESS_FRAME = new JDialog(parent,"Work in progress");
			
			JPanel panel = new JPanel(new FlowLayout());
			panel.setOpaque(true);
			
			panel.add(new JLabel("Working, stand by."));
			PROGRESS_FRAME.setContentPane(panel);
			PROGRESS_FRAME.setSize(new Dimension(400,400));
		}
		
		PROGRESS_FRAME.setVisible(true);
		PROGRESS_FRAME.repaint();
		
}
```

Habe die Vermutung, es könnte an Mischung AWT/Swing liegen, aber nichts derartiges gefunden. Auch ein Repaint() bzw. toFront() hat nichts gebracht, der PROGRESS_FRAME bleibt inaktiv.

Weiß da jmd eine Vorgehensweise?

Grüße,
Kaffeemaschinist


----------



## Wildcard (12. Mrz 2009)

Eine ProgressBar heißt doch normalerweise, das du eine Long Running Operation ausführen möchtest. Meine Vermutung ist: du führst die Operation im UI Thread aus und blockierst ihn damit. In der FAQ ist ein Beitrag zu ProgressBars


----------



## Kaffeemaschinist (12. Mrz 2009)

Ne, hier ist ja noch gar kein Progressbar drin, den hab ich mal rausgenommen, um die Fehler einzugrenzen. Außerdem wird der ProgressBar eh im Indeterminate-Modus starten, es soll sich also nur etwas "bewegen".

Im Grunde läuft es etwa folgendermaßen:

```
showProgressWindow();
LongRunningOperation();
hideProgressWindow();
```

Ich hab die LROp mal auskommentiert und dort ein langes Thread-Sleep eingebaut. Das Problem ist nach wie vor das Gleiche: Der Frame mal seine ContentPane nicht, sondern lässt die darunter liegenden Information durchschimmern.
Zusatzinfo: Der Aufruf des PPOGRESS_FRAME (jetzt JDialog) geschieht aus einem anderen JFrame heraus, aber daran sollte es doch nicht liegen, oder?


----------



## Wildcard (12. Mrz 2009)

Klar ist das Problem nach wie vor das gleiche. Ob sleep, oder rechnen, beides blockiert den UI Thread. Die Long Running Operation muss in einem eigenen Thread laufen (siehe FAQ zu Progress Bars).


----------



## slawaweis (12. Mrz 2009)

Kaffeemaschinist hat gesagt.:


> Ergebnis: Der Dialog/Frame wird zwar angezeigt, die ContentPane bleibt aber komplett transparent (sieht aus, wie wenn manchmal irgendwas abschmiert, dann sieht man den Hintergrund, den das Fenster beim Abschmieren angenommen hat, auch die gesamte Zeit durch).


hinter dem ContentPane liegt das RootPane und dahinter der Dialog selber, d.h. es wäre egal, ob der ContentPane transparent wäre. Es klingt ganz nach einem Thread-Problem. Ich würde versuchen zum Test den Dialog einmal nicht Modal zu machen und einmal ohne Parent zu starten. Wenn der Dialog danach normal erscheint, kann man weiter das Problem ergründen.


```
PROGRESS_FRAME.setVisible(true);
		PROGRESS_FRAME.repaint();
```

der Dialog blockiert bereits in setVisible(true), repaint() wird also erst nach dem Beenden des Dialogs aufgerufen.

Slawa


----------



## Wildcard (12. Mrz 2009)

slawaweis hat gesagt.:


> Es klingt ganz nach einem Thread-Problem.


Er gab sich die antwort doch schon selbst:
[HIGHLIGHT="Java"]showProgressWindow();
LongRunningOperation();
hideProgressWindow();[/HIGHLIGHT]
Ergebnis: zwischen show und hide ist die GUI Blockiert und verarbeitet keine Events mehr.


----------



## slawaweis (12. Mrz 2009)

Wildcard hat gesagt.:


> Ergebnis: zwischen show und hide ist die GUI Blockiert und verarbeitet keine Events mehr.


ich habe es so verstanden, dass sein PROGRESS_FRAME auch blokiert ist:



Kaffeemaschinist hat gesagt.:


> Ergebnis: Der Dialog/Frame wird zwar angezeigt, die ContentPane bleibt aber komplett transparent (sieht aus, wie wenn manchmal irgendwas abschmiert, dann sieht man den Hintergrund, den das Fenster beim Abschmieren angenommen hat, auch die gesamte Zeit durch).



Slawa


----------



## Wildcard (12. Mrz 2009)

Ist er ja auch, es gibt nur einen UI Thread. Hat allerdings nichts mit Modalität zu tun, daher wird der vorgeschlagene Test kein Resultat erbringen.


----------



## Kaffeemaschinist (13. Mrz 2009)

Nochmal zur Klarstellung: Ich lasse keine Operation laufen. Mittlerweile hab ich das Problem soweit eingedämmt, dass ich wirklich nur einen Dialog mit einem Label drin anzeige. Trotzdem ist die RootPane voll transparent.


----------



## Verjigorm (13. Mrz 2009)

Ziemlich lernresistent


----------



## Kaffeemaschinist (13. Mrz 2009)

```
if (isKonstruktives(Verjigorm.getKommentar())) {
	schreibeInThread();
} else {
	KommentarUmleitung("/dev/null");
}
```

Das Problem lag anscheinend daran, dass das Fenster, bevor es gezeichnet wurde, von einer Zeichen-Aktion in einem Frame des aktuellen UI Thread verdrängt wurde.

Jetzt zum eigentlichen: (ich vermute mal, das passt noch zum Topic, wenn nicht, ansagen und ich eröffne es an unter neuem Thread und entfern es hier)
Ich führe eine längere Datenbankaktion durch, die ich aus einer Swing-GUI starte und deren Resultat natürlich angezeigt werden soll. Während die DB-Aktion leiert, soll der Nutzer durch einen Progressbar (einfach nur ein bewegtes Objekt, muss nicht durch den Worker geupdatet werden) beschäftigt sein, soll also nicht weiter in der GUI herumklicken "dürfen". Letzteres geht, wie vorgeschlagen durch den modalen Dialog, problemlos.

Dazu meine Idee:


```
MySwingWorker worker = new MySwingWorker(Object[] params);
	worker.execute(); /* läuft in einem Extra-Thread */
	showModalDialogWithProgressBar(); 
	
	boolean success = false;
	try {
		/* Problem: ich warte blockierend, und der ModalDialog wird nicht mehr neu gezeichnet */
		success = worker.get();
	} catch (Exception e) {
		OMFG!!!
	}
	/* hier liegt das Ergebnis an, also den ModalDialog "abschießen" */
	closeModalDialogWithProgressBar();
	
	...
```

Nun läuft der Worker im Hintergrund, beim Abwarten des Endes des Workers hab ich aber wieder eine Blockade, die vermutlich dafür sorgt, dass der ModalDialog nicht geupdatet werden kann (passiert z.B. beim Verschieben des Inhalts).

Sollte ich besser mit publish() arbeiten und dort abfangen, wenn der Worker durch ist? Oder gibt es dafür insgesamt eine viel einfachere Herangehensweise?


----------

