JPanel: setOpaque(false) funktioniert nicht

Status
Nicht offen für weitere Antworten.

pc-world

Bekanntes Mitglied
Ich hab ein Fenster, das so aussieht:
java-transparente6q.png


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:

Code:
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();
	}
}
 
Du hast ja immer noch den Fehler in der paintComponent()-Methode, den Marco13 angesprochen hat, im Code... 🙂
 
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 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:
java_transparent_panyvj.png
 
1. ich hoffe du hast das repaint rausgemacht
2. schicke mal ein bischen code oder ein lauffähiges beispiel wo der effekt vorkommt...
 
So wie's aussieht, muss ich doch etwas von meinem Code posten...

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

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

	}

}
 
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


Code:
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();
    }
}
 
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 😉
 
Ich hab die main()-Methode mal in folgendes geändert:
Code:
	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...
java_transparentm5m.png
 
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:
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();
	}
}
 
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
 
SlaterB hat gesagt.:
neues Java-Projekt öffnen, geposteten Code reinkopieren, läuft es oder nicht
Wenn du deinen Code meinst, ja, der läuft.
java_transparent_slaxn3.png


SlaterB hat gesagt.:
als nächstes fehlt GUI_JTabbedPaneWithCloseIcons
Die Klasse GUI_JTabbedPaneWithCloseIcons:
Code:
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
 
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... 🙂)
 
> 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
 
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)
 
Aber doch nicht für ein Hintergrundbild...
Das Bild am besten mit IOmageIO laden und in der paintComponent()-Methode zeichnen.
 
was spricht gegen?? funktioniert einwandfrei

Code:
private Image img=new ImageIcon("icon1.png").getImage();
 
So eine Klasse habe ich ja schon:
Code:
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:
Code:
		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();
}
 
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?
 
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:
Code:
	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.
 
Hier mal ein kurzes selbstständiges kompilierbares Beispiel (immer noch mit dem gleichen Bug):
Code:
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).
 
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..
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben