添加两个 JPanel 时出现问题

问题描述

我正在尝试向 JFrame 添加两个 JPanel,一个带有简单的背景,另一个带有按钮等。要么我只得到按钮,要么只得到背景。我无法在任何地方找到我的问题的解决方案,因此任何帮助将不胜感激。我还是 Java 新手,所以请不要讨厌。

GuiMainMenu:

public class GuiMainMenu extends JFrame implements ActionListener,KeyListener {
    private static final long serialVersionUID = -7936366600070922227L;

    Color blue = new Color(114,137,218);
    Color gray = new Color(44,47,51);
    Color white = new Color(255,255,255);

    ImagePanel panel = new ImagePanel(new ImageIcon("image.png").getimage());

    public static int width;
    public static int height;

    JPanel p = new JPanel();
    JPanel p1 = new JPanel();
    JLabel l = new JLabel();
    JLabel l1 = new JLabel();
    JLabel l2 = new JLabel();
    JButton b = new JButton();
    JButton b1 = new JButton();
    JButton b2 = new JButton();
    String title = "-";

    
    public GuiMainMenu() {
        setSize(m.X,m.Y);
        setTitle(title);
        setResizable(true);
        setLocationRelativeto(null);
        setDefaultCloSEOperation(JFrame.EXIT_ON_CLOSE);
        addKeyListener(this);

        p.setLayout(null);

        width = getWidth();
        height = getHeight();

        getRootPane().addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                width = getWidth();
                height = getHeight();

                addButtons();
                addLabels();
            }
        });

        addLabels();
        addButtons();
        
        add(p);
        add(panel);
        setVisible(true);
    }

    public void addLabels() {
        l.setSize(width,height);
        l.setLocation(5,-40);
        l.setText("x");
        l.setHorizontalAlignment(SwingConstants.LEFT);
        l.setVerticalAlignment(SwingConstants.BottOM);
        l.setForeground(blue);
        l.setFont(new Font("Trebuchet MS",Font.PLAIN,15));

        l1.setSize(width,height);
        l1.setLocation(-22,-40);
        l1.setText("y");
        l1.setHorizontalAlignment(SwingConstants.RIGHT);
        l1.setVerticalAlignment(SwingConstants.BottOM);
        l1.setForeground(blue);
        l1.setFont(new Font("Trebuchet MS",15));

        l2.setText("test label");
        l2.setSize(width,height);
        l2.setLocation(0,-75);
        l2.setVerticalAlignment(SwingConstants.CENTER);
        l2.setHorizontalAlignment(SwingConstants.CENTER);
        l2.setForeground(blue);
        l2.setFont(new Font("Trebuchet MS",Font.BOLD,26));

        p.add(l);
        p.add(l1);
        p.add(l2);
        validate();
    }

    public void addButtons() {
        b.setText("button0");
        b.setFocusable(false);
        b.setBorder(null);
        b.setLocation(width / 2 - 200,height / 2 - 35);
        b.setSize(400,35);
        b.setForeground(white);
        b.setBackground(blue);
        b.addActionListener(this);

        b1.setText("button1");
        b1.setFocusable(false);
        b1.setBorder(null);
        b1.setLocation(width / 2 - 200,height / 2 + 10);
        b1.setSize(400,35);
        b1.setForeground(white);
        b1.setBackground(blue);
        b1.addActionListener(this);

        p.add(b);
        p.add(b1);
        validate();
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
    }

    @Override
    public void keypressed(KeyEvent arg0) {
    }

    @Override
    public void keyreleased(KeyEvent arg0) {
    }

    @Override
    public void keyTyped(KeyEvent arg0) {
    }
}

ImagePanel 类:

class ImagePanel extends JPanel {
    private static final long serialVersionUID = -7270956677693528549L;
    private Image img;

    public ImagePanel(String img) {
        this(new ImageIcon(img).getimage());
    }

    public ImagePanel(Image img) {
        this.img = img;
    }

    public void paintComponent(Graphics g) {
        g.drawImage(img,GuiMainMenu.width,GuiMainMenu.height,null);
    }
}

解决方法

我想您想显示一个带有背景图像和各种组件的 JFrame。我认为在查看您的代码后,您的部分存在一些误解导致了问题。

我创建了一小段代码来完成基础工作,也许可以帮助您解决问题。 (未测试!)

@SuppressWarnings("serial")
public class GuiMainMenu extends JFrame{

    private BufferedImage imageBackground;  // TODO: load your background image

    public GuiMainMenu(){
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(1024,768));
        setMinimumSize(new Dimension(800,600));
        // TODO: setLayout if needed
        JPanel panel = (JPanel)add(new JPanel(){
            @Override
            public void paintComponent(Graphics g){
                super.paintComponent(g);
                g.drawImage(imageBackground,this);
            }
        });
        addOtherComponents(panel);
        pack();
        setLocationRelativeTo(null);
        setTitle("Your Title her");
        setVisible(true);
    }

    private void addOtherComponents(JPanel panel){
        //TODO: add the needed Stuff
        //panel.add ...
    }
}
,
p.setLayout(null); 

不要使用空布局。 Swing 旨在与布局管理器一起使用。

阅读关于 Layout Managers 的 Swing 教程中的部分,了解更多信息和工作示例。

我要么只得到按钮,要么只得到背景

add(p);
add(panel);

JFrame 的默认布局管理器是 BorderLayout。如果您不指定约束,两个组件都会添加到 CENTER。但是只会显示最后添加的一个。

尝试以下操作以查看不同之处:

add(p,BorderLayout.PAGE_STRT);
add(panel,BorderLayout.CENTER);

一个带有简单的背景,另一个带有按钮等

然而上面不是你想要的。 Swing 组件具有父/子关系。所以你真正需要的是:

backgroundPanel.add(buttonPanel);
add(backgroundPanel,BorderLayout.CENTER);

注意我使用了更有意义的名称,因为“p”和“panel”不是描述性的。为变量使用描述性名称,以便人们理解它们的含义。