2011-07-23 46 views
2

首先:我知道我所做的是糟糕的设计。我正在尝试这个以获得更好的Java感觉 - 什么是可能的,什么不是,为什么?使用派生类的Java Swing控件为自己创建侦听器

我写了下面的代码:

import java.awt.*; 
    import java.awt.event.*; 

    import javax.swing.*; 

    public class ButtonTest 
    { 
     public static void main(String[] args) 
     { 
      EventQueue.invokeLater(new Runnable() 
      { 
       @Override 
       public void run() 
       { 
        ButtonFrame frame = new ButtonFrame(); 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        frame.setVisible(true); 
       } 
      }); 
     } 
    } 

    @SuppressWarnings("serial") 
    class ButtonFrame extends JFrame 
    { 
     private final static int DEFAULT_WIDTH = 300; 
     private final static int DEFAULT_HEIGHT = 200; 
     private final JPanel buttonPanel; 

     public ButtonFrame() 
     { 
      this.setTitle("Button Frame"); 
      this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 

      PanelButton yellowButton = new PanelButton("Yellow", Color.YELLOW, this); 
      PanelButton redButton = new PanelButton("Red", Color.RED, this); 
      PanelButton blueButton = new PanelButton("Blue", Color.BLUE, this); 

      this.buttonPanel = new JPanel(); 
      this.buttonPanel.add(yellowButton); 
      this.buttonPanel.add(redButton); 
      this.buttonPanel.add(blueButton); 

      // add panel to frame 
      this.add(this.buttonPanel); 
     } 
    } 

    @SuppressWarnings("serial") 
    class PanelButton extends JButton implements ActionListener 
    { 
     private final Color buttonColor; 
     private final ButtonFrame containingFrame; 

     public PanelButton(String title, Color buttonColor, 
       ButtonFrame containingFrame) 
     { 
      super(title); 
      this.buttonColor = buttonColor; 
      this.containingFrame = containingFrame; 
      this.addActionListener(this); 
     } 

     @Override 
     public void actionPerformed(ActionEvent event) 
     { 
      this.containingFrame.setBackground(this.buttonColor); 
     } 
    } 

但是,这是行不通的。我从调试器看到actionPerformed()正在被调用,它有预期的值。我无法理解这里发生的事情。有人可以帮帮我吗?

回答

3

您可以跳过传递的容器,只是做

@Override 
public void actionPerformed(ActionEvent event) 
{ 
    this.getParent().setBackground(buttonColor); 
} 
+0

+ +1为单独的解决方案。我要解释为什么他不工作,你的工作表明如何做得更好。那里有良好的二元性。 –

+0

感谢您的回答。 –

4

您正在设置JFrame的背景色,而是一个由JFrame,然后握着你的按钮,占用了所有的JFrame的空间包含JPanel,所以你不能看到背景颜色变化。

This Works。

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class ButtonTest 
{ 
    public static void main(String[] args) 
    { 
     EventQueue.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       ButtonFrame frame = new ButtonFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 

@SuppressWarnings("serial") 
class ButtonFrame extends JFrame 
{ 
    private final static int DEFAULT_WIDTH = 300; 
    private final static int DEFAULT_HEIGHT = 200; 
    private final JPanel buttonPanel; 

    public ButtonFrame() 
    { 
     this.setTitle("Button Frame"); 
     this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 

     this.buttonPanel = new JPanel(); 

     PanelButton yellowButton = new PanelButton("Yellow", Color.YELLOW, buttonPanel); 
     PanelButton redButton = new PanelButton("Red", Color.RED, buttonPanel); 
     PanelButton blueButton = new PanelButton("Blue", Color.BLUE, buttonPanel); 

     this.buttonPanel.add(yellowButton); 
     this.buttonPanel.add(redButton); 
     this.buttonPanel.add(blueButton); 

     // add panel to frame 
     this.add(this.buttonPanel); 
    } 
} 

@SuppressWarnings("serial") 
class PanelButton extends JButton implements ActionListener 
{ 
    private final Color buttonColor; 
    private final JPanel buttonPanel; 

    public PanelButton(String title, Color buttonColor, 
      JPanel buttonPanel) 
    { 
     super(title); 
     this.buttonColor = buttonColor; 
     this.buttonPanel = buttonPanel; 
     this.addActionListener(this); 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) 
    { 
     buttonPanel.setBackground(this.buttonColor); 
    } 
} 
+0

感谢解释小姐。我更喜欢其他解决方案,因为它隐藏了容器属于哪种类型的事实,因此在其他情况下也更加有用。 –

+0

但是,当然!是的,另一种解决方案更好,但我觉得你应该明白为什么你遇到了问题(因为这就是你问的问题!)。 :P。快乐编程! –

+0

我喜欢最复杂的例子+1 – mKorbel

相关问题