Using a Derived class of a Java Swing control to create listener for self
At the outset: I know that what I am doing is bad design. I am trying this to get a better feel of Java - what is possible, what is not and why?
I have written the following code:
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 开发者_StackOverflow社区= 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);
}
}
But this is not working. I see from the debugger that actionPerformed()
is being invoked and it has the expected values. I am not able to understand what is happening here. Can someone please help me?
You are setting the background color of the JFrame
, but the JPanel
that is contained by the JFrame
, which then holds your buttons, takes up all of the space of the JFrame
, so you can't see the background color changing.
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);
}
}
You can skip passing the container and just do
@Override
public void actionPerformed(ActionEvent event)
{
this.getParent().setBackground(buttonColor);
}
精彩评论