50

I am trying to add an image to a JButton and I'm not sure what I'm missing. When I run the following code the button looks exactly the same as if I had created it without any image attribute. Water.bmp is in the root of my project folder.

ImageIcon water = new ImageIcon("water.bmp");
    JButton button = new JButton(water);
    frame.add(button);
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
kevinstueber
  • 2,926
  • 3
  • 26
  • 26
  • That **should** work...can you try using the `URL` form of the `ImageIcon` constructor and see what it does? It might be that it can't find the image file for some reason. – Cameron Skinner Jan 26 '11 at 04:39
  • Yes, it's working now. No changes to the code. Thanks everyone for your suggestions. – kevinstueber Jan 28 '11 at 04:38

11 Answers11

79

I think that your problem is in the location of the image. You shall place it in your source, and then use it like this:

  JButton button = new JButton();
  try {
    Image img = ImageIO.read(getClass().getResource("resources/water.bmp"));
    button.setIcon(new ImageIcon(img));
  } catch (Exception ex) {
    System.out.println(ex);
  }

In this example, it is assumed that image is in src/resources/ folder.

Oldalf
  • 31
  • 7
Rogach
  • 26,050
  • 21
  • 93
  • 172
  • 3
    I dont know why but this didnt work either for me. I even build a function which searched the wanted files in the directory and found them - still no icons. So, i just use the line: button1.setIcon("path/pic.png"); - this runs. Any ideas why? – Yannic Hansen Oct 24 '14 at 14:59
18

@Rogach

and you may like to add:

// to remote the spacing between the image and button's borders
button.setMargin(new Insets(0, 0, 0, 0));
// to add a different background
button.setBackground( ... );
// to remove the border
button.setBorder(null);
ungalcrys
  • 5,242
  • 2
  • 39
  • 23
7

It looks like a location problem because that code is perfectly fine for adding the icon.

Since I don't know your folder structure, I suggest adding a simple check:

File imageCheck = new File("water.bmp");

if(imageCheck.exists()) 
    System.out.println("Image file found!")
else 
    System.out.println("Image file not found!");

This way if you ever get your path name wrong it will tell you instead of displaying nothing. Exception should be thrown if file would not exist, tho.

Kamila Szewczyk
  • 1,874
  • 1
  • 16
  • 33
donnyton
  • 5,874
  • 9
  • 42
  • 60
6

You put your image in resources folder and use follow code:

JButton btn = new JButton("");
btn.setIcon(new ImageIcon(Class.class.getResource("/resources/img.png")));
ParisaN
  • 1,816
  • 2
  • 23
  • 55
3
public class ImageButton extends JButton {

    protected ImageButton(){
    }

    @Override
        public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        Image img = Toolkit.getDefaultToolkit().getImage("water.bmp");

        g2.drawImage(img, 45, 35, this);
        g2.finalize();
    }
}

OR use this code

class MyButton extends JButton {

    Image image;
    ImageObserver imageObserver;


    MyButtonl(String filename) {
            super();
            ImageIcon icon = new ImageIcon(filename);
            image = icon.getImage();
            imageObserver = icon.getImageObserver();
        }

     public void paint( Graphics g ) {
            super.paint( g );
            g.drawImage(image,  0 , 0 , getWidth() , getHeight() , imageObserver);
        }
    }
prolink007
  • 33,872
  • 24
  • 117
  • 185
KFC
  • 541
  • 1
  • 4
  • 17
  • 6
    Too complex. There is a built-in mechanism for adding icons to buttons, why create additional problems? – Rogach Jan 26 '11 at 04:33
  • @Rogach Not specifically for this question, but in my case it was useful to have further control on where the image was placed in the button. – Aldo Canepa Feb 23 '21 at 18:45
2
buttonB.setIcon(new ImageIcon(this.getClass().getResource("imagename")));
MathieuF
  • 3,130
  • 5
  • 31
  • 34
2

I did only one thing and it worked for me .. check your code is this method there ..

setResizable(false);

if it false make it true and it will work just fine .. I hope it helped ..

Dan
  • 31
  • 1
  • 1
    the frame (?) being resizable or not is irrelevant – kleopatra Dec 22 '11 at 16:39
  • Yes you maybe right .. but when you have a Borderlayout and then you make this statement.. you restrict the frame .. thus if you make true it will give your frame the space. – Dan Dec 24 '11 at 15:25
1
//paste required image on C disk
JButton button = new JButton(new ImageIcon("C:water.bmp");
1

This code work for me:

    BufferedImage image = null;
    try {
        URL file = getClass().getResource("water.bmp");
        image = ImageIO.read(file);
    } catch (IOException ioex) {
        System.err.println("load error: " + ioex.getMessage());
    }
    ImageIcon icon = new ImageIcon(image);
    JButton quitButton = new JButton(icon);
CamelTM
  • 1,225
  • 12
  • 17
1

For example if you have image in folder res/image.png you can write:

try
{
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    InputStream input = classLoader.getResourceAsStream("image.png");
    // URL input = classLoader.getResource("image.png"); // <-- You can use URL class too.
    BufferedImage image = ImageIO.read(input);

    button.setIcon(new ImageIcon(image));
}
catch(IOException e)
{
    e.printStackTrace();
}

In one line:

try
{
    button.setIcon(new ImageIcon(ImageIO.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("image.png"))));
}
catch(IOException e)
{
    e.printStackTrace();
}

If the image is bigger than button then it will not shown.

