# JLayeredPane mit JPanel im Vordergrund, Hintergrundelemente sperren



## mabuhay (28. Sep 2011)

Hallo wieder mal

Ich versuche mit Hilfe einer JLayeredPane eine durchsichtige graue Fläche über den gesamten Bereich eines JFrames zu legen, damit ich die Eingabe im JFrame sperren kann und Informationen als Popup anzeigen kann. Dies funktioniert auch ganz gut, die graue durchsichtige Fläche hab ich und kann auch Elemente darauf legen.

Mein Problem ist nun nur noch dass ich immer noch durch die graue Fläche "durchklicken" kann, also ich kann die Elemente dahinter noch bedienen. Gibt es irgend eine Möglichkeit dies zu verhindern? Ich weiss dass man sowas mit der GlassPane machen könnte, die wäre aber natürlich dann ganz im Vordergrund, also noch vor der grauen Fläche.

mfg


----------



## Wladimir (28. Sep 2011)

Hier ein Beispiel von einem Panel welches gegen Mouse und Key Events blockt und sich leicht verfärbt anzeigt. Es kümmert sich auch um die richtige Größe.

```
class MyEventCatcher extends JPanel implements ComponentListener
	{
		public MyEventCatcher()
		{
			setOpaque(false);
			enableEvents(AWTEvent.MOUSE_EVENT_MASK);
			setFocusable(true);
			setFocusCycleRoot(true);
		}
		
		@Override
		public void paint(Graphics g)
		{
			super.paint(g);
			g.setColor(new Color(255,0,0,25));
			g.fillRect(0, 0, getWidth(), getHeight());
		}

		@Override
		public void componentResized(ComponentEvent e)
		{
			this.setSize(e.getComponent().getSize());
		}

		@Override
		public void componentMoved(ComponentEvent e)
		{
		}

		@Override
		public void componentShown(ComponentEvent e)
		{
		}

		@Override
		public void componentHidden(ComponentEvent e)
		{
		}
	}
```
Einfügen z.B. mit

```
MyEventCatcher catcher = new MyEventCatcher();
   frame.getLayeredPane().add(catcher, JLayeredPane.MODAL_LAYER);
   frame.addComponentListener(catcher);
```
Die Layer Ebene je nach Bedarf anpassen.
Dein Popup mußt du um eine Ebene höher einfügen.


----------



## bERt0r (28. Sep 2011)

Erm was soll so ein EventCatcher bringen? mach doch einfach setEnabled(false)

edit: Wenn du mit "Informationen als Popup anzeigen" meinst, dass du einen JDialog aufrust, kannst du den auch einfach Modal machen, dann kann man auch nix mehr ändern im Frame. How to Make Dialogs (The Java™ Tutorials > Creating a GUI With JFC/Swing > Using Swing Components)


----------



## mabuhay (1. Okt 2011)

Danke Wladimir für deine Antwort. Ich habe einfach die drei Zeilen

```
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
setFocusable(true);
setFocusCycleRoot(true);
```
zu meinem Popup-Panel welches über den anderen liegt hinzugefügt, und es funktioniert wie gewünscht 

EDIT:
Ich habe jetzt nur noch das Problem, dass ein Button der auf dem Layer hinter dem Popup liegt noch auf Key-Events reagiert, ich also mit TAB zwischen den Buttons wechseln kann und mit der LEERTASTE diese auch anwählen kann...

@bERt0r
Wenn ich setEnable(false) verwenden wollte müsste ich dies ja für jedes Element unter dem Popup-Panel anwenden.
-> "Note: Disabling a component does not disable its children."

mfg


----------



## bERt0r (2. Okt 2011)

> Wenn ich setEnable(false) verwenden wollte müsste ich dies ja für jedes Element unter dem Popup-Panel anwenden.


Dann machst du das halt für die Kindelemente, ist doch kein Problem. Selbst wenn du nicht wüsstest was für Elemente das sind, kannst du dir noch immer einen 10 Zeiler schreiben, der den Component Tree durchgeht.


----------



## mabuhay (3. Okt 2011)

Ja das stimmt. Aber was ist wenn eines der Kindelemente schon auf setEnabled(false) ist? Dann gehe ich den component-tree beim schliessen des Popups wieder durch und setzte alle auf setEnabled(true), aber müsste mir auch noch merken welche vorher schon auf "false" waren, oder welche vielleicht in der zwischenzeit auf "false" gesetzt wurden...


----------



## vanny (3. Okt 2011)

Naja merken musst du dir nur die Komponenten, die enabled waren, denn die musst du wieder zurücksetzen. Und das bekommt man mit nem 10-Zeiler hin.

Gruß Vanny


----------



## mabuhay (3. Okt 2011)

Die welche enabled waren, und auch die welche während dem offenen popup enabled wurden...

Habs jetzt so gelöst: Die drei vorher genannten Zeilen im Konstruktor des Popup-Panels welches über alle Komponenten gezeichnet wird. Dann in der setVisible()-Methode des Panels folgendes:


```
if (visible) {
		requestFocusInWindow();
}
```

Funktioniert nun wie gewollt.


----------

