HOWTO · Java

How to Create Image Icons in Java

This tutorial demonstrates how to create image icons in Java.

On this page

In Swing, ImageIcon represents an image that you can paint in a component or attach to a JButton. The examples below show both approaches in a window when you run them with --show in a working graphical session. They create images in memory; for image files, use a path or classpath resource that the application can access.

Paint an Image with ImageIcon in Java

To paint an icon in a custom panel, load or create the ImageIcon, set the panel’s preferred size from the icon dimensions, and override paintComponent. Call super.paintComponent(g) before paintIcon(this, g, x, y) so Swing can prepare the panel before drawing. This example creates a small image in memory and starts GUI setup on Swing’s event dispatch thread. Run it without arguments to paint safely in headless mode; pass --show in a working graphical session to display the panel in a frame:

Run this example:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main {
  private static class IconPanel extends JPanel {
    private final ImageIcon icon;

    IconPanel(ImageIcon icon) {
      this.icon = icon;
      setPreferredSize(new Dimension(icon.getIconWidth(), icon.getIconHeight()));
    }

    @Override
    protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      icon.paintIcon(this, g, 0, 0);
    }
  }

  public static void main(String[] args) {
    boolean showWindow = args.length > 0 && "--show".equals(args[0]);
    if (!showWindow) {
      System.setProperty("java.awt.headless", "true");
    }

    BufferedImage source = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
    Graphics2D sourceGraphics = source.createGraphics();
    sourceGraphics.setColor(Color.BLUE);
    sourceGraphics.fillRect(0, 0, 16, 16);
    sourceGraphics.dispose();

    ImageIcon icon = new ImageIcon(source);
    SwingUtilities.invokeLater(() -> {
      if (showWindow) {
        JFrame frame = new JFrame("Paint an ImageIcon");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new IconPanel(icon));
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
      }
      System.out.println("Icon size: " + icon.getIconWidth() + "x" + icon.getIconHeight());
    });
  }
}
Icon size: 16x16

The panel uses the icon’s width and height, and paintComponent draws it at the top-left corner. Run without arguments, the program only creates the icon in headless mode and prints its size; the icon is painted in the panel only when you run with --show in a graphical session. To load an image file instead, construct the icon with a path such as new ImageIcon("delftstack.jpg"); put that file in the application’s working directory or provide the correct path. A missing or unreadable file does not produce the intended icon, so confirm the path from the process’s working directory. In a packaged application, a classpath resource is often more reliable than a working-directory-relative path. This example uses an in-memory image and does not depend on that external file.

Add ImageIcon to Java Buttons

Pass an ImageIcon to a JButton constructor to show an image on a button. This example creates three in-memory icons and adds their buttons to a JPanel with a FlowLayout. Run it without arguments to build the buttons safely in headless mode; pass --show in a working graphical session to display them in a frame:

Run this example:

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main {
  private static ImageIcon makeIcon(Color color) {
    BufferedImage image = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
    image.setRGB(8, 8, color.getRGB());
    return new ImageIcon(image);
  }

  public static void main(String[] args) {
    boolean showWindow = args.length > 0 && "--show".equals(args[0]);
    if (!showWindow) {
      System.setProperty("java.awt.headless", "true");
    }

    SwingUtilities.invokeLater(() -> {
      JButton facebookButton = new JButton(makeIcon(Color.BLUE));
      JButton twitterButton = new JButton(makeIcon(Color.CYAN));
      JButton emailButton = new JButton(makeIcon(Color.RED));
      JPanel buttonPanel = new JPanel(new FlowLayout());
      buttonPanel.add(facebookButton);
      buttonPanel.add(twitterButton);
      buttonPanel.add(emailButton);

      if (showWindow) {
        JFrame frame = new JFrame("ImageIcon Buttons");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(buttonPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
      }

      System.out.println("Buttons created: "
          + facebookButton.getIcon().getIconWidth() + ", "
          + twitterButton.getIcon().getIconWidth() + ", "
          + emailButton.getIcon().getIconWidth());
    });
  }
}
Buttons created: 16, 16, 16

For image files, replace each makeIcon(...) call with an icon such as new ImageIcon("facebook.png"), new ImageIcon("twitter.png"), or new ImageIcon("email.png"). Keep those files at the paths the application uses, or load them as classpath resources, and verify that each path resolves from the application’s working directory. The FlowLayout arranges the three buttons in a row inside the panel, which is added to the frame for display. The sample keeps the Facebook, Twitter, and email button tasks separate from painting an icon in a custom panel.