2010-03-30 6 views
21

Est-ce que le fond JPanel peut être défini sur transparent?Comment définir un fond transparent de JPanel?

Mon cadre est a deux JPanel s:

  • Image Panel et
  • Panel Feature.

Panel Feature est Panneau de chevauchement image. Le Image Panel fonctionne en arrière-plan et charge l'image depuis une URL distante.

Sur Panneau de caractéristiques Je souhaite dessiner des formes. Maintenant Image Panel ne peut pas être vu en raison de couleur de fond du panneau de fonctionnalité.

que je dois faire panneau Feature fond transparent tout en tirant encore ses formes et je veux Image Panel soit visible (car il fait fonction de mosaïque et cache des images).

J'utilise deux JPanel « s, parce que je dois séparer l'image et la forme dessin.

Y a-t-il un moyen pour que le Jpanel qui se chevauche ait un arrière-plan transparent?

+0

JPanel lorsque l'image PNG transparente est chargée, et que vous définissez 'JPanel.setOpaque (false);' elle utilisera la méthode image transparente, sinon elle affichera une image non transparente. – YumYumYum

Répondre

6

Sinon, tenez compte The Glass Pane, discuté dans l'article How to Use Root Panes. Vous pouvez dessiner votre contenu "Feature" dans la méthode paintComponent() du volet de verre.

Additif: Utilisation de l'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é le procédé de vitre paintComponent():

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); 
    } 
} 

image http://i41.tinypic.com/2j0mlv9.png

+2

L'utilisation d'un glasspane ne fonctionnera pas (correctement) sans que setOpaque() (comme décrit dans mon post) ne fonctionne. – Nate

24

Appel setOpaque(false) sur le JPanel supérieur devrait fonctionner.

De votre commentaire, ça sonne comme la peinture Swing peut être cassé quelque part -

d'abord - vous vouliez sans doute de passer outre paintComponent() plutôt que paint() dans tout ce composant que vous avez paint() surchargées dans le

deuxième -. Lorsque vous Remplacez paintComponent(), vous devez d'abord appeler super.paintComponent() en premier pour faire toutes les tâches de peinture Swing par défaut (dont 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); 
     } 
    } 
} 
+0

Je l'ai fait, mais cela n'a pas fonctionné, devrais-je appeler cette fonction dans le constructeur ou dans la méthode paint()? – Imran

+0

@Imran - Dans le constructeur ou dans la méthode paint() de quoi? Le panneau lui-même? voir la mise à jour ... – Nate

+0

Très bien, merci Nate, ça a marché. avant d'appeler super.paint(), je place Opaque sur false et ensuite, avant de dessiner ma forme, je place Opaque sur true. merci buddy – Imran

2
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 faites comme ça, mais c'est très flicker

4
(Feature Panel).setOpaque(false); 

Espérons que cela aide.

5

Dans mon cas particulier, il était plus facile de le faire:

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

invalide - avec opaque à true, le panneau garantit le remplissage en remplissant complètement son arrière-plan (ce qui n'est pas le cas avec un fond transparent) – kleopatra

+0

ce que vous dites est vrai, mais pour le but désiré du design, définissez n'importe quelle couleur avec alpha 0 De plus, il n'a pas spécifié s'il devait avoir accès aux composants du panneau de fond, comme je l'ai compris, le panneau qui se trouve au niveau inférieur sert simplement à définir une image de fond. – Ordiel

0

Comme Thrasgod correctement montré dans sa réponse, la meilleure façon est d'utiliser le paintComponent, mais aussi si le cas est d'avoir une semi-transparente JPanel (ou tout autre composant, vraiment) et avoir quelque chose de pas transparent à l'intérieur. Vous devez également remplacer la méthode paintChildren et définir la valeur d'alfa à 1. Dans mon cas, je tendis les JPanel comme ça:

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 ne dois instancier Jpanel jp = new TransparentJPanel(0.3f, 1.0f);, si je veux seulement Jpanel transparent. Vous pouvez également manipuler la forme JPanel en utilisant g2d.fillRoundRect et g2d.drawRoundRect, mais cela ne fait pas partie de la portée de cette question.

Questions connexes