JLayeredPane mit JPanel im Vordergrund, Hintergrundelemente sperren

mabuhay

Bekanntes Mitglied
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
 
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.
Java:
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
Java:
   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.
 
Danke Wladimir für deine Antwort. Ich habe einfach die drei Zeilen
Java:
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
 
Zuletzt bearbeitet:
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.
 
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...
 
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
 
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:

Java:
if (visible) {
		requestFocusInWindow();
}

Funktioniert nun wie gewollt.
 

Zurück
Oben