如何将 JButton 添加到其他类的 JPanel 中



所以我有2个类。一个创建 JPanel 和一个 JFrame,另一个创建按钮。现在我想将这些按钮添加到我的 JPanel 中。

我的 JPanel 和 JFrame 创建的地方:

public class Surface extends JPanel implements KeyListener, ActionListener
{
    private static final long serialVersionUID = 1L;
    static JFrame jframe = new JFrame("TitleComingSoon");
    Snake mySnake = new Snake(true);
    int width;
    int height;
    @SuppressWarnings("deprecation")
    public Surface(int width, int height)
    {
        this.width = width;
        this.height = height;
        // Create the JPanel
        setLayout(null);
        setBounds(0, 0, 400, 400);
        setBackground(Color.DARK_GRAY);
        // Create the JFrame
        jframe.setSize(width, height);
        jframe.setResizable(false);
        jframe.setLayout(null);
        jframe.add(this); // Add the JPanel to the JFrame
        jframe.setVisible(true);
        // Add the KeyListener
        addKeyListener(this);
        setFocusTraversalKeysEnabled(true);
        setFocusable(true);
        requestFocusInWindow();
        show();
    }
    @Override
    public void paintComponent(Graphics diamond)
    {   
        super.paintComponent(diamond);
        diamond.drawRect(60, 60, 100, 50);
        diamond.setColor(Color.RED);
        repaint();
    }
}

在我的另一堂课上,我正在这样做:

Surface.jframe.add(myButton);

我的问题是,按钮在 JPanel 下方。因此,如果我删除JPanel,我可以看到按钮。

有几件事跳出来了...

  1. 使用null布局。虽然看起来您获得了控制权,但会增加工作量并失去平台之间的灵活性。
  2. 从另一个组件创建框架,但更重要的是,从其构造函数中创建框架。面板不应关注其显示方式,而应专注于完成其设计目的的工作。
  3. 使用KeyListener . KeyListener挑剔又麻烦,最好使用键绑定 API
  4. 使用static进行跨对象通信。静态不是您提供跨类字段访问的方式,还有很多其他技术可以提供更好的支持。主要问题是,如果您创建窗格的另一个实例,您将创建一个新框架并更改对static字段的引用......现在你实际上是在处理哪个框架?

那么,解决方案是什么?

  • 从"主"入口类中,创建一个JFrameSurface面板和按钮的实例。将Surface面板设置为框架的内容面板,然后将按钮添加到框架中。
  • 使用适当的布局管理器
  • 使用键绑定 API 而不是KeyListener

您可以在Surface中创建ButtonHolderClass的实例,并通过公共getter方法检索按钮:

public Surface(int width, int height)
{
    ...
    ButtonHolderClass buttonHolder = new ButtonHolderClass();
    JButton myButton = buttonHolder.getMyButton();
    add(myButton); // Add myButton
    jframe.add(this); // Add the JPanel to the JFrame
}
Surface.jframe.add(myButton);

您正在将按钮添加到 JFrame。你说你想把它添加到JPanel中。

简单制作

Surface.add(myButton);
Surface.jframe.add(Surface);
这会将 JButton 添加到 JPanel

,然后将 JPanel 添加到 JFrame。

在这里订购东西有一个小问题。在 Surface 构造函数完成构造之前,将 Surface 实例添加到帧中。

package test;
import java.awt.Dimension;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Surface extends JPanel {
    static JFrame jframe;
    static Surface surfaceInstance = new Surface();
    public static Surface getInstance() {
        return surfaceInstance;
    }
    public static void main(String argv[]) {
        /* You need this to be a good friend of the Swing */
        Runnable initiator = new Runnable() {
            public void run() {
                jframe = new JFrame("Whatever title you want");
                jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // this will kill the application when you close the frame
                jframe.setContentPane(Surface.getInstance());
                jframe.pack();
                jframe.setVisible(true);
            }
        };
        /** You let the Swing run your initiator when Swing wishes to do so */
        SwingUtilities.invokeLater(initiator);
        Surface.getInstance().setPreferredSize(new Dimension(400,400));
        /** then you can add other stuff to it **/
        for (String buttonTitle: new String[] {"button1", "button2", "button3"}) {
            Surface.getInstance().add(new JButton(buttonTitle));
        }
    }
}

最新更新