Search code examples
javaswingjbutton

How do I change the image on a JButton when clicked?


    JButton lunarButton = new JButton(new ImageIcon("assets/Buttons/moon.png"));
    lunarButton.setActionCommand("switch");
    c.gridwidth=1;
    c.gridy = 0;
    searchArea.add(lunarButton, c);

.

public void actionPerformed(ActionEvent ev)
{
    int count = 1;
    String action = ev.getActionCommand();

    if("switch".equals(action))
    {           
        ImageIcon sun = new ImageIcon("assets/sun.png");
        ImageIcon moon = new ImageIcon("assets/moon.png");

        changeLunar();
        count++;
        if (count % 2 == 0)
        {
             lunarButton.setIcon(sun);
        }
        else
        {
             lunarButton.setIcon(moon);
        }

I have this code implemented, but eclipse tells me "lunarButton cannot be resolved", is it not able to see the lunarButton variable in my init() method? what am I missing here?


Solution

  • Your lunarButton may be declared locally, perhaps in the init method.

    One solution: declare it as an instance field in the class, not in the init method.

    Solution two: don't even worry about the variable. Get the JButton object from the ActionEvent parameter's getSource() method. Cast the object returned to JButton, and call whatever methods you'd like on it.

    For example:

    if("switch".equals(action))
    {           
        // ImageIcon sun = new ImageIcon("assets/sun.png");
        // ImageIcon moon = new ImageIcon("assets/moon.png");
    
        JButton btn = (JButton) ae.getSource();
    
        changeLunar();
        count++;
        if (count % 2 == 0)
        {
             btn.setIcon(sun);
        }
        else
        {
             btn.setIcon(moon);
        }
    

    As an aside: you really don't want to re-load the images from disk each time the button is pushed. Instead read the images in once, perhaps in a constructor, stuff them into an ImageIcon field, and use that field when needed.