Kann JPanel
s Hintergrund auf transparent gesetzt werden?
Mein Rahmen hat zwei JPanel
s:
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 JPanel
s, da ich die Bild- und Formzeichnung trennen muss.
Gibt es eine Möglichkeit, dass das überlappende Jpanel einen transparenten Hintergrund hat?
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);
}
}
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.
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);
}
}
}
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
(Feature Panel).setOpaque(false);
Hoffe das hilft.
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
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.