Search code examples
javaswingjbuttonactionlistener

how to change background color back and forth eg red and green when clicked using only 1 jbutton


so what I'm trying to do is creating a button that when clicks, turns the background color to be green. once its clicked on again, it turns red. And repeat basically. So im looking for some help that show me how I can do this.

this is what I've done so far

class colorText implements ActionListener{
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Go")) {
            panel.setBackground(Color.GREEN);
        }
    }
}       

I tried doing it by doing this but I get an error and was wondering either how to get around it or a new a way of doing it

            if (e.getActionCommand() == Color.GREEN) {
            panel.setBackground(Color.RED);
        }

Solution

  • Your attempted solution doesn't work because (as we can see from the first example), e.getActionCommand() returns a String - and likely will always return "Go" when they click on your button.

    What you need is some way of determining the state; telling the difference between "I should make the background red now" and "I should make the background green now". There are two ways of doing this that come to mind:

    1) Check the current background colour

    If the API lets you query the background colour and compare against a constant, you could check it like so:

    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Go")) {
            if (panel.getBackground() == Color.RED) {
                panel.setBackground(Color.GREEN);
            } else { // could check for GREEN background here
                panel.setBackground(Color.RED)
            }
        }
    }
    

    Possible downsides to this approach:

    • You might not be able to (reliably) read back the colour that you set. Either it's not exposed in the panel's API, or the value you get back does not equate to the Color constants for some reason (e.g. the read value has an alpha channel while the constants do not)
    • This only works if this method is the only way that the background gets modified. If any other code were to modify the background, you'd not have an accurate record of what your previous button press did. This is potentially a big issue as it means this code doesn't play nicely with other functionality.

    2) Store a flag and flip it each time

    This approach involves storing an explicit field that lets you know what to set the background to next. This could just be a boolean, like so:

    private boolean greenIsNext = true
       
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("Go")) {
            Color nextColour = greenIsNext ? Color.GREEN : Color.RED
            panel.setBackground(nextColour);
            // Flip the flag
            greenIsNext = !greenIsNext
        }
    }
    

    This is likely the cleaner way to handle this behaviour, as pressing the button will alternate between setting the background green and red regardless of what else is going on with the page.