The following code produces a window with buttons, but an error message pops up when I run i and actally press the button. According to the Spring tooltip:
Cannot make a static reference to the non-static method setBackground(Color) from the type JComponent
This program is literally entered from my Java textbook line for line, as far as I can tell. It's an older book, so there might be incompatibility, but it doesn't seem likely.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonTest
{
public static void main(String[] args)
{
final ButtonFrame frame = new ButtonFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.show();
}
}
class ButtonFrame extends JFrame
{
public ButtonFrame()
{
setTitle("Button Test");
setSize(Default_width, Default_height);
//panel
ButtonPanel panel = new ButtonPanel();
Container contentPane=getContentPane();
contentPane.add(panel);
}
public static final int Default_width = 300;
public static final int Default_height = 200;
}
class ButtonPanel extends JPanel
{
public ButtonPanel()
{
JButton yellowButton = new JButton("Yellow");
JButton blueButton = new JButton("Blue");
JButton redButton = new JButton("Red");
add(yellowButton);
add(blueButton);
add(redButton);
ColorAction yellowAction= new ColorAction(Color.YELLOW);
ColorAction redAction = new ColorAction(Color.RED);
ColorAction blueAction = new ColorAction(Color.BLUE);
yellowButton.addActionListener(yellowAction);
blueButton.addActionListener(blueAction);
redButton.addActionListener(redAction);
}
}
class ColorAction implements ActionListener
{
public ColorAction(Color c)
{
backgroundColor=c;
}
public void actionPerformed(ActionEvent event)
{
ButtonPanel.setBackground(backgroundColor);
}
private Color backgroundColor;
}
One approach is to nest ColorAction
as an inner class in ButtonPanel
, where it has implicit access to the enclosing panel.
Addendum: As noted in comments by @Andrew Thompson and @nachokk, the implicit accessibility can be made explicit by qualifying this
using the enclosing class name. See JLS §15.8.4. Qualified this
for details. In this example, these two invocations are equivalent:
setBackground(backgroundColor);
ButtonPanel.this.setBackground(backgroundColor);
As an more general alternative, consider encapsulating the target panel and color in an Action
, as outlined here.
class ButtonPanel extends JPanel {
public ButtonPanel() {
JButton yellowButton = new JButton("Yellow");
JButton blueButton = new JButton("Blue");
JButton redButton = new JButton("Red");
add(yellowButton);
add(blueButton);
add(redButton);
ColorAction yellowAction = new ColorAction(Color.YELLOW);
ColorAction redAction = new ColorAction(Color.RED);
ColorAction blueAction = new ColorAction(Color.BLUE);
yellowButton.addActionListener(yellowAction);
blueButton.addActionListener(blueAction);
redButton.addActionListener(redAction);
}
private class ColorAction implements ActionListener {
public ColorAction(Color c) {
backgroundColor = c;
}
@Override
public void actionPerformed(ActionEvent event) {
setBackground(backgroundColor);
}
private Color backgroundColor;
}
}