Hintergrundfarbe von Panels durchsichtig machen

Kann man die Hintergrundfarbe von Panels durchsichtig machen?

Wenn ja, wie?

setOpaque( false ) (oder true, die verwechsle ich immer?)

Funktioniert leider nicht. Ich habe ein Panel (A) auf dem mehrere Panels liegen.
Auf A ist ein Hintergrund, der auch durch die anderen Panels durchscheinen soll.

Schnappschuss:

Bei mir funktioniert es:

 * OpaqueDemo.java
 */
import java.awt.*;
import javax.swing.*;
public class OpaqueDemo extends JFrame {
    private JPanel jPanel1;
    private JPanel jPanel2;
    public OpaqueDemo() {
        jPanel1 = new JPanel();
        jPanel2 = new JPanel();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jPanel1.setBackground(new Color(204, 204, 255));
        jPanel1.setLayout(new GridBagLayout());
        jPanel2.setBorder(BorderFactory.createLineBorder(new Color(0, 0, 0)));
        jPanel2.setOpaque(false);//<-------------------------------------
        jPanel2.setPreferredSize(new Dimension(150, 150));
        jPanel1.add(jPanel2, new GridBagConstraints());
        getContentPane().add(jPanel1, BorderLayout.CENTER);
        setSize(400, 300);
        setLocationRelativeTo(null);
    }
    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                new OpaqueDemo().setVisible(true);
            }
        });
    }
}```

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:


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();
	}
}```

Als allgemeiner Hinweis: Innerhalb der paintComponent ein „repaint()“ aufzurufen, schickt den Event-Dispatch-Thread auf eine laaange Reise die aus ständigem Neuzeichnen besteht…
Auf das beschriebene Problem hat das aber eigentlich keinen Einfluß… :confused:

EDIT: Das beschriebene Panel, mit dem Image, das in den Hintergrund gezeichnet wird, sieht aber vom Zeichnen her (!) grundsätzlich richtig aus… Kannst du ein compilierbares Programm posten, wo der Fehler auftritt?

Auf http://www.java-forum.org/de/viewtopic.php?t=17894#117646 steht:

swing komponenten sind per default auf opaque = false…
für transparenz musst du schon selbst malen…

Selbst malen??? :confused:

Aber wenn er ein Bild auf das Panel malt ist doch klar, daß der Hintergrund nicht durchkommt. setOpaque(…) hin oder her. Da müßte ja dann das Bild, daß er malt zumindest in Teilen transparent sein.

Die Bedeutung der “opaque” Eigenschaft wird häufig mißverstanden. Hier ist die Erklärung:
http://wiki.byte-welt.net/wiki/Malen_in_AWT_und_Swing#Die_Opazit.C3.A4t

Wenn ich’s richtig verstanden habe, geht es um das kleine Panel (das mit dem Tab-Label und dem Tab-Button) - und wenn DAS transparent ist (d.h. wenn bei diesem kleinen Panel setOpaque(false) gemacht wurde) sollte man eigentlich das Bild (vom dahinterliegenden Panel) durchsehen können…

Dann muß uns pcworld nochmal aufschlauen, was jetzt wirklich gemeint ist :smiley:

RICHTIG verstanden!

Dieses Panel meine ich:

Hier mein Code:


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);

	}

}```

Hat sich jetzt erledigt.
S. http://www.java-forum.org/de/viewtopic.php?t=72982&postdays=0&postorder=asc&start=15#436129

Und alles nur, weil du nicht auf uns gehört hast… :stuck_out_tongue_winking_eye:

???

Ich meine, André war von Anfang an der Meinung, dass das mit dem Aufruf von setOpaque() einzustellen geht. Du warst der Meinung, es geht nicht, dabei hast du die Methode offenbar nur an der falschen Stelle aufgerufen.

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

Am besten ist es, die paintComponent()-Methode zum Zeichnen zu überschreiben, so wie du das machst, gefällt mir das gar nicht.
Das Bild solltest du auch schon mit ImageIO einlesen, das ist effizienter und weniger umständlich.

Wie „überschreiben“?