簡體   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