我的 Java Swing JPanel 居中功能不起作用。为什么?

My Java Swing JPanel centering function does not work. Why?

中间的"JPanel",我想把对齐操作移到separate function,但不知怎么的不行。这些操作都是在本地进行的,所有工作都很好。

desCont = new DesignController();

JPanel centerBox = desCont.createCenterPanel();
this.add(centerBox);

设计控制器class 来源:

public class DesignController {
(...)
    public JPanel createCenterPanel(){
        JPanel centerPanel = new JPanel();
        JPanel hbox = new JPanel();
        JPanel vbox = new JPanel();

        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS ));
        centerPanel.add(Box.createHorizontalGlue());
        centerPanel.add(hbox);
        centerPanel.add(Box.createHorizontalGlue());

        hbox.setLayout(new BoxLayout(hbox, BoxLayout.Y_AXIS ));
        hbox.add(Box.createVerticalGlue());
        hbox.add(vbox);
        hbox.add(Box.createVerticalGlue());

        return centerPanel;
    }
}

更新:

示例文件重构问题的必要元素:

public class CenterTest {
    private JFrame frame;
    private static CardLayout cardLayout = new CardLayout();
    private JPanel headPanel;
    private static JPanel contentPanel;
    private JPanel footerPanel;
    private static JPanel mainPanel;

    private AppConstants appVars;

    -->default main method (generated by IDE)
    -->default constructor (generated by IDE)

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {
        appVars = new AppConstants();

        frame = new JFrame();
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
        frame.setBounds(100, 100, appVars.initWidth, appVars.initHeight);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        mainPanel = new JPanel();
        frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
        mainPanel.setLayout(new BorderLayout(0, 0));

        headPanel = new JPanel();
        headPanel.setBackground(Color.LIGHT_GRAY);
        headPanel.setPreferredSize(new Dimension( appVars.initHeaderPanelWidth, appVars.headerPanelHeight ));
        mainPanel.add(headPanel, BorderLayout.NORTH);

        contentPanel = new JPanel();
        contentPanel.setPreferredSize(new Dimension(appVars.initContentWidth, appVars.initContentHeight));
        mainPanel.add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(cardLayout);

        footerPanel = new JPanel();
        footerPanel.setBackground(Color.GREEN);
        footerPanel.setPreferredSize(new Dimension(appVars.initFooterPanelWidth, appVars.footerPanelHeight));
        mainPanel.add(footerPanel, BorderLayout.SOUTH);

        addCard(new CenterPanel(), "center-panel");
    }

    public static void addCard(JPanel panel, String name){
        contentPanel.add(panel, name);
        cardLayout.show(contentPanel, name);
    }

}

class CenterPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    /**
     * Include DesignController class.
     */
    private DesignController desCont;

    /**
     * Include global variables class.
     */
    private AppConstants appVars;

    public CenterPanel(){
        appVars = new AppConstants();
        desCont = new DesignController();

        /* ------------ THIS SECTION IS NOT CORRECTLY WORKING ----------------- */
        JPanel hBox = desCont.createCenterPanel();
        hBox.setBackground(Color.YELLOW);
        this.add(hBox);
        /* ------------ THIS SECTION IS NOT CORRECTLY WORKING ----------------- */

        /* ------------ THIS SECTION IS CORRECTLY WORKING ----------------- */

        /*JPanel hbox = new JPanel();
        JPanel vbox = new JPanel();
        vbox.setBackground(new Color(0, 204, 204));
        vbox.setPreferredSize(new Dimension(appVars.initContentWidth, appVars.initContentHeight));

        setLayout(new BoxLayout(this, BoxLayout.X_AXIS ));
        add(Box.createHorizontalGlue());
        add(hbox);
        add(Box.createHorizontalGlue());

        hbox.setLayout(new BoxLayout(hbox, BoxLayout.Y_AXIS ));
        hbox.add(Box.createVerticalGlue());
        hbox.add(vbox);
        hbox.add(Box.createVerticalGlue());*/

        /* ------------ THIS SECTION IS CORRECTLY WORKING ----------------- */
    }
}



class DesignController {
    private AppConstants appVars = new AppConstants();

