2013-10-06 26 views
3

下面的代碼會生成一個帶按鈕的窗口,但是當我運行i並按下按鈕時會彈出錯誤消息。根據春季工具提示:面板中的背景顏色不會改變

Cannot make a static reference to the non-static method setBackground(Color) from the type JComponent 

這個程序是從我的Java教科書行直接輸入,據我所知。這是一本較舊的書,因此可能存在不兼容性,但似乎不太可能。

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; 
} 
+0

'frame.show();'不要忽視廢棄警告。 –

+0

+1 [sscce](http://sscce.org/)。 – trashgod

回答

4

一種方法是nestColorActionButtonPanel一個內部類,在那裏它具有封閉面板的隱式訪問。

附錄:正如在@Andrew Thompson和@nachokk的評論中指出的那樣,隱式可訪問性可以通過使用封閉類名來限定this來明確。詳細信息請參見JLS §15.8.4. Qualifiedthis。在這個例子中,這兩個調用是等效的:

setBackground(backgroundColor); 
ButtonPanel.this.setBackground(backgroundColor); 

作爲更一般的替代方案中,考慮封裝目標面板和顏色在Action,所概述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; 
    } 
} 
+0

另請參見[§15.8.4。合格](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.4)。 - 這是在(現已刪除的)答案上發佈的評論,這是唯一值得重複的部分。 –

+0

@AndrewThompson:我相信你,但是我發現你的觀點清晰明瞭,你應該恢復答案。 – trashgod

+0

這個問題的大部分答案都是錯誤的(給出代碼結構)。如果我復活了它的任何部分,它只會作爲評論。 –

2

ButtonPanel.setBackground() 不是一個靜態方法,所以你不能把它作爲一個。你需要一個具體的ButtonPanel實例來設置背景。

ButtonPanel bp = new ButtonPanel(); 
bp.setBackground(backgroundColor); 
0

在外觀上也改變和感覺可以幫助:

//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());