2010-03-30 28 views
21

Can JPanel s ¿establecer el fondo como transparente?Cómo establecer un fondo transparente de JPanel?

mi cuerpo es tiene dos JPanel s:

  • Image Panel y
  • panel distintivo.

Panel de funciones es la superposición de Panel de imágenes. Image Panel funciona como fondo y carga imágenes desde una URL remota.

En Feature Panel Quiero dibujar formas. Ahora Image Panel no se puede ver debido a Feature Panel's color de fondo.

Necesito hacer función de panel de fondo transparente tiempo que se extraen sus formas y quiero Image Panel sea visible (ya que está haciendo el embaldosado y la memoria caché función de las imágenes).

Estoy usando dos JPanel, porque necesito separar el dibujo de la imagen y la forma.

¿Hay alguna manera de que el jpanel superpuesto tenga un fondo transparente?

+0

JPanel cuando se carga una imagen PNG transparente, y establece 'JPanel.setOpaque (false);' usará el método transparente de la imagen, de lo contrario, mostrará una imagen no transparente. – YumYumYum

Respuesta

6

alternativa, considere The Glass Pane, discutido en el artículo How to Use Root Panes. Puede dibujar su contenido "Característica" en el método paintComponent() del panel de vidrio.

Adición: Trabajar con el GlassPaneDemo, añadí una imagen:

/* 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); 

y alterado el método de la luna de vidrio 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

El uso de un cristal no funcionará (correctamente) sin setOpaque() (como se describe en mi publicación) funcionando. – Nate

24

Llamar setOpaque(false) en la parte superior JPanel debería funcionar.

Desde su comentario, parece que la pintura oscilación se puede romper alguna parte -

En primer lugar - es probable que desearan invalidar paintComponent() en lugar de paint() en cualquier componente que tiene paint() anulados a

En segundo lugar -. Cuando sobreescriba paintComponent(), primero deberá llamar al super.paintComponent() para hacer todas las cosas predeterminadas de la pintura Swing (de las cuales honrar a setOpaque() es una).

Ejemplo -

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

Lo hice, pero no funcionó, ¿debo llamar a esta función en el constructor o en el método paint()? – Imran

+0

@Imran - En el constructor o en el método paint() de qué? El panel en sí? ver respuesta actualizada ... – Nate

+0

Bien, gracias Nate, eso funcionó. antes de llamar a super.paint() establezco Opaque en falso y luego, antes de dibujar mi forma, configuro Opaque en verdadero. gracias amigo – 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); 
    } 

he tratado de hazlo de esta manera, pero es muy parpadeante

4
(Feature Panel).setOpaque(false); 

Espero que esto ayude.

5

En mi caso particular, que era más fácil de hacer esto:

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

que no es válido: con opaco a verdadero, el panel garantiza que el relleno llene completamente su fondo (lo que no ocurre con un fondo transparente) – kleopatra

+0

lo que diga es cierto, pero para el propósito deseado de diseño, establezca cualquier color con alfa 0 al trabajo, además no especificó si necesita tener acceso a los componentes del panel de fondo, ya que entendí que el panel que está en el nivel inferior es solo para establecer una imagen de fondo. – Ordiel

0

Como Thrasgod mostró correctamente en su respuesta, la mejor manera es utilizar el paintComponent, pero también si el caso es tener un semi transparente JPanel (o cualquier otro componente, realmente) y tener algo no transparente dentro. Usted tiene que anular también el método paintChildren y establecer el valor alfa a 1. En mi caso he ampliado los JPanel por el estilo:

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 
} 

Y en mi proyecto sólo necesito para crear una instancia Jpanel jp = new TransparentJPanel(0.3f, 1.0f);, si sólo la quiero Jpanel transparente. También podría interferir con la forma de JPanel usando g2d.fillRoundRect y g2d.drawRoundRect, pero no está dentro del alcance de esta pregunta.