繁体   English   中英

在 JFrame 中心的 JPanel 内制作 JPanel

[英]Make a JPanel inside a JPanel in the center of the JFrame

抱歉,如果重复,找不到正确的答案

我正在尝试将本身添加到另一个 JPanel 中的 JPanel 居中

public class bgframe extends JPanel
{
    // The Image to store the background image in.
    Image img;
    public bgframe()
    {
        // Loads the background image and stores in img object.
        img = Toolkit.getDefaultToolkit().getImage("img/fondAccueil.png");
    }

    protected void paintComponent(Graphics g)
    {
        // Draws the img to the BackgroundPanel_accueil.
        g.drawImage(img, 0, 0, this);
    }
}

public class Frame_Accueil extends JFrame
{
public Frame_Accueil()
{
        this.setSize(1000,500);

        bgframe fond = new bgframe();
        JPanel boutons = new JPanel(new GridBagLayout());
    
        JButton btn1 = new JButton("btn1");
        JButton btn2 = new JButton("btn1");

        btn1.setPreferredSize(new Dimension(300, 50));
        btn2.setPreferredSize(new Dimension(300, 50));

        btn.add(btn1);
        btn.add(btn2);

        this.add(fond,BorderLayout.CENTER);
        fond.add(boutons,BorderLayout.CENTER);
    
        this.setVisible(true);
    
    }
}

问题是我有背景但按钮不在中心。 我怎样才能解决这个问题??

谢谢

首先,您的代码中有多个问题:

  1. bgframe没有从JFrame扩展,因此更好的名称可能是BgPanelBgPane ,因为它扩展了JPanel

  2. bgframeFrame_Accueil都不遵循Java 命名约定,因为其中一个不是大写字母,另一个使用的是蛇形而不是驼峰形。

    • FirstWordUpperCasedClass
    • firstWordLowerCasedVariable
    • firstWordLowerCasedMethodName()
    • ALL_WORDS_UPPER_CASED_CONSTANT
  3. 您忘记将super.paintComponent(g)作为bgframe内的第一行paintComponent调用,这可能会弄乱您的程序,因为 Swing 可能不知道在执行过程中的任何随机点上绘制什么或如何绘制bgframe的组件。

  4. 不要调用setSize(...) ,如果这样做,您的JFrame的装饰(边框和标题栏)正在考虑这一点,因此您的实际内容屏幕的大小比您想象的要小,最好覆盖getPreferredSize()然后在JFrame上调用pack()

  5. 没有必要扩展JFrame因为你没有改变它的行为,最好在你的程序中创建一个JFrame的实例,请参阅: 扩展 Z97A6D52B9C04A839F278842FB267 在这个程序中创建它的更深入的解释。 .

  6. 我知道btn是什么,所以我以为你指的是boutons

  7. 一旦您将应用程序作为 jar 文件 package 文件,图像和其他资产将成为embedded-resources ,因此开始这样对待它们是明智的,请参阅此答案以获取运行示例。

  8. 除了设置JButton的首选大小之外,您还可以创建一个单独的 class 扩展JButton ,并覆盖它的getPreferredSize ,就像上面第 4 点建议的JPanel一样。

  9. 默认情况下, JPanel具有FlowLayout ,因此它将忽略您对BorderLayout.CENTER的调用,您可以组合不同的布局管理器以获得所需的 output,例如,如果您将fond的布局更改为BoxLayout ,它将垂直居中,因为我认为这就是你的问题是。

  10. 最后但并非最不重要的一点是,将您的程序放在 EDT 上(并且在将代码发布到 Stack Overflow 时不要忘记main方法),更多内容在这个答案

所以,最后你的程序(没有我删除的bgframe class 因为这个特定问题不需要背景)应该是这样的:

import java.awt.Dimension;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class FrameAccueil {
    private JFrame frame;
    
    public FrameAccueil() {
        frame = new JFrame(getClass().getSimpleName());
        
        JPanel fond = new JPanel() { // Move this code inside your bgfond class
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(1000, 500);
            }
        };
        fond.setLayout(new BoxLayout(fond, BoxLayout.PAGE_AXIS));
        
        JPanel boutons = new JPanel(new GridBagLayout());

        JButton btn1 = new JButton("btn1");
        JButton btn2 = new JButton("btn1");

        JButton btn1 = new JButton("btn1") { // If you follow point 8, these code shall be moved there and these JButtons should be objects of that class.
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 50);
            }
        };
        JButton btn2 = new JButton("btn1") {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 50);
            }
        };

        boutons.add(btn1);
        boutons.add(btn2);

        fond.add(boutons); //Try to first add the inner objects and then the outer ones, so go inside-out as to keep them ordered in a more logical way
        frame.add(fond);

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new FrameAccueil()); //Place your program on the EDT
    }
}

它应该看起来像这样(使屏幕更小)

在此处输入图像描述

您可以尝试将按钮设置在网格的中心。 您也可以使用“GridBagConstraints.CENTER”和“GridBagConstraints.HORIZONTAL”

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM