开发者

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