arcy
arcy

Reputation: 13123

Want a JLabel with an image that has a transparent background

I use this icon for a JLabel in a JTable's custom renderer. When the row in the table is selected, the icon background shows up white.

I've used paint.net to create a green triangle, and set its background to white with an alpha of 255. That's the image I use in this code to create an IconImage for the JLabel; I use varying widths for the icon for external reasons. Here's an example program showing what is done:

package spacecheck.images;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * represents an icon used in the directory tree; handles 'expanded' and
 * 'unexpanded' directories as well as indentation representing different
 * levels.
 * @author rcook
 *
 */
public class TreeIconExample
{
  public static int UNEXPANDED = 1;
  public static int EXPANDED = 2;

  @SuppressWarnings({"unused"})
  private void say (String msg) { System.out.println(msg); }

  private static ImageIcon expandedIcon = null;
  private static ImageIcon unexpandedIcon = null;
  private static int       iconHeight = 0;
  private static int       iconWidth  = 0;

  private static ArrayList<ImageIcon> cachedExpandedIcons = new ArrayList<ImageIcon>();
  private static ArrayList<ImageIcon> cachedUnexpandedIcons = new ArrayList<ImageIcon>();

  static
  {
    expandedIcon = new ImageIcon(TreeIconExample.class.getResource("images/Expanded.GIF"));
    unexpandedIcon = new ImageIcon(TreeIconExample.class.getResource("images/Unexpanded.GIF"));
    iconHeight = unexpandedIcon.getIconHeight();
    iconWidth =  unexpandedIcon.getIconWidth();
  }

  public TreeIconExample()  {  }

  public static void main(String ... arguments)
  {
    JFrame frame = new JFrame("icon test");
    frame.setBackground(Color.blue);
    JLabel label = new JLabel("background test");
    label.setBackground(Color.magenta);
    TreeIconExample treeIcon = new TreeIconExample();
    ImageIcon icon = treeIcon.getIcon(2, false);
    label.setIcon(icon);
    frame.add(label);
    frame.pack();
    frame.setVisible(true);
  }

  /**
   * return the icon for an expanded or unexpanded level
   * @param int level of folder relative to other levels displayed;
   * starts at 0 and increases with depth
   * @param boolean indicates whether this level is expanded or not.
   * @return ImageIcon appropriate for expansion flag and level.
   */
  public ImageIcon getIcon(int level, boolean expanded)
  {
    ImageIcon result = null;

    // generate this icon and store it in the cache before returning it.
    ImageIcon baseIcon = unexpandedIcon;
    if (expanded) { baseIcon = expandedIcon; }
    int iconH = iconHeight;
    int iconW = iconWidth*(level+1);

    BufferedImage bufferedImage = new BufferedImage(iconW,iconH,BufferedImage.TYPE_INT_ARGB);
    Graphics g = bufferedImage.getGraphics();

    g.fillRect(0, 0, iconW, iconH);
    g.drawImage(baseIcon.getImage(), iconWidth*level, 0, null);
    result = new ImageIcon(bufferedImage);

    return result;
  }
}

And here is my result:

enter image description here

what I would like to do is eliminate the white portion of the icon; I'd like that to be transparent, so the background of the JLabel shows through. I don't know why neither magenta nor blue show up in this program; if someone cares to tell me that, I'd appreciate it. But the transparent background on the image is the main thing I'm trying to figure out.

Upvotes: 3

Views: 11277

Answers (4)

Jack&#39;
Jack&#39;

Reputation: 2518

As you are using Graphics, I think what you were looking for was this :

Graphics g = bufferedImage.getGraphics();
Graphics2D g2d = (Graphics2D) graphics;
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));

You can choose your opacity level changing the value 0.3f between 0 and 1.

Upvotes: 0

kleopatra
kleopatra

Reputation: 51525

the transparent background on the image is the main thing

The reason it's not transparent is that you are explicitly filling it with the default color which is non-transparent :-)

Graphics g = bufferedImage.getGraphics();
say("" + g.getColor());
g.fillRect(0, 0, iconW, iconH);

output:

java.awt.Color[r=255,g=255,b=255]

So either don't fill, or use a fully/partly transparent Color.

I don't know why neither magenta nor blue show up in this program; if someone cares to tell me that, I'd appreciate it

  • (already answered in earlier posts) magenta is not showing because the label is !opaque by default: meaning that its background is not filled with its background color
  • blue is not showing because you set it to the frame which is covered by its contentPane: by default, the latter is a plain JPanel which opacity defaults to true, that is it fills its area with its background

To see the blue, either set it as background color to the contentPane or change its opacity:

frame.getContentPane().setBackground(Color.blue);
// or
frame.setBackground(Color.YELLOW);
((JComponent) frame.getContentPane()).setOpaque(false);

Upvotes: 5

NeplatnyUdaj
NeplatnyUdaj

Reputation: 6242

I think you should use a rendering hint for the Graphics2D of the buffered image:

Graphics2D g = bufferedImage.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);

Also, why do you have a fillRect there? It won't be transparent I guess.

EDIT: After trying to run the code, only removing fillRect is enough to fix the white rectangle problem:

enter image description here

NOTE: The images I used were gifs created in gimp.

Upvotes: 1

Ozan
Ozan

Reputation: 206

Set your Label to opaque

label.setOpaque(true). If it doesn't work. Use a PNG file without background.

If it still doesn't work. You can try different approaches ( like making a custom label class which overrides paintComponent and paints a triangle ).

Upvotes: 1

Related Questions