使GridBagLayout JPanel大小为内容,而不是容器?

时间:2017-06-18 14:01:29

标签: java swing size layout-manager gridbaglayout

我在GridBagLayout JPanel中包含BorderLayout JPanel。我希望GridBagLayout将自己调整为内部网格。相反,它将自身调整为BorderLayout,在内部网格的两侧添加空格(GridBagLayout中的所有权重均为0)。

我的想法是我希望BorderLayout提供空白(用胶水)。相反,GridBagLayout正在提供空白;你可以通过查看我添加的TitleBorder来看到。

原因是当我将GridBagLayout发送到我的打印机时,我不想要包含所有这些空白。

import java.awt.*;
import javax.swing.*;

public class GBLDemo {
    public static void main (String[] args) {
        JFrame jframe = new JFrame("GridBagLayout Demo");
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container contentPane = new JPanel(new BorderLayout());
        jframe.setContentPane(contentPane);

        GridBagConstraints gbc = new GridBagConstraints();
        JPanel gb = new JPanel(new GridBagLayout());
        contentPane.add(gb);

        gbc.gridx = gbc.gridy = 0;
        gb.add(new JLabel("Look "), gbc);

        gbc.gridx = 1;
        gb.add(new JLabel("at"), gbc);         

        gbc.gridx = 0;
        gbc.gridy = 1;
        gb.add(new JLabel("the "), gbc);

        gbc.gridx = 1;
        gb.add(new JLabel("border"), gbc);

        gb.setBorder(BorderFactory.createTitledBorder("Border"));

        jframe.pack();
        jframe.setVisible(true);
        jframe.setSize(640, 480);
    } // main(args)
} // GBLDemo

这是我想要的ASCII模型:

+-------------------------------------------+
|                                           |
|                                           |
|           +Border-----+                   |
|           |Look  at   |                   |
|           | the border|                   |
|           +-----------+                   |
|                                           |
|                                           |
+-------------------------------------------+

这是以上代码生成的显示:

enter image description here

3 个答案:

答案 0 :(得分:2)

将组件置于其首选大小(例如问题代码中的contentPane)的一个好方法是将其作为单个组件添加到具有网格包布局的容器中,而不指定约束

以下是上面的代码,适用于此。

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class GBLDemo {

    private JComponent ui = null;

    GBLDemo() {
        initUI();
    }

    private Container getContentPanel() {
        Container contentPane = new JPanel(new BorderLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        JPanel gb = new JPanel(new GridBagLayout());
        contentPane.add(gb);

        gbc.gridx = gbc.gridy = 0;
        gb.add(new JLabel("Look "), gbc);

        gbc.gridx = 1;
        gb.add(new JLabel("at"), gbc);         

        gbc.gridx = 0;
        gbc.gridy = 1;
        gb.add(new JLabel("the "), gbc);

        gbc.gridx = 1;
        gb.add(new JLabel("border"), gbc);

        gb.setBorder(BorderFactory.createTitledBorder("Border"));
        return contentPane;
    }

    public void initUI() {
        if (ui!=null) return;

        // A single object added to a grid bag layout with no constraint, 
        // will be centered within the available space.
        ui = new JPanel(new GridBagLayout()); 
        ui.setBorder(new EmptyBorder(4,4,4,4));

        ui.add(getContentPanel());
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                GBLDemo o = new GBLDemo();

                JFrame f = new JFrame(o.getClass().getSimpleName());
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

答案 1 :(得分:0)

具有绝对布局(null)的解决方案将是这样的:

import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class GBLDemo {
    public static void main (String[] args) {
        JFrame jframe = new JFrame("GridBagLayout Demo");
        jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        Container contentPane = new JPanel();
        contentPane.setLayout(null);
        jframe.setContentPane(contentPane);
        jframe.setVisible(true);
        jframe.setSize(640, 480);
        GridBagConstraints gbc = new GridBagConstraints();
        JPanel gb = new JPanel(new GridBagLayout());
        contentPane.add(gb);

        gbc.gridx = gbc.gridy = 0;
        gb.add(new JLabel("Look "), gbc);

        gbc.gridx = 1;
        gb.add(new JLabel("at"), gbc);         

        gbc.gridx = 0;
        gbc.gridy = 1;
        gb.add(new JLabel("the "), gbc);

        gbc.gridx = 1;
        gb.add(new JLabel("border"), gbc);

        gb.setBorder(BorderFactory.createTitledBorder("Border"));
        gb.setSize(gb.getPreferredSize());
        gb.setLocation(jframe.getWidth()/2-gb.getWidth()/2, jframe.getHeight()/2-gb.getHeight()/2);

        jframe.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent arg0) {
                gb.setSize(gb.getPreferredSize());
                gb.setLocation(jframe.getWidth()/2-gb.getWidth()/2, jframe.getHeight()/2-gb.getHeight()/2);
            }
        });        

    } // main(args)
} // GBLDemo

制作: code results

gb JPanel将永远位于中心,ComponentListener将负责这一点。 gp将更改其大小以自动适应包含gb.setSize(gb.getPreferredSize());的对象。

答案 2 :(得分:0)

您可以将您的面板gb直接添加到contentPanel,而不是将另一个带有GridBagLayout的面板添加到contentPane,并将面板gb添加到该面板(不填充)。

&#39>中心'具有BorderLayout的Panel的组件在获得其首选大小的北/东/西/南组件之后总是获得所有剩余空间。所以上面的中间人组件将会吸收' BorderLayout给它的所有空间,只要你没有添加"填充"约束,它应该以你想要的方式显示。