One solution would be to get the JButton's reference from the ActionEvent parameter:
@Override
public void actionPerformed(ActionEvent e) {
// the source here refers to the object that provoked this method to occur
JButton sourceBtn = (JButton) e.getSource();
sourceBtn.setBackground(Color.RED);
}
Also you could make button a field, not a local variable.
Also you could declare it as final.
Note that you'd never use code such as what you're posting since most non-trivial GUI programs would not be created inside of a static main method as you're doing, but rather would be done within OOP-compliant GUI classes.
For example:
import java.awt.Color;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ButtonColorChange extends JPanel {
private JButton button = new JButton(new ButtonAction("Press Me"));
public ButtonColorChange() {
add(button);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("ButtonColorChange");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ButtonColorChange());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class ButtonAction extends AbstractAction {
private static final Color COLOR_1 = Color.BLUE;
private static final Color COLOR_2 = Color.RED;
public ButtonAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
AbstractButton btn = (AbstractButton) e.getSource();
Color c = btn.getBackground();
c = c == COLOR_1 ? COLOR_2 : COLOR_1;
btn.setBackground(c);
}
}
Edit regarding further questions of yours:
Actually the code in my question it's only an example, the real code is something like your.
Then better to show the real code, or best a minimal compilable runnable example that simulates the real code.
(a) It is preferred to use e.getSource() or to make button a field?
Either or. If the same Action is to be used on multiple buttons, and you are only interested in the button pressed, then use getSource()
. If your Action or ActionListener is an inner class, then a field would work fine. If not, then you could pass the variable into the Action via a constructor parameter as per another answer to your question.
(b) You say that Also you could declare it as final but I receive this error: The local variable may not have been initialized. What I'm wrong?
Without your real code, it's hard to tell, but likely you don't initialize the button at the same time that you declare it.
(c) I my GUI program I don't launch the frame from a thread (id est I write the code of createAndShowGui() in the main(), without the thread). What is the difference?
My code guarantees that my GUI will start up on the Swing event thread, something that should be done for thread safety.