it-swarm.com.de

Wie kann ich einen transparenten Hintergrund von JPanel einstellen?

Kann JPanels Hintergrund auf transparent gesetzt werden?

Mein Rahmen hat zwei JPanels: 

  • Image Panel und
  • Funktionsbereich.

Feature Panel überlappt Image Panel . Das Image Panel arbeitet als Hintergrund und lädt ein Bild von einer Remote-URL. 

Auf Feature-Panel möchte ich Formen zeichnen. Jetzt kann Image Panel aufgrund der Hintergrundfarbe von Feature Panel nicht angezeigt werden. 

Ich muss den Hintergrund von Feature Panel transparent machen, während ich seine Formen noch zeichne, und ich möchte, dass Image Panel sichtbar ist (da es eine Kachel- und Zwischenspeicherfunktion für Bilder gibt). 

Ich verwende zwei JPanels, da ich die Bild- und Formzeichnung trennen muss.

Gibt es eine Möglichkeit, dass das überlappende Jpanel einen transparenten Hintergrund hat?

24
Imran

Alternativ können Sie The Glass Pane betrachten, das im Artikel How Root Panes verwenden . Sie können Ihren "Feature" -Inhalt in der paintComponent() -Methode der Glasscheibe zeichnen.

Nachtrag: Beim Arbeiten mit GlassPaneDemo habe ich ein Bild hinzugefügt:

//Set up the content pane, where the "main GUI" lives.
frame.add(changeButton, BorderLayout.SOUTH);
frame.add(new JLabel(new ImageIcon("img.jpg")), BorderLayout.CENTER);

und änderte die paintComponent() Methode der Glasscheibe:

protected void paintComponent(Graphics g) {
    if (point != null) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setComposite(AlphaComposite.getInstance(
            AlphaComposite.SRC_OVER, 0.3f));
        g2d.setColor(Color.yellow);
        g2d.fillOval(point.x, point.y, 120, 60);
    }
}

enter image description here

Wie bereits erwähnt hier , müssen Swing-Komponenten die ndurchsichtige Eigenschaft berücksichtigen; In dieser Variante füllt ImageIcon das BorderLayout.CENTER des Standardlayouts des Rahmens vollständig aus.

7
trashgod

Das Aufrufen von setOpaque(false) auf der oberen JPanel sollte funktionieren.

Aus Ihrem Kommentar klingt es, als könnte das Swing-Malen irgendwo kaputt sein - 

Zuerst wollten Sie wahrscheinlich paintComponent() anstelle von Paint() in der Komponente überschreiben, in der Sie Paint() überschrieben haben. 

Zweitens: Wenn Sie paintComponent() überschreiben, sollten Sie zuerst super.paintComponent() aufrufen, um alle Standard-Swing-Paintings zu erledigen (wovon setOpaque() ausgezeichnet wird).

Beispiel -

import Java.awt.Color;
import Java.awt.Graphics;

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


public class TwoPanels {
    public static void main(String[] args) {

        JPanel p = new JPanel();
        // setting layout to null so we can make panels overlap
        p.setLayout(null);

        CirclePanel topPanel = new CirclePanel();
        // drawing should be in blue
        topPanel.setForeground(Color.blue);
        // background should be black, except it's not opaque, so 
        // background will not be drawn
        topPanel.setBackground(Color.black);
        // set opaque to false - background not drawn
        topPanel.setOpaque(false);
        topPanel.setBounds(50, 50, 100, 100);
        // add topPanel - components Paint in order added, 
        // so add topPanel first
        p.add(topPanel);

        CirclePanel bottomPanel = new CirclePanel();
        // drawing in green
        bottomPanel.setForeground(Color.green);
        // background in cyan
        bottomPanel.setBackground(Color.cyan);
        // and it will show this time, because opaque is true
        bottomPanel.setOpaque(true);
        bottomPanel.setBounds(30, 30, 100, 100);
        // add bottomPanel last...
        p.add(bottomPanel);

        // frame handling code...
        JFrame f = new JFrame("Two Panels");
        f.setContentPane(p);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(300, 300);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    // Panel with a circle drawn on it.
    private static class CirclePanel extends JPanel {

        // This is Swing, so override Paint*Component* - not Paint
        protected void paintComponent(Graphics g) {
            // call super.paintComponent to get default Swing 
            // painting behavior (opaque honored, etc.)
            super.paintComponent(g);
            int x = 10;
            int y = 10;
            int width = getWidth() - 20;
            int height = getHeight() - 20;
            g.drawArc(x, y, width, height, 0, 360);
        }
    }
}
26
Nate

In meinem speziellen Fall war das einfacher:

 panel.setOpaque(true);
 panel.setBackground(new Color(0,0,0,0,)): // any color with alpha 0 (in this case the color is black
5
Ordiel
(Feature Panel).setOpaque(false);

Hoffe das hilft.

4
Edesa
 public void paintComponent (Graphics g)
    { 
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.0f)); // draw transparent background
     super.paintComponent(g);
    ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f)); // turn on opacity
    g.setColor(Color.RED);
    g.fillRect(20, 20, 500, 300);
     } 

Ich habe es auf diese Weise versucht, aber es ist sehr flackernd

2
Imran

Wie Thrasgod in seiner Antwort richtig gezeigt hat, ist es am besten, die paintComponent zu verwenden, aber auch, wenn der Fall ein halbtransparentes JPanel (oder wirklich eine andere Komponente) ist und etwas nicht transparent ist. Sie müssen auch die paintChildren-Methode überschreiben und den alfa-Wert auf 1 setzen. In meinem Fall habe ich das JPanel so erweitert:

public class TransparentJPanel extends JPanel {

private float panelAlfa;
private float childrenAlfa;

public TransparentJPanel(float panelAlfa, float childrenAlfa) {
    this.panelAlfa = panelAlfa;
    this.childrenAlfa = childrenAlfa;
}

@Override
public void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(getBackground());
    g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setComposite(AlphaComposite.getInstance(
            AlphaComposite.SRC_OVER, panelAlfa));
    super.paintComponent(g2d);

}

@Override
protected void paintChildren(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(getBackground());
    g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setComposite(AlphaComposite.getInstance(
            AlphaComposite.SRC_ATOP, childrenAlfa));

    super.paintChildren(g); 
}
 //getter and setter
}

Und in meinem Projekt muss ich nur Jpanel jp = new TransparentJPanel(0.3f, 1.0f); instanziieren, wenn ich nur das Jpanel transparent machen will ..__ Sie könnten sich auch mit der JPanel-Form mit g2d.fillRoundRect und g2d.drawRoundRect herumschlagen, aber das ist nicht im Rahmen dieser Frage.

0
emportella