3

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;
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Alden Utter
  • 33
  • 1
  • 3

3 Answers3

4

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.

image

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;
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • See also [§15.8.4. Qualified this](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.4). -- That was a comment posted on a (now deleted) answer that was the only part worth repeating. – Andrew Thompson Oct 06 '13 at 12:11
  • @AndrewThompson: I defer to you, but I found your argument for clarity to be cogent, should you restore your answer. – trashgod Oct 06 '13 at 16:46
  • The bulk of the answer was wrong for this question (given the code structure). If I did resurrect any part of it, it would only be as a comment. – Andrew Thompson Oct 06 '13 at 16:59
  • 1
    Also, @AndrewThompson Thank you for both your help, and for saying that your the "this.setbackground" fix was incorrect. I had tried this before and was worried that there was something wrong with my compiler that was causing it to fail. – Alden Utter Oct 06 '13 at 18:59
  • 1
    Glad you got it sorted. :) – Andrew Thompson Oct 06 '13 at 19:02
2

ButtonPanel.setBackground() is not a static method so you can't call it as one. You need a concrete instance of ButtonPanel to set the background.

ButtonPanel bp = new ButtonPanel();
bp.setBackground(backgroundColor);
Meistro
  • 3,664
  • 2
  • 28
  • 33
0

Also change in look and feel can help:

//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
Ryan K
  • 3,985
  • 4
  • 39
  • 42
Tuomas
  • 169
  • 2
  • 4