L'arrière-plan de JPanel
s peut-il être défini sur transparent?
Mon cadre a deux JPanel
s:
Panneau de fonctions chevauche le Panneau d'images. Le Panneau d'images fonctionne comme arrière-plan et charge l'image à partir d'une URL distante.
Sur Panneau de fonctions Je veux dessiner des formes. À présent, Panneau d'image ne peut pas être vu à cause de la couleur d'arrière-plan de {panneaux de fonctions.
J'ai besoin de rendre le {Panneau de fonctions} _ arrière-plan transparent tout en dessinant ses formes et je veux que le {Panneau d'images} _ soit visible (puisqu'il s'agit de la fonction de mosaïque et du cache des images).
J'utilise deux JPanel
's, car je dois séparer l'image et le dessin de forme.
Y a-t-il un moyen pour que Jpanel qui se chevauchent ait un fond transparent?
Vous pouvez également envisager Le panneau de verre , abordé dans l'article Comment utiliser les panneaux de racine . Vous pouvez dessiner votre contenu "Feature" dans la méthode paintComponent()
de la vitre.
Addendum: Travailler avec le GlassPaneDemo , j'ai ajouté une image:
//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);
et modifié la méthode paintComponent()
de la vitre:
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);
}
}
Comme noté ici , les composants Swing doivent respecter la propriété opaque ; Dans cette variante, la ImageIcon
remplit complètement le BorderLayout.CENTER
de la présentation par défaut de l'image.
Appeler setOpaque(false)
sur la JPanel
supérieure devrait fonctionner.
D'après votre commentaire, il semble que la peinture de Swing puisse être cassée quelque part -
Premièrement, vous avez probablement voulu remplacer paintComponent()
plutôt que Paint()
dans le composant dans lequel vous avez remplacé Paint()
.
Deuxièmement - lorsque vous remplacez paintComponent()
, vous voudrez d’abord appeler super.paintComponent()
pour faire tout le travail de peinture Swing par défaut (dont honorer setOpaque()
en est un).
Exemple -
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);
}
}
}
Dans mon cas particulier, c'était plus facile à faire:
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);
J'espère que cela t'aides.
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);
}
J'ai essayé de le faire de cette façon, mais c'est très scintillant
Comme Thrasgod l'a bien montré dans sa réponse, le meilleur moyen consiste à utiliser le composant paintComponent, mais également si le cas est d'avoir un JPanel semi-transparent (ou tout autre composant, réellement) et d'avoir quelque chose de non transparent à l'intérieur. Vous devez également redéfinir la méthode paintChildren et définir la valeur alfa sur 1 . Dans mon cas, j’ai étendu JPanel comme suit:
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
}
Et dans mon projet, je n’ai besoin que d’instancier Jpanel jp = new TransparentJPanel(0.3f, 1.0f);
, si je ne veux que le Jpanel transparent . Vous pouvez aussi manipuler la forme JPanel en utilisant g2d.fillRoundRect
et g2d.drawRoundRect
, mais cela n’entre pas dans le cadre de cette question.