# JPanel: setOpaque(false) funktioniert nicht



## pc-world (6. Aug 2008)

Ich hab ein Fenster, das so aussieht:






Wenn ich jetzt setOpaque(false) auf Panel A anwende, bleibt das Panel aber immer noch undurchsichtig!

Vielleicht liegt es daran, dass ich nicht die _setBackground()_-Methode verwende, sondern eine Klasse verwende, die _JPanel_ erweitert und mir mit der _paintComponent()_-Methode ein Bild auf den Hintergrund zeichnet:


```
package testPackage;

import java.awt.*;
import java.io.*;
import javax.swing.*;

class GUI_MyJPanel extends JPanel {

	private Image image;

	public GUI_MyJPanel(Image file) {
		image = file;
		repaint();
	}

	public GUI_MyJPanel(String file) {
		this(Toolkit.getDefaultToolkit().getImage(file));
	}

	public GUI_MyJPanel(File file) {
		this(file.toString());
	}

	public void paintComponent(Graphics g) {
		g.drawImage(image, 0, 0, null);
		repaint();
	}
}
```


----------



## L-ectron-X (6. Aug 2008)

Du hast ja immer noch den Fehler in der paintComponent()-Methode, den Marco13 angesprochen hat, im Code...


----------



## SlaterB (6. Aug 2008)

du kannst doch nicht innerhalb von paintComponent repaint() aufrufen..,
sei froh, dass Swing so nett ist, daraus keine Endlosschleife zu machen,

wie im anderen Forum zu lesen ist, funktioniert sowas 'normalerweise',
wenn bei dir nicht, dann musst du den Code dazu posten,
es geht doch wohl um Tab1, also Panel A, dazu schreibst du nix,

idealerweise ein vollständiges kurzes Testprogramm


----------



## Quaxli (6. Aug 2008)

Wie schon im anderen Forum geschrieben: Er malt ein Bild in sein Panel. Wenn das Bild nicht (teilweise) transparent ist, hat setOpaque(..) keine Auswirkung.

<edit>
Hier schon mal ein Lösungsansatz dazu

</edit>


----------



## Guest (7. Aug 2008)

Quaxli hat gesagt.:
			
		

> Wie schon im anderen Forum geschrieben: Er malt ein Bild in sein Panel. Wenn das Bild nicht (teilweise) transparent ist, hat setOpaque(..) keine Auswirkung.



Ich glaube, hier gibt es ein kleines Missverständnis... 

Ich meine folgendes Panel:


----------



## Gast2 (7. Aug 2008)

1. ich hoffe du hast das repaint rausgemacht
2. schicke mal ein bischen code oder ein lauffähiges beispiel wo der effekt vorkommt...


----------



## pc-world (7. Aug 2008)

SirWayne hat gesagt.:
			
		

> 1. ich hoffe du hast das repaint rausgemacht


Hab ich

[quote='SirWayne]2. schicke mal ein bischen code oder ein lauffähiges beispiel wo der effekt vorkommt...[/quote]
Mach ich


----------



## pc-world (7. Aug 2008)

So wie's aussieht, muss ich doch etwas von meinem Code posten...

Wollte gerade eine einfache Beispieldatei erstellen, doch bei der funktioniert es...  :roll:


----------



## pc-world (7. Aug 2008)

Hier meine Klasse:


```
package forumPackage;

import java.io.File;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;

public class OpaqueProblem {
	private ArrayList<GUI_tabs> tabListe = new ArrayList<GUI_tabs>();
	private static final int fensterHoeheStandard = 700;
	private static final int fensterBreiteStandard = 800;
	private JFrame fenster = new JFrame();

	private GUI_MyJPanel ueberschriftPanel;

	private GUI_JTabbedPaneWithCloseIcons tabs = new GUI_JTabbedPaneWithCloseIcons();

	public OpaqueProblem() {
		fenster.setSize(fensterBreiteStandard, fensterHoeheStandard);
		fenster.setLocationRelativeTo(null);

		if (ueberschriftPanel != null) {
			fenster.add(BorderLayout.NORTH, ueberschriftPanel);
		}
		fenster.add(BorderLayout.CENTER, tabs);
	}

	public void addTab(int arrayNr, String titel, JPanel panel,
			boolean closeIcon) {
		tabListe.add(arrayNr, new GUI_tabs(titel, panel, closeIcon));
	}

	public GUI_tabs getTab(int arrayNr) {
		return tabListe.get(arrayNr);
	}

	public void setSichtbar(boolean sichtbar) {
		fenster.setVisible(sichtbar);
	}

	public void schliessenBeimSchliessen() {
		fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	class GUI_tabs {

		private GUI_MyJPanel gesamtPanel;
		private JPanel northPanel = new JPanel();
		private JPanel eastPanel = new JPanel();
		private JPanel centerPanel = new JPanel();

		private GUI_tabs() {
			File bgGesamtpanel = new File(getClass().getResource(
					"bg_gesamtpanel.jpg").getFile());
			bgGesamtpanel = new File(String.valueOf(bgGesamtpanel).replace(
					"%20", " "));
			gesamtPanel = new GUI_MyJPanel(bgGesamtpanel);
			gesamtPanel.repaint();

			centerPanel.setOpaque(false);
		}

		public GUI_tabs(String titel, JPanel panel, boolean closeIcon) {
			this();

			setCenterPanel(panel);
			if (closeIcon) {

				tabs.addTab(titel, gesamtPanel);
			} else {
				tabs.addTabWithoutCloseIcon(titel, gesamtPanel);
			}
		}

		public void setNorthPanel(JPanel panel) {
			JPanel panel2 = new JPanel();
			panel2.setLayout(new GridBagLayout());
			panel2.add(panel);
			gesamtPanel.remove(northPanel);
			northPanel = panel2;
			gesamtPanel.add(BorderLayout.NORTH, northPanel);
			gesamtPanel.validate();
		}

		public void setEastPanel(JPanel panel) {
			JPanel panel2 = new JPanel();
			panel2.setLayout(new GridBagLayout());
			panel2.add(panel);
			gesamtPanel.remove(eastPanel);
			eastPanel = panel2;
			gesamtPanel.add(BorderLayout.EAST, eastPanel);
			gesamtPanel.validate();
		}

		public void setCenterPanel(JPanel panel) {
			JPanel panel2 = new JPanel();
			panel2.setLayout(new GridBagLayout());
			panel2.add(panel);
			gesamtPanel.remove(centerPanel);
			centerPanel = panel2;
			gesamtPanel.add(BorderLayout.CENTER, centerPanel);
			gesamtPanel.validate();
		}

	}

	public static void main(String[] args) {
		OpaqueProblem fenster = new OpaqueProblem();
		fenster.schliessenBeimSchliessen();

		JPanel panel = new JPanel();
		JLabel label = new JLabel("Tab1");
		panel.add(label);
		fenster.addTab(0, "Tab1", panel, false);

		panel.add(new JButton("Tab1"));
		fenster.getTab(0).setCenterPanel(panel);

		fenster.setSichtbar(true);

	}

}
```


----------



## SlaterB (7. Aug 2008)

ohne ein vollständiges Testprogramm ist dein Code so gut wie nutzlos,
es sieht so aus, als wäre gesamtPanel immer noch opaque=true
aber kann auch an tausend anderen Dingen z.b. in der unbekannten Klasse GUI_MyJPanel liegen



```
public class TestGUI
    extends JFrame
{

    public TestGUI()
    {
        JPanel red = new JPanel();
        red.setBorder(BorderFactory.createTitledBorder("red"));
        red.setBackground(Color.RED);
        red.setPreferredSize(new Dimension(100, 100));

        JPanel yellow = new JPanel();
        yellow.setBorder(BorderFactory.createTitledBorder("yellow"));
        yellow.setBackground(Color.YELLOW);
        yellow.setPreferredSize(new Dimension(100, 100));
        yellow.setOpaque(false);

        JPanel blue = new JPanel();
        blue.setBorder(BorderFactory.createTitledBorder("blue"));
        blue.setBackground(Color.BLUE);

        blue.add(red);
        blue.add(yellow);

        add(blue);
        setSize(200, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    public static void main(String[] args)
    {
        new TestGUI();
    }
}
```


----------



## Gast2 (7. Aug 2008)

> So wie's aussieht, muss ich doch etwas von meinem Code posten...
> 
> Wollte gerade eine einfache Beispieldatei erstellen, doch bei der funktioniert es... icon_rolleyes.gif



also hast du da doch die lösung deines problem


----------



## pc-world (7. Aug 2008)

Ich hab die _main()_-Methode mal in folgendes geändert:

```
public static void main(String[] args) {
		OpaqueProblem fenster = new OpaqueProblem();
		fenster.schliessenBeimSchliessen();

		JPanel panel = new JPanel();
		JLabel label = new JLabel("Tab1");
		panel.add(label);
		fenster.addTab(0, "Tab1", panel, false);

		panel.add(new JButton("Tab1"));
		fenster.getTab(0).setCenterPanel(panel);
		fenster.getTab(0).centerPanel.setOpaque(false);

		System.out.println(fenster.getTab(0).centerPanel.isOpaque());

		fenster.setSichtbar(true);
		while (true) {
			System.out.println(fenster.getTab(0).centerPanel.isOpaque());
		}
	}
```

Es wird immer _false _ ausgegeben, aber ich sehe trotzdem was anderes im Fenster...


----------



## pc-world (7. Aug 2008)

SlaterB hat gesagt.:
			
		

> ohne ein vollständiges Testprogramm ist dein Code so gut wie nutzlos,


Ich habe doch ein _vollständiges Testprogramm_ gepostet.



			
				SlaterB hat gesagt.:
			
		

> es sieht so aus, als wäre gesamtPanel immer noch opaque=true


Danke, das ist der Fehler! Werde mich gleich mal auf die Suche machen...



			
				SlaterB hat gesagt.:
			
		

> aber kann auch an tausend anderen Dingen z.b. in der unbekannten Klasse GUI_MyJPanel liegen


Stimmt, die habe ich vergessen, aber so ganz unbekannt ist die Klasse auch nicht... ;-)
http://www.java-forum.org/de/viewtopic.php?p=436076*#435773*

Aber trotzdem nochmal den Code:

```
package forumPackage;

import java.awt.*;
import java.io.*;
import javax.swing.*;

class GUI_MyJPanel extends JPanel {

	private Image image;

	public GUI_MyJPanel(Image file) {
		image = file;
		repaint();
	}

	public GUI_MyJPanel(String file) {
		this(Toolkit.getDefaultToolkit().getImage(file));
	}

	public GUI_MyJPanel(File file) {
		this(file.toString());
	}

	public void paintComponent(Graphics g) {
		g.drawImage(image, 0, 0, null);
		//repaint();
	}
}
```


----------



## SlaterB (7. Aug 2008)

als nächstes fehlt GUI_JTabbedPaneWithCloseIcons usw.,

unsere Definitionen von 'vollständiges Programm' gehen wohl auseinander 
ich kann dein Programm nicht ausführen, insofern bringt der Code nahezu nix,

abgesehen von erschwerten Dingen wie Bilder, die man von der Festplatte laden muss, kannst du selber den Test machen: 
neues Java-Projekt öffnen, geposteten Code reinkopieren, läuft es oder nicht


----------



## pc-world (7. Aug 2008)

SlaterB hat gesagt.:
			
		

> neues Java-Projekt öffnen, geposteten Code reinkopieren, läuft es oder nicht


Wenn du deinen Code meinst, ja, der läuft.







			
				SlaterB hat gesagt.:
			
		

> als nächstes fehlt GUI_JTabbedPaneWithCloseIcons


Die Klasse *GUI_JTabbedPaneWithCloseIcons*:

```
package forumPackage;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
 * A JTabbedPane which has a close ('X') icon on each tab.
 * 
 * To add a tab, use the method addTab(String, Component)
 * 
 * To have an extra icon on each tab (e.g. like in JBuilder, showing the file
 * type) use the method addTab(String, Component, Icon). Only clicking the 'X'
 * closes the tab.
 */
public class GUI_JTabbedPaneWithCloseIcons extends JTabbedPane implements
		MouseListener {
	public GUI_JTabbedPaneWithCloseIcons() {
		super();
		addMouseListener(this);
	}

	public void addTab(String title, Component component) {
		this.addTab(title, component, null);
	}

	public void addTab(String title, Component component, Icon extraIcon) {
		super.addTab(title, new CloseTabIcon(extraIcon), component);
	}

	public void addTabWithoutCloseIcon(String title, Component component) {
		super.addTab(title, component);
	}

	public void mouseClicked(MouseEvent e) {
		try {
			int tabNumber = getUI().tabForCoordinate(this, e.getX(), e.getY());
			if (tabNumber < 0)
				return;
			Rectangle rect = ((CloseTabIcon) getIconAt(tabNumber)).getBounds();
			if (rect.contains(e.getX(), e.getY())) {
				// the tab is being closed
				this.removeTabAt(tabNumber);
			}
		} catch (NullPointerException ex) {
			System.out
					.println("Gewöhnliche Nullpointer-Exception, tritt auf bei Tab ohne Close-Icon");
		}
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}
}

/**
 * The class which generates the 'X' icon for the tabs. The constructor accepts
 * an icon which is extra to the 'X' icon, so you can have tabs like in
 * JBuilder. This value is null if no extra icon is required.
 */
class CloseTabIcon implements Icon {
	private int x_pos;
	private int y_pos;
	private int width;
	private int height;
	private Icon fileIcon = null;

	public CloseTabIcon(Icon fileIcon) {
		this.fileIcon = fileIcon;
		width = 16;
		height = 16;
	}

	public void paintIcon(Component c, Graphics g, int x, int y) {
		this.x_pos = x;
		this.y_pos = y;

		Color col = g.getColor();

		g.setColor(Color.black);
		int y_p = y + 2;

		g.drawLine(x + 1, y_p, x + 12, y_p);
		g.drawLine(x + 1, y_p + 13, x + 12, y_p + 13);
		g.drawLine(x, y_p + 1, x, y_p + 12);
		g.drawLine(x + 13, y_p + 1, x + 13, y_p + 12);
		g.drawLine(x + 3, y_p + 3, x + 10, y_p + 10);
		g.drawLine(x + 3, y_p + 4, x + 9, y_p + 10);
		g.drawLine(x + 4, y_p + 3, x + 10, y_p + 9);
		g.drawLine(x + 10, y_p + 3, x + 3, y_p + 10);
		g.drawLine(x + 10, y_p + 4, x + 4, y_p + 10);
		g.drawLine(x + 9, y_p + 3, x + 3, y_p + 9);
		if (fileIcon != null) {
			fileIcon.paintIcon(c, g, x + width, y_p);
		}
		g.setColor(col);
	}

	public int getIconWidth() {
		return width + (fileIcon != null ? fileIcon.getIconWidth() : 0);
	}

	public int getIconHeight() {
		return height;
	}

	public Rectangle getBounds() {
		return new Rectangle(x_pos, y_pos, width, height);
	}
}
```



			
				SlaterB hat gesagt.:
			
		

> ich kann dein Programm nicht ausführen, insofern bringt der Code nahezu nix,


OK, dann noch das Hintergrundbild...: http://www.abload.de/img/bg_gesamtpanel77f.jpg

Und zu guter letzt... -
- ...den Source-Code zum runterladen!  http://www.uploadarea.de/files/3ylmvydis8mcgpewnlnl5kjbb.zip


----------



## pc-world (7. Aug 2008)

Noch kurz was zum Ausführen:
Man muss die Größe des Fensters ändern, dass das Hintergrundbild angezeigt wird.
(Habe es noch nicht fertiggebracht, die _repaint()_-Methode an der richtigen Stelle einzubauen, sodass sie auch was bringt... )


----------



## SlaterB (7. Aug 2008)

> Wenn du deinen Code meinst

ne, deinen, denn deiner ging ja nicht, sowas solltest du vorher testen

--------

mit Ausprobieren eine Sache von wenigen Minuten,
in der Klasse OpaqueProblem muss das panel aus Zeile 111 auf opaque false gesetzt werden 
sowie centerPanel/ panel2 in Zeile 100,

was hat dich denn nun tagelang davon abgehalten, das selber zu tun?
der anscheinend einzige Versuch von dir in Zeile 60
 centerPanel.setOpaque(false); 
ist erstens ziemlich sinnlos, da du diesen Konstruktor gar nicht verwendest,
außerdem wird centerPanel später mit panel2 überschrieben,
da bringt es mächtig wenig, das vorherigen Panel zu ändern


----------



## pc-world (7. Aug 2008)

SlaterB hat gesagt.:
			
		

> in der Klasse OpaqueProblem muss das panel aus Zeile 111 auf opaque false gesetzt werden


Danke! Jetzt funktioniert alles.

Noch eine kurze Frage:
Wo genau muss die _repaint()_-Methode hin, dass auch gleich der Hintergrund angezeigt wird? (Ohne, dass ich die Größe vom Fenster ändern muss...)
(Hab schon rumprobiert, allerdings ohne Erfolg)


----------



## SlaterB (7. Aug 2008)

ich kenne das Laden von Bildern mit MediaTracker
http://www.tutego.com/java/articles/MediaTracker.html

aber da können andere wohl intelligenteres zu sagen


----------



## Gast2 (7. Aug 2008)

verwende ImageIcon dann müsste es klappen...


----------



## L-ectron-X (7. Aug 2008)

Aber doch nicht für ein Hintergrundbild...
Das Bild am besten mit IOmageIO laden und in der paintComponent()-Methode zeichnen.


----------



## Gast2 (7. Aug 2008)

was spricht gegen?? funktioniert einwandfrei


```
private Image img=new ImageIcon("icon1.png").getImage();
```


----------



## pc-world (8. Aug 2008)

SlaterB hat gesagt.:
			
		

> ne, deinen, denn deiner ging ja nicht, sowas solltest du vorher testen


Hatte ich doch natürlich!


----------



## pc-world (8. Aug 2008)

So eine Klasse habe ich ja schon:

```
package testPackage;

import java.awt.*;
import java.io.*;
import javax.swing.*;

class GUI_MyJPanel extends JPanel {

	private Image image;

	public GUI_MyJPanel(Image file) {
		image = file;
		repaint();
	}

	public GUI_MyJPanel(String file) {
		this(Toolkit.getDefaultToolkit().getImage(file));
	}

	public GUI_MyJPanel(File file) {
		this(file.toString());
	}

	public void paintComponent(Graphics g) {
		g.drawImage(image, 0, 0, null);
	}
}
```

Meine Frage lautet, wo ich die _repaint()_-Methode in der Klasse _OpaqueProblem_ einbauen muss.

Ich habe es schon in _setCenterPanel()_ probiert, allerdings ohne Erfolg:

```
public void setCenterPanel(JPanel panel) {
			JPanel panel2 = new JPanel();
			panel2.setLayout(new GridBagLayout());
			panel2.add(panel);
			gesamtPanel.remove(centerPanel);
			centerPanel = panel2;
			centerPanel.repaint();
			gesamtPanel.add(BorderLayout.CENTER, centerPanel);
			gesamtPanel.validate();
}
```


----------



## SlaterB (8. Aug 2008)

repaint musst du überhaupt nicht aufrufen, insbesondere beim Programmstart VOR setVisible(true) für das JFrame ist das dermaßen sinnloss für jede Art von Zweck..

hast du denn überhaupt die anderen Bild-Laden-Methoden eingebaut/ auprobiert?


----------



## pc-world (8. Aug 2008)

SlaterB hat gesagt.:
			
		

> repaint musst du überhaupt nicht aufrufen, insbesondere beim Programmstart VOR setVisible(true) für das JFrame ist das dermaßen sinnloss für jede Art von Zweck..



Hab das repaint jetzt mal nach _setVisible()_ eingebaut:

```
public static void main(String[] args) {
		OpaqueProblem fenster = new OpaqueProblem();
		fenster.schliessenBeimSchliessen();

		JPanel panel = new JPanel();
		JLabel label = new JLabel("Tab1");
		panel.add(label);
		fenster.addTab(0, "Tab1", panel, false);

		panel.add(new JButton("Tab1"));
		fenster.getTab(0).setCenterPanel(panel);
		fenster.getTab(0).centerPanel.setOpaque(false);

		System.out.println(fenster.getTab(0).centerPanel.isOpaque());

		fenster.setSichtbar(true);
		
		fenster.getTab(0).gesamtPanel.repaint();
	}
```

Allerdings seh ich immer noch keinen Hintergrund.
Erst wenn ich mit dem Cursor die Größe des Fensters ändere.


----------



## pc-world (8. Aug 2008)

Hier mal ein kurzes selbstständiges kompilierbares Beispiel (immer noch mit dem gleichen Bug):

```
package forumPackage;

import java.io.*;
import javax.swing.*;
import java.awt.*;

class OpaqueProblemKSKB {
	public static void main(String[] args) {
		new OpaqueProblemKSKB().los();
	}

	public void los() {
		JFrame fenster = new JFrame("OpaqueProblemKSKB");
		fenster.setSize(500, 500);
		fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		File background = new File(getClass().getResource("bg_gesamtpanel.jpg")
				.getFile());
		background = new File(String.valueOf(background).replace("%20", " "));
		MyJPanel panel = new MyJPanel(background);
		panel.add(new JButton("Button"));
		
		fenster.add(panel);
		fenster.setVisible(true);
		panel.repaint();
	}
}

class MyJPanel extends JPanel {

	private Image image;

	public MyJPanel(Image file) {
		image = file;
		repaint();
	}

	public MyJPanel(String file) {
		this(Toolkit.getDefaultToolkit().getImage(file));
	}

	public MyJPanel(File file) {
		this(file.toString());
	}

	public void paintComponent(Graphics g) {
		g.drawImage(image, 0, 0, null);
	}
}
```

Dann einfach noch irgendeine Datei mit dem Namen _bg_gesamtpanel.jpg_ in den Ordner mitreinpacken (http://www.abload.de/img/bg_gesamtpanel77f.jpg).


----------



## SlaterB (8. Aug 2008)

ich verstehe diese Menschen nicht,
du hast immer noch
// this(Toolkit.getDefaultToolkit().getImage(file));

wenn ich das durch 
 this(new ImageIcon(file).getImage());
oder 
this(ImageIO.read(new File(file)));
ersetze,
was beides hier schon gepostet wurde, dann läufts, 

wie kann man nur fertige Tipps ignorieren, ein KSKB bauen und dann andere die eine Zeile austauschen lassen?
naja, wenns anders nicht geht..


----------

