# RootPane bzw CardLayout Transparent machen



## BlubBlub (25. Jul 2011)

Hi,

Ich habe ein JRootPane mit einem CardLayout versehen.
Im CardLayout befinden sich zwei JPanels.
Eines davon, das CustomPanel beinhaltet ein JLabel mit einem Text.

Das JRootPane wurde in ein JPanel das als riesiges Hauptpanel dient 
integriert.

Nun das Problem: 
Ich möchte, dass wenn das CustomPanel angezeigt wird nur der Text
zu sehen ist der im JLabel drin ist. Der komplette Hintergrund soll aber 
Transparent sein, so dass man den Hintergrund von dem riesigen
Hauptpanel sieht. 
Doch ich schaffe es nicht den Hintergrund transparent zu bekommen.
Der Hintergrund ist die ganze Zeit grau.

Meine Vermutung: 
Hauptvermutung: Es liegt an dem contentPane des JRootPane. Content Panes kann
man nicht auf durchsichtig setzen.

Weitere Vermutung: Entweder man kann den Hintergrund des JRootPanes nicht auf durchsichtig
setzen oder man kann den Hintergrund des CardLayouts nicht auf durchsichtig setzen.



```
public class MyJFrame extends JFrame
{
	Container contentPane;
	public MyJFrame()
	{
		super();
		
		contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(new MainPanel());
		
		setSize(700, 500);
		setVisible(true);
	}
}
```


```
public class MainPanel extends JPanel
{
	public MainPanel()
	{
		super();
		setLayout(new FlowLayout());
		setBackground(Color.CYAN);
		add(new StandardRootPane());
	}

}
```


```
public class StandardRootPane extends JRootPane
{
	private Container contentPane;
	private CardLayout cardLayout;

	
	public StandardRootPane()
	{
		super();
		
		DefaultPanel defaultPanel = new DefaultPanel();
		CustomPanel customPanel = new CustomPanel();

		cardLayout = new CardLayout();
		contentPane = getContentPane();
		contentPane.setLayout(cardLayout);
		contentPane.add(defaultPanel, "defaultPanel");
		contentPane.add(customPanel, "customPanel");
		showCard("customPanel");
		
		this.setOpaque(false);
	}
	
	public void showCard(String cardName)
	{
		cardLayout.show(contentPane, cardName);
	}
}
```


```
public class CustomPanel extends JPanel
{
	private JLabel textLabel;
	
	public CustomPanel()
	{
		super();
		setLayout(new BorderLayout());
		setOpaque(false);
		
		textLabel = new JLabel("textLabel", JLabel.CENTER);
		textLabel.setForeground(Color.BLUE);
		textLabel.setOpaque(false);
		add(textLabel);
	}
}
```


```
public class DefaultPanel extends JPanel
{
	JLabel fieldLabel;
	JLabel flagEventLabel;
	
	public DefaultPanel()
	{
		setLayout(new GridLayout(2,1));
		setOpaque(false);
		
		fieldLabel = new JLabel("fieldname", JLabel.CENTER);
		fieldLabel.setOpaque(true);
		
		flagEventLabel = new JLabel("#flagname", JLabel.CENTER);
		flagEventLabel.setOpaque(true);
		
		add(fieldLabel);
		add(flagEventLabel);
	}
}
```


----------



## Michael... (25. Jul 2011)

Grundsätzlich fragwürdig ist: Warum verwendets Du hier JRootPane?? Warum nicht einfach JPanel bzw. alles direkt auf MainPanel platzieren?


BlubBlub hat gesagt.:


> Meine Vermutung:
> Hauptvermutung: Es liegt an dem contentPane des JRootPane. Content Panes kann
> man nicht auf durchsichtig setzen.


Direkt nicht, aber da es i.d.R ein JPanel ist: doch ;-)


BlubBlub hat gesagt.:


> Weitere Vermutung: Entweder man kann den Hintergrund des JRootPanes nicht auf durchsichtig
> setzen oder man kann den Hintergrund des CardLayouts nicht auf durchsichtig setzen.


Der Hintergrund ist Grau weil, die ContentPane des JRootPane Grau ist. Das CardLayout ist keine Komponente sondern ein Layout - kann daher weder durchsichtig, noch undurchsichtig sein ;-)

Aber wie gesagt: Wenn Du keinen guten Grund hast JRootPane zu verwenden, dann verwende es auch nicht.


----------



## BlubBlub (25. Jul 2011)

Das was ich hier zeige ist nur eine stark vereinfachte Version des Programms 
an dem ich grad sitze.

Ich verwendet das JRootPane auf Grund der GlassPane die dort angeboten wird.
In meinem eigentlichen Programm kann ich nämlich Button und Slider etc in das
JRootPane aufnehmen.
Der User hat die Wahl zwischen zwei Modi. Im Modus Animation kann er die Buttons
etc betätigen.
Im Modus Edit kann der User die Buttons nicht nutzen, die GlassPane fängt alle Events ab.
Zudem werden im Modus Edit auf der GlassPane Handles gezeichnet mit denen man das
JRootPane vergrößern und verkleinern. Des Weiteren ist es in diesem Modus möglich das JRootPane
beliebig zu verschieben.


----------



## Michael... (25. Jul 2011)

BlubBlub hat gesagt.:


> Ich verwendet das JRootPane auf Grund der GlassPane die dort angeboten wird.
> In meinem eigentlichen Programm kann ich nämlich Button und Slider etc in das
> JRootPane aufnehmen.
> Der User hat die Wahl zwischen zwei Modi. Im Modus Animation kann er die Buttons
> ...


Und dafür muss die RootPane transparent sein? Dann bleibt ja nur die Möglichkeit die ContentPane transparent zu setzen bzw. eine transparente Komponent als ContentPane zu nutzen.

Warum nimmst Du nicht die GlassPane des JFrames?


----------



## BlubBlub (26. Jul 2011)

Also in meinem eigentlichen Programm habe ich dem JFrame eine JPanel mainpanel hinzugefügt das als Hauptfläche dient. Dieses mainpanel beinhaltet eine JLayeredPane. Die JLayeredPane hat
drei Ebenen. in der obersten Ebene befinden sich die JRootPanes. In der mittleren Ebene befindet sich ein JPanel das als Wallpaper fungiert, auf das ich also verschieden Bilder setzen kann. Und die unterste Ebene dient dazu damit ich die RootPane "unsichtbar" machen kann wenn der User es will, dann werden die JRootPanes einfach in die untersteEbene gelegt.

Jedes JRootPane kann Buttons oder auch Bilder oder Text oder JRadioButtons beinhalten.
Man könnte also als Wallpaper ein Bild einer Handyoberfläche laden. und jedes JRootPane würde
dann ein JButton beinhalten oder jedes RootPane würde zwei JButtons beinhalten oder wie der Benutzer es auch immer will. Nun würde man die JRootPanes so positionieren dass sie an der Position der Handytasten des Wallpapers liegen. 

In meinem Programm beinhaltet die JRootPane also die Bedienelement und man kann das JRootPane vergrößern und verkleiner und verschieben. Damit kann man also das JRootPane genau so über dem Wallpaper positionieren das sie über den Handytasten des Wallpapers liegen. Zudem kann man die größe so anpassen, dass die JRootpanes so groß sind wie die Handytasten. 
Da beim verschieben und vergrößern nciht ausversehen ein Button gedrückt werden kann, kommt hier die GlassPane zum Einsatz. Diese fängt die Events ab. Und zudem nutze ich die GlassPane praktischersweise zum zeichnen der Handles. 

Der Benutzer soll natürlich auch auf das HandyWallpaper im Bereich des Handybildschirms einfach Text drüberlegen können, und daher brauche ich ne Möglichkeit wie ich die ContentPane des JRootPane durchsichtig machen kann, damit man eben den Handybildschirm nicht verdeckt mit der Hintergrundfarbe des contentPane.

Die GlassPane des JFrame nehme ich deshalb nicht, weil sie sich ja auf das komplete Fenster beziehen würde, aber wie grad beschrieben möchte ich nur dass die einzelnen JRootPanes davon betroffen sind. Würde ich die GlassPane des JFrame aktivieren so könnte ich meine JRootPanes nicht mehr verschieben, vergrößern etc. Diese Option würde bei meinem Programm nicht funktionieren.

"Dann bleibt ja nur die Möglichkeit die ContentPane transparent zu machen" , genau nach dieser Möglichkeit suche ich aber ich weiß nicht wie das geht. Das was ich bisher so gefunden habe deutet eher daraufhin dass dies nicht möglich ist. Was mich allerings auch ein wenig verweundert, denn wenn man eine eigene JLayerPane erstellt, so kann man diese auf durchsichtig stellen, obwohl diese ja ebenfalls eine contentPane beinhaltet.


----------



## Michael... (26. Jul 2011)

BlubBlub hat gesagt.:


> "Dann bleibt ja nur die Möglichkeit die ContentPane transparent zu machen" , genau nach dieser Möglichkeit suche ich aber ich weiß nicht wie das geht. Das was ich bisher so gefunden habe deutet eher daraufhin dass dies nicht möglich ist.


Die ContentPane einer JRootPane ist meistens ein JPanel oder zumindest von JComponent abgeleitet, daher kann man diese ohne Probleme transparent setzen. Wenn man nicht weiß wie, war ja mein Vorschlag einfach eine transparente Komponente (z.B. JPanel) als ContentPane zu setzen.


BlubBlub hat gesagt.:


> Was mich allerings auch ein wenig verweundert, denn wenn man eine eigene JLayerPane erstellt, so kann man diese auf durchsichtig stellen, obwohl diese ja ebenfalls eine contentPane beinhaltet.


Wäre mir neu, wenn JLayeredPane eine ContentPane nutzt??


----------



## Michael... (26. Jul 2011)

Was Du meintest war wahrscheinlich, dass JRootPane eine JLayeredPane nutzt, um die verschiedenen Ebenen u.a. auch dessen ContentPane zu verwalten.


----------



## BlubBlub (26. Jul 2011)

> mein Vorschlag einfach eine transparente Komponente (z.B. JPanel) als ContentPane zu setzen.



Jau das ist DIE Lösung. Danke für den Hinweis. Das funktioniert und hat mir grad unheimlich viel Arbeit erspart. Hatte schon überlegt mein Konzept zu verändern, was mich ziemlich zurückgeworfen hätte und das neue Konzept wäre nicht so toll gewesen wie das bisherige. Danke nochmals.





> Was Du meintest war wahrscheinlich, dass JRootPane eine JLayeredPane nutzt, um die verschiedenen Ebenen u.a. auch dessen ContentPane zu verwalten.


Hier ist ein Bild vom Aufbau der JRootpane zu sehen:
Java Platform SE 6

Ich hatte da wohl was falsch verstanden, ich dachte nämlich, dass jede JLayeredPane egal ob sie  bereits in einem JRootPane integriert ist oder ob man selbst eine JLayereadPane instanziiert immer auch eine contentPane besitzt. 
Ich habe mir dass immer so vorgestellt, dass die JLayeredPane wie so eine Sammlung Klarsichtsfolien ist in die man Komponenten einfügen kann, aber das es immer eine ContentPane also Standardmäßig immer eine Folie gibt die eine Grundkomponente besitzt, was ja falsch ist. Die Vorstellung der Klarsichtsfolien ist ja schon richtig nur ebend war es von mir falsch zu denken, dass es Standardmäßig eine contentPane auch drin gibt.


----------