Oxygenium
  • 71
  • 1
  • 2
  • 7
0

eclipse example:
After reading the above, it still took me more research to understand, where and how to place image resources, using eclipse. The outcome: in eclipse you need to store images underneath any "Source Folder" (such as "src") or below in a "Folder".
You create both by right-clicking on your project, "New"->"Source Folder" or "New"->"Folder". Any folder name is fine. Examples for "<Source Folder>/<image Folder>" are "src/images" or "resource/img".
Here's some fully functioning sample code, which expects two button images, "Button-Image-Up.png" and "Button-Image-Down.png" in folder "images":

import javax.swing.JDialog;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class ImageButtonDlg extends JDialog {
    // define button images and fall-back text
    private static gstrTxt="<Button Fall-back Text>"; // in case image does not load
    private static String gstrImgUp="Button-Image-Up.png";   // regular image
    private static String gstrImgDown="Button-Image-Down.png"; // button pressed image
    private static String gstrImgFolder="images";   // image folder, "/images" is also fine
    public static void main(String[] args) {
        ImageButtonDlg dialog = new ImageButtonDlg();
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setVisible(true);
    }
    /**
     * Create the dialog.
     */
    public ImageButtonDlg() {
        initializeDialog();
    }
    /**
     * Create a new ImageIcon from an image resource. 
     * The input can be: 
     * - an image file name, e.g. <image.png> 
     * - a relative path, e.g. <image/image.png>
     * - an absolute path, e.g. </home/user/dev/image.png>
     * In eclipse, images can be stored below any project "Source folder", 
     * such as "src".
     * ├── src
     * │   ├── img1.png
     * │   └── images
     * │       └── img2.png
     * ├── resources
     * │   ├── img3.png
     * │   └── images
     * │       └── img4.png
     * └── img5.png
     *  In above example img1.png to img4.png are found by 
     *  image file name or relative path
     *  However, img5 is stored in the project root folder and 
     *  needs an absolute path.
     *    
     * @param strImagePath - image filename, absolute path or relative path
     * @return new ImageIcon or 'null' if load fails
     */    
    public static ImageIcon getResourceImageIcon(String strFilepath) {
        ClassLoader loader = null;
        URL url = null;
        Image img=null;
        ImageIcon imgIcon=null;
        loader = ImageButtonDlg.class.getClassLoader();
        System.out.println(loader.toString());
        try {  // file location: <a relative path>
            url = loader.getResource("images/"+strFilepath);
            if(url==null) {
                System.out.printf("ImageButtonDlg.class.getResource(%s)=>null\n", "images/"+strFilepath);
            }
        } catch (Exception e0) {
            e0.printStackTrace();
        }
        if(url==null) {
            try {  // file location: <image filename>
                url = loader.getResource(strFilepath);
                if(url==null) { 
                    System.out.printf("Util.class.getResource(%s)=>null\n", strFilepath);
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
        try {
            img = ImageIO.read(url);
        } catch (Exception e2) {
            e2.printStackTrace();
            System.exit(0);
        }
        if (img!=null){
            imgIcon = new ImageIcon(img);
        }
        return imgIcon;
    }
    /**
     * Create JButton with Image
     * In case Image load fails, we create a JButton with text
     * @param strImgPath - path to Image
     * @param strAltText - fall-back text
     * @return
     */
    public static JButton getNewJButtonWithImageIcon(String strImgPath, String strAltText) {
        JButton btnReturn = null;
        ImageIcon imgIcon = getResourceImageIcon(strImgPath);
        if (imgIcon!=null){
            btnReturn = new JButton(imgIcon);
        }
        else {
            btnReturn = new JButton(strAltText);
        }
        return btnReturn;
    }
    /**
     * Image button was pressed, display a message box
     */
    private void actionImageButtonPressed() {
        try {
            JOptionPane.showMessageDialog(null, "Image Button was pressed", "Info", JOptionPane.INFORMATION_MESSAGE);
        }
        catch (Exception e) {
            ; // ignore
        }
    }
    /**
     * Initialize the dialog
     * add a button panel and the image button to the window/content pane
     */
    private void initializeDialog()
    {
        this.setTitle("Image Button Example");
        this.setResizable(false);
        this.setBounds(200, 200, 699, 601);
        JPanel panelButton = new JPanel();
        panelButton.setLayout(new FlowLayout(FlowLayout.RIGHT)); // all buttons in a row
        getContentPane().add(panelButton, BorderLayout.SOUTH); // button pane at the bottom of the window
        // create the Image Button
        JButton btnImageButton = getNewJButtonWithImageIcon(gstrImgUp, gstrTxt);
        btnImageButton.setToolTipText("<Explain what pressing the Button does>");
        btnImageButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                actionImageButtonPressed();// The Action
            }
        });
        // load button image when button clicked/released
        btnImageButton.addMouseListener((MouseListener) new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                btnImageButton.setIcon(getResourceImageIcon(gstrImgDown));              
            }
            public void mouseReleased(MouseEvent e) {
                btnImageButton.setIcon(getResourceImageIcon(gstrImgUp));
            }
        });
        btnImageButton.setActionCommand("ImageButtonAction");
        // add button to button panel
        panelButton.add(btnImageButton);
    }
}

Have Fun!
Volker Fröhlich
P.S.:
Perhaps someone can share additional practical experience.

  • In eclipse "WindowBuilder Editor" such image buttons are shown, but they cannot be accessed - is there some workaround?
  • What is the NetBeans approach, if any different?