    public JPanel createCenterPanel(){
        JPanel centerPanel = new JPanel();
        JPanel hbox = new JPanel();
        JPanel vbox = new JPanel();

        vbox.setBackground(new Color(0, 204, 204));
        vbox.setPreferredSize(new Dimension(appVars.initContentWidth, appVars.initContentHeight));

        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS ));
        centerPanel.add(Box.createHorizontalGlue());
        centerPanel.add(hbox);
        centerPanel.add(Box.createHorizontalGlue());

        hbox.setLayout(new BoxLayout(hbox, BoxLayout.Y_AXIS ));
        hbox.add(Box.createVerticalGlue());
        hbox.add(vbox);
        hbox.add(Box.createVerticalGlue());

        return centerPanel;
    }

}

class AppConstants {
    /**
     * Define initial width of window <br/>
     * <b>900</b>
     */
    public int initWidth = 900;

    /**
     * Define initial height of window <br/>
     * <b>600</b>
     */
    public int initHeight = 600;


    /**
     * Define initial width of window header, same as window width <br/>
     * <b>900</b>
     */
    public int initHeaderPanelWidth = initWidth;

    /**
     * Define height of windows header panel <br/>
     * <b>80</b>
     */
    public int headerPanelHeight = 80;



    /**
     * Define initial width of window footer, same as window width <br/>
     * <b>900</b>
     */
    public int initFooterPanelWidth = initWidth;

    /**
     * Define height of windows footer panel <br/>
     * <b>50</b>
     */
    public int footerPanelHeight = 50;



    /**
     * Define initial width of content panel, same as window width <br/>
     * <b>900</b>
     */
    public int initContentWidth = 900;

    /**
     * Define height of content panel <br/>
     * <b>window initial height - (header panel height + footer panel height)</b>
     */
    public int initContentHeight = initHeight - (headerPanelHeight + footerPanelHeight);
}

你的做法是错误的。你不能 return "center panel"。

为了使面板居中,您需要这样的结构:

HorizontalPanel
   VerticalPanel
        CenterPanel

vertical/horizontal 面板是包装器,您需要将水平面板添加到框架中,因为它是组件的父面板。

如果将 "CenterPanel" 添加到框架,那么您将丢失 vertical/horizontal 包装器面板,因为 Swing 组件只能有一个父级。因此框架成为 "CenterPanel".

的新父级

因此您的方法设计需要类似于:

public static Component centerPanel(Component panelToBeCentered)
{
    JPanel vertical = ...
    vertical.add( panelToBeCentered );

    JPanel horizontal = ...
    horizontal.add( vertical );

    return horizontal;
}

要使用代码,您需要执行以下操作:

 JPanel center = new JPanel();
 center.add(...);

 frame.add( DesignController.centerPanel( center ) );

请注意,在使用 BoxLayout 时,您可以使用方便的静态方法:

Box vertical = Box.createVerticalBox();
Box horizontal Box.createHorizontalBox();

创建一个容器来容纳您的组件。

更简单的是您不需要使用嵌套框。您可以只使用 GridBagLayout。 GridBagLayout 的默认约束会导致组件居中:

JPanel center = new JPanel();
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(center, new GridBagConstraints());
frame.add( wrapper );

我修改的函数,基于@camickr 的回答:

parentPanel 布局设置为 BoxLayout.X_AXIS 并添加一个新的 JPanel 作为hbox horizo​​ntalGlues 之间。之后我将 hbox 布局设置为 BoxLayout.Y_AXIS 并创建一个新的 JPanel inside hbox 作为vbox verticalGlues.

public JPanel createCenterPanel(JComponent parentPanel){
    JPanel hbox = new JPanel();
    JPanel vbox = new JPanel();

    vbox.setBackground(new Color(0, 0, 255));

    parentPanel.setLayout(new BoxLayout(parentPanel, BoxLayout.X_AXIS ));
    parentPanel.add(Box.createHorizontalGlue());
    parentPanel.add(hbox);
    parentPanel.add(Box.createHorizontalGlue());

    hbox.setLayout(new BoxLayout(hbox, BoxLayout.Y_AXIS ));
    hbox.add(Box.createVerticalGlue());
    hbox.add(vbox);
    hbox.add(Box.createVerticalGlue());

    return hbox;
}