Wie lässt sich ein teiltransparentes JPanel erzeugen?

Ein JPanel kann durch die Methode JComponent#setOpaque() entweder opak oder volltransparent gesetzt werden. Möchte man ein teiltransparentes JPanel erzeugen, so gelingt dies durch Erweitern der Klasse und Überschreiben von paintComponent().

Das Beispiel zeigt ein einfaches Fenster auf Basis eines JFrame, in dem zwei teiltransparente Panel geladen werden. Zur Darstellung der Stärke der Transparenz besitzen die Container farbige Hintergründe und zeigen einfache Texte.

Die Zuweisung neuer Farben ist der Weg, die gewünschte Teiltransparenz zu erreichen. Die Klasse Color besitzt Konstruktoren, die neben den Farbwerten auch einen Alpha-Wert entgegennehmen. Der Austausch der ursprünglichen opaken Hintergrundfarbe gegen eine transparente führt zum gewünschten Ziel.

Im Konstruktor der Klasse TransparentPanel wird die Methode initGUI() aufgerufen, die das Fenster der Klasse mit seinen GUI-Elementen erzeugt. Nach dem Setzen der Fenstergröße werden dort zwei Objekte vom Typ TPanel erstellt. Die Klasse ist von JPanel abgeleitet und überschreibt lediglich paintComponent(). Dort wird die Erscheinung der Panel-Objekte durch eine Reihe von Parametern gesteuert, deren Werte dem Konstruktor übergeben und in paintComponent() ausgewertet werden. Zu diesen Parametern zählen jeweils zwei Color-Objekte für die Vorder- und Hintergrundfarbe, die ihrerseits vier float-Parameter besitzen. Der letzte definiert hierbei einen Alphawert zwischen 0 und 1. Ein Wert von 0 bezeichnet dabei die volle Transparenz, 1 die vollständige Opazität.
Alle Parameter werden bei der Objektbildung im Konstruktor der Klasse TPanel an Instanzvariablen übergeben und dann in paintComponent() ausgewertet.
Für die Darstellung der Panel-Objekte auf dem Frame ist es unabdingbar, deren Erscheinungsgröße festzulegen, da ein leeres Panel andernfalls kollabieren würde und so nicht sichtbar wäre. Dies geschieht in initGUI() durch den Aufruf der drei Methoden setPreferredSize(), setMinimumSize() und setSize().

Innerhalb paintComponent() wird zunächst die gleichnamige Methode der Superklasse JPanel aufgerufen, um deren ordnungsgemäße Ausführung sicherzustellen. Dem Graphics-Objekt der Methode werden die teiltransparenten Farben durch Graphics#setColor() übergeben und die Größen der Hintergrundrechtecke berechnet. Nach dem Zeichnen der Fläche wird der Text in der Vordergrundfarbe erzeugt und in einer Schleife mehrfach untereinander gesetzt.

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class TransparentPanel extends JFrame {
    TPanel lowerPanel, upperPanel;

    public TransparentPanel() {
        initGUI();
    }

    private void initGUI() {
        this.setSize(300, 300);

        lowerPanel = new TPanel("Ein Text im unteren Panel",
                new Color(0f, 0f, 1f, 0.5f), new Color(1f, 1f, 0f, 0.6f), 300,
                300, this);
        Dimension ldim = new Dimension(getWidth(), getHeight());
        lowerPanel.setPreferredSize(ldim);
        lowerPanel.setMinimumSize(ldim);
        lowerPanel.setSize(ldim);

        upperPanel = new TPanel("Ein oberer Text", new Color(1f, 0f, 0f, 0.6f),
                new Color(0f, 0f, 0f, 0.4f), 200, 200, this);
        Dimension udim = new Dimension(getWidth() - 60, getHeight() - 60);
        upperPanel.setPreferredSize(udim);
        upperPanel.setMinimumSize(udim);
        upperPanel.setSize(udim);
        
        // Layout
        this.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.NORTHWEST;
        this.add(upperPanel, gbc, 1, 1, 1, 1, this);
        this.add(lowerPanel, gbc, 1, 1, 1, 1, this);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    public void add(Component c, GridBagConstraints constraints, int x, int y,
            int w, int h, Container p) {
        constraints.gridx = x;
        constraints.gridy = y;
        constraints.gridwidth = w;
        constraints.gridheight = h;
        p.add(c, constraints);
    }

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

class TPanel extends JPanel {
    String txt;
    Color fgColor, bgColor;
    int width, height;
    Component parent;

    public TPanel(int width, int height, Component parent) {
        this("", parent.getBackground(), parent.getForeground(), width, height,
                parent);
    }

    public TPanel(String txt, Color bgColor, Color fgColor, int width,
            int height, Component parent) {
        this.txt = txt;
        this.fgColor = fgColor;
        this.bgColor = bgColor;
        this.width = width;
        this.height = height;
        this.parent = parent;
        setOpaque(false);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(bgColor);
        int start = (parent.getWidth() - width) / 2;
        g.fillRect(start, start, width, height);
        g.setColor(fgColor);
        g.setFont(new Font("Verdana", Font.BOLD, 20));
        for (int i = 0; i < 15; ++i) {
            g.drawString(txt + "\n", start + 5, start + 20 + i * 20);
        }
    }
}

Die Methode paintComponent() wird jedes Mal, wenn das Fenster mit seinen Inhalten neu gezeichnet wird aufgerufen, also bei der erstmaligen Darstellung und bei jeder Größenänderung, sodass die in ihr enthaltenen Routinen jedes Mal erneut ausgeführt werden.

In initGUI() werden beide TPanel-Objekte durch ein GridBagLayout im Fenster an die gleiche Position gesetzt, sodass die Teiltransparenz anhand der Mischung der Farben und durch die Überdeckung der Schriften augenfällig wird.

Teiltransparentes Fenster