Swing GUI Sperren mit GlassPane

Status
Nicht offen für weitere Antworten.

hdi

Top Contributor
Hey,

ich bin vor einigen Tagen auf ein cooles Tutorial im Netz gestoßen. Die haben dort ein JFrame GlassPane modifiziert, sodass es sich halbtransparent über die GUI legt, und eine Message anzeigt, während die GUI gesperrt sein soll.

Leider hab ich's nicht gebookmarkt und auch nach 30 min googlen mit allem was ich noch aus dem Beitrag wusste, hat mich diesen nicht wieder finden lassen 🙁

Jetzt wollte ich es auf eigene Faust versuchen, aber ich scheiter schon am normalen GlassPane. Ich hatte jetzt mal auf meinem Frame folgendes getan:

Java:
setGlassPane(new MyGlassPane());

Java:
class MyGlassPane extends JPanel{
  public MyGlassPane(){
     setOpaque(true);
     setBackground(new Color(150,150,150,100));
     setSize(500,500) // zum test erstmal
  }
}

Aber wenn ich dann

Java:
getGlassPane().setVisible(true);

aufrufe, ist das Teil nicht transparent.

Desweiteren weiss ich noch dass im Tutorial auch alle Events von Maus etc. vom GlassPane "aufgefressen" wurden. Irgendwas mit consumeEvents() oder so, aber ich finde die Methode nicht..

Könnt ihr mir also bitte erklären, wie man sowas macht?

Danke
 
Hey, danke für den Link.
Aber irgendwie krieg ich's nicht hin:

Java:
public class GUI extends JFrame {

	public GUI() {
                setGlassPane(new MyGlassPane());

		pack();
		setLocationRelativeTo(null);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	public void lock() {
		getGlassPane().setVisible(true);
		getGlassPane().requestFocusInWindow();
	}

	public void unlock() {
		getGlassPane().setVisible(false);
	}

	class MyGlassPane extends JPanel {

		public MyGlassPane() {
			setOpaque(true);
			setBackground(new Color(255, 0, 0, 50));

			addKeyListener(new KeyListener() {
				public void keyPressed(KeyEvent e) {
					e.consume();
				}

				public void keyTyped(KeyEvent e) {
				}

				public void keyReleased(KeyEvent e) {
					e.consume();
				}
			});
		}
	}
}

...und zwar ist das Teil einfach nicht transparent. Die Farbe sieht zwar je nach alpha-Wert anders aus (wird halt blasser je niedriger alpha ist), aber man sieht dahinter nicht meine Fenster-Inhalte (die hab ich jetzt hier nur zu Demo-Zwecken weggelassen, in Wirklichkeit habe ich natürlich Komponenten in meinem ContentPane).

Was mach ich falsch?
 
Naja, ne ganz ausgefuchste Methode: Füge folgendes in deine MyGlassPane ein:
Java:
        @Override
        public void paintComponent(Graphics g) {
            setOpaque(true);
        	super.paintComponent(g);
            setOpaque(false);
        }

Ja ich weiss, scheusslich, aber funktioniert bei mir. Ich versuch mal herauszufinden, was genau das Problem ist.
 
Versuch's mal so:
Java:
    class MyGlassPane extends JPanel {
        public MyGlassPane() {
            setOpaque(false);
            setBackground(new Color(255, 0, 0, 50));
            addKeyListener(new KeyListener() {
                public void keyPressed(KeyEvent e) {
                    e.consume();
                }
                public void keyTyped(KeyEvent e) {
                }
                public void keyReleased(KeyEvent e) {
                    e.consume();
                }
            });
            setFocusTraversalKeysEnabled(false);
        }
        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(getBackground());
            g.fillRect(0, 0, getSize().width, getSize().height);
        }
    }
Das Problem ist, daß man bei Transparenz immer [c]setOpaque(false)[/c] setzen muss, damit der RepaintManager weiss, daß er zuerst die dahinterliegende Komponente malen muß.
 
Zuletzt bearbeitet:
Wenn du setOpaque(false) aufrufst, dann wird der Background halt nicht mehr gezeichnet. Jetzt weiss ich halt nicht, ob deine GlassPane ganz einfach ein Rechteck zeichnen soll, das könntest du ja dann auch selber mit g.fillRect(...).

Wenn du aber Komponenten auf der GlassPane hast, die transparent sein sollen, musst du paint in der GlassPane überschreiben:
Java:
        @Override
        public void paint(Graphics g) {
        	BufferedImage image = new BufferedImage(getWidth(),getHeight(),BufferedImage.TYPE_INT_ARGB);
        	Graphics2D ig = (Graphics2D) image.getGraphics();
        	super.paint(ig);
        	Graphics2D g2 = (Graphics2D) g.create();
        	g2.setComposite(AlphaComposite.SrcOver.derive(.5f));
        	g2.drawImage(image,0,0,this);
        	g2.dispose();
        }
Und damit der Hintergrund gezeichnet wird, musst die setOpaque(false) auf der Glasspane aufgerufen werden.
 
Ah okay, also nur damit ich mir das richtig merke:

setOpaque(false) ist nötig bei Transparenz. Aber es deaktiviert gleichzeitig den Background, deshalb muss ich den per Hand in der paintComponent malen?

Hoffe ich hab das richtig verstanden. Funktionieren tut's zumindest!

Vielen Dank 😉

edit: Ach eine Frage noch: MouseEvents muss ich nicht consumen?
 
Zuletzt bearbeitet:
Status
Nicht offen für weitere Antworten.

Zurück
Oben