首页 文章

为什么我的JPanel会占用JFrame?

提问于
浏览
0

我对编程比较陌生,所以如果这个问题很愚蠢,我很抱歉 . 我正在创建一个Java程序,它在JPanel中包含一个JButton,而JPanel在JFrame中 . 另一个按钮位于JPanel外部,但仍在JFrame中 . 我将布局设置为BoxLayout . 我的问题是,我制作黑色的面板占据了整个JFrame,除了第二个按钮的位置 . 如何制作JPanel,只占用第一个按钮周围的区域?

public class alt {
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    JButton button1 = new JButton("button 1");
    JButton button2 = new JButton("button 2");
    public alt(){
        frame.setVisible(true);
        frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
        panel.setBackground(Color.black);
        frame.setTitle("test");
        frame.setExtendedState(java.awt.Frame.MAXIMIZED_BOTH);
        panel.add(button1);
        frame.add(panel);
        frame.add(button2);
        button2.setAlignmentX(Component.CENTER_ALIGNMENT);
    }
}

2 回答

  • 1

    您可以使用不同的布局管理器,它可以让您更好地控制决定如何分配空间和处理填充,例如 GridBagLayout ...

    Example

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class SampleLayout {
    
        public static void main(String[] args) {
            new SampleLayout();
        }
    
        public SampleLayout() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    }
    
                    JPanel panel = new JPanel();
                    JButton button1 = new JButton("button 1");
                    JButton button2 = new JButton("button 2");
    
                    panel.setBackground(Color.black);
                    panel.add(button1);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.setLayout(new GridBagLayout());
                    GridBagConstraints gbc = new GridBagConstraints();
                    gbc.gridwidth = GridBagConstraints.REMAINDER;
                    frame.add(panel, gbc);
                    frame.add(button2, gbc);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
    }
    

    请查看Laying Out Components Within a Container了解更多详情

  • 2

    面板占据框架内容窗格大部分的原因在于 BoxLayout 管理器使用组件的最小值,首选值和最大值的方式 . 它考虑了组件的最大值 . 由于 JPanel 的最大值很大,因此占用了所有可用空间 . 解决方案是更改面板的最大值 . 但是,这是不好的做法 . 我不建议使用 BoxLayout 管理器 - 它非常弱并导致代码不佳 .

    我建议使用 MigLayout 管理器或 GroupLayout 管理器 .

    我提供了三种解决方案:更正的 BoxLayout 解决方案, MigLayout 解决方案和 GroupLayout 解决方案 .

    BoxLayout solution

    我们确定按钮的最大尺寸,并将面板的大小更改为比按钮大一点 .

    package com.zetcode;
    
    import java.awt.Color;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import javax.swing.BorderFactory;
    import javax.swing.Box;
    import javax.swing.BoxLayout;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    
    public class BoxLayoutPanel extends JFrame {
    
        public BoxLayoutPanel() {
    
            initUI();
        }
    
        private void initUI() {
    
            JPanel cpane = (JPanel) getContentPane();
            cpane.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
            cpane.setLayout(new BoxLayout(cpane, 
                    BoxLayout.Y_AXIS));        
    
            JPanel pnl = new JPanel();
    
            JButton btn1 = new JButton("Button 1");
            JButton btn2 = new JButton("Button 2");
    
            Dimension dm = btn1.getMaximumSize();
            dm.height += 15;
            dm.width += 15;
    
            pnl.setMaximumSize(dm);
    
            pnl.setBackground(Color.black);
            add(pnl);
            add(Box.createVerticalStrut(10));
            pnl.add(btn1);
            btn2.setAlignmentX(Component.CENTER_ALIGNMENT);
            add(btn2);
    
            setTitle("BoxLayout solution");
            pack();
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    BoxLayoutPanel ex = new BoxLayoutPanel();
                    ex.setVisible(true);
                }
            });   
        }
    }
    

    这不是一个干净的解决方案 . 通常,我们应该避免在应用程序代码中调用 getMaximumSize()setMaximumSize() - 这是布局管理器's job. Also in three occasions, we use fixed pixel widths: when we define an empty border, a vertical strut, and a maximum panel'的大小 . 但是,此代码不可移植 . 当屏幕分辨率发生变化时,像素宽度会发生变化 . 这是 BoxLayout 经理的缺点 .

    MigLayout solution

    该解决方案更清洁,更便携 . MigLayout 是第三方经理,因此我们需要下载其他库 .

    package com.zetcode;
    
    import java.awt.Color;
    import java.awt.EventQueue;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import net.miginfocom.swing.MigLayout;
    
    
    public class MigLayoutPanel extends JFrame {
    
        public MigLayoutPanel(){
    
            initUI();
    
            setTitle("MigLayout solution");
            setLocationRelativeTo(null);       
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    
        private void initUI() {
    
            JPanel main = new JPanel(new MigLayout("center"));
    
            JPanel pnl2 = new JPanel();
    
            JButton btn1 = new JButton("Button 1");
            JButton btn2 = new JButton("Button 2");
    
            pnl2.setBackground(Color.black);
    
            pnl2.add(btn1);
            main.add(pnl2, "wrap");
            main.add(btn2, "alignx center");
    
            add(main);
    
            pack();
        }
    
    
        public static void main(String[] args){
    
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    MigLayoutPanel ex = new MigLayoutPanel();
                    ex.setVisible(true);
                }
            });
        }
    }
    

    MigLayout solution

    GroupLayout solution

    GroupLayout 是一个内置的布局管理器 . 使用 MigLayout ,它们是最便携,最灵活的布局管理器 .

    package com.zetcode;
    
    import java.awt.Color;
    import java.awt.Container;
    import java.awt.EventQueue;
    import javax.swing.GroupLayout;
    import static javax.swing.GroupLayout.Alignment.CENTER;
    import static javax.swing.GroupLayout.DEFAULT_SIZE;
    import static javax.swing.GroupLayout.PREFERRED_SIZE;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import static javax.swing.LayoutStyle.ComponentPlacement.RELATED;
    
    
    public class GroupLayoutPanel extends JFrame {
    
        public GroupLayoutPanel(){
    
            initUI();
    
            setTitle("GroupLayout solution");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setLocationRelativeTo(null);        
        }
    
        private void initUI() {
    
            Container pane = getContentPane();
            GroupLayout gl = new GroupLayout(pane);
            pane.setLayout(gl); 
    
            JPanel pnl = new JPanel();
    
            JButton btn1 = new JButton("Button 1");
            pnl.add(btn1);
    
            JButton btn2 = new JButton("Button 2");
    
            pnl.setBackground(Color.black);
    
            gl.setAutoCreateGaps(true);
    
            gl.setHorizontalGroup(gl.createSequentialGroup()
                    .addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
                    .addGroup(gl.createParallelGroup(CENTER)
                            .addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE, 
                                    PREFERRED_SIZE)
                            .addComponent(btn2))
                    .addContainerGap(DEFAULT_SIZE, Integer.MAX_VALUE)
            );
    
            gl.setVerticalGroup(gl.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(pnl, DEFAULT_SIZE, DEFAULT_SIZE, 
                            PREFERRED_SIZE)
                    .addPreferredGap(RELATED)
                    .addComponent(btn2)
                    .addContainerGap()
            );
    
            pack();
        }
    
    
        public static void main(String[] args){
    
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    GroupLayoutPanel ex = new GroupLayoutPanel();
                    ex.setVisible(true);
                }
            });
        }
    }
    

    GroupLayout solution

相关问题