3

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

mKorbel
  • 109,525
  • 20
  • 134
  • 319
MinhHoang
  • 681
  • 3
  • 9
  • 22

1 Answers1

6

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.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • hi you misunderstood my idea! From inside MyPanel class I want to set Component JLabel to be translucent by invoking method JLabel.getGraphics() then doing translucent stuff here – MinhHoang Aug 20 '11 at 17:51
  • 1
    Perhaps, but your idea is just silly. Never call `getGraphics()` (unless you *really* know what you are doing). Also, you are confusing the strategy with the goal. I still don't understand the goal because you have yet to state it clearly. You keep focusing on how you want to achieve the goal (i.e. the flawed strategy). – Andrew Thompson Aug 20 '11 at 18:00
  • @Final: I agree strongly with Andrew -- you don't want to use the Graphics object of a component obtained via getGraphics. For one, it won't persist on redraws. If I were you, I'd go with Andrew's suggestions (1+). – Hovercraft Full Of Eels Aug 20 '11 at 18:03
  • Thank you! I just wonder how it can be done if i get Graphics of JLabel inside MyPanel class and change its visual apperance? – MinhHoang Aug 20 '11 at 18:54
  • hmmm.. dont really understand the problem nor the sugested solutions: all that's needed is a transparent _icon_, right? Dont see any need to subclass any _component_ - a utility containing the icon- transparentizing code is enough, anyLabel.setIcon(transparentize(myIcon)). My missing something is a not-zero probability, as the solution comes from @Andrew :-) What am I missing? – kleopatra Aug 21 '11 at 09:30
  • @kleopatra Hey, I can't really say I understand this question either. I was just taking a few 'stabs in the dark' because I was bored & there was an opportunity for screen shots. ;) – Andrew Thompson Aug 21 '11 at 09:58
  • hach ... lame excuse for unnecessary subclassing :-) – kleopatra Aug 21 '11 at 10:03