Search code examples
javaswingjpaneltranslucency

Translucent components inside JPanel


I have class MyPanel that extends from JPanel. MyPanel class has JLabel component which holds an icon.

My question is how can i paint/render this JLabel component to get translucent effect (see through icon) inside MyPanel class (not create xxxJLabel extends JLabel class and override paintComponents method).

Thank you


Solution

  • One way is to provide a translucent image to the JLabel. That might be done with a standard label, before setIcon() or similar is called, or alternately by extending JLabel and overriding the setIcon() method to do the same.

    E.G. of 2nd technique

    enter image description here

    Code

    import java.awt.*;
    import java.awt.image.*;
    import javax.swing.*;
    import javax.imageio.ImageIO;
    import java.net.URL;
    
    class TransparentIcon {
        public static void main(String[] args) throws Exception {
            String imgURL =
                "http://www.gravatar.com/avatar/" +
                "a1ab0af4997654345d7a949877f8037e";
            final BufferedImage image = ImageIO.read(new URL(imgURL));
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    ImageIcon icon = new ImageIcon(image);
    
                    JPanel  p = new JPanel(new GridLayout(2,3));
                    for (int ii=0; ii<6; ii++) {
                        TransparentLabel tl = new TransparentLabel();
                        tl.setOpacity((ii+1)/6f);
                        tl.setIcon(icon);
                        p.add(tl);
                    }
    
                    JOptionPane.showMessageDialog(null, p);
                }
            });
        }
    }
    
    class TransparentLabel extends JLabel {
    
        float opacity = 1f;
    
        public void setOpacity(float opacity) {
            this.opacity = opacity;
        }
    
        private Icon getTranslucentIcon(Icon icon) {
    
            if (icon!=null) {
                BufferedImage bi = new BufferedImage(
                    icon.getIconWidth(),
                    icon.getIconHeight(),
                    BufferedImage.TYPE_INT_ARGB);
                Graphics2D g = bi.createGraphics();
                AlphaComposite ac = AlphaComposite.getInstance(
                    AlphaComposite.SRC_OVER,
                    opacity);
                g.setComposite(ac);
                icon.paintIcon(this,g,0,0);
                g.dispose();
    
                return new ImageIcon(bi);
            } else {
                return null;
            }
        }
    
        public void setIcon(Icon icon) {
            super.setIcon( getTranslucentIcon(icon) );
        }
    }
    

    Update

    I just wonder how it can be done if i get Graphics of JLabel inside MyPanel class and change its visual appearance?

    LabelRenderTest.java renders a JLabel to a BufferedImage so that it can be used for custom rendering inside the paintComponent(Graphics) method.

    Note though: I don't quite understand what the advantage of the JLabel is in your use-case. I was using it in that example in order to render HTML. If I only had an image, I'd use the image directly (e.g. Graphics.drawImage(Image,int,int,ImageObserver)) and never create the label.