【问题标题】:Gridbag layout problems网格包布局问题
【发布时间】:2012-11-29 07:34:15
【问题描述】:

我正在设计一个面板并在OptionPane Confirm Dialog 中使用这个面板,如下所示:

JOptionPane.showConfirmDialog(null, slaveGroupPanel, messages.getString("centrum.manageGroups"), JOptionPane.OK_CANCEL_OPTION);

我的网格包约束是这样的:

    addGroupButton.setText(messages.getString("centrum.slavegroup.add"));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 6;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    add(addGroupButton, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 1;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.gridwidth = 5;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.weightx = 1.0;
    add(addGroupTextField, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.gridwidth = 1;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    add(groupNameLabel, gridBagConstraints);

    groupComboBox.setModel(new DefaultComboBoxModel(slaveGroupHash.keySet().toArray() ));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.gridwidth = 5;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    gridBagConstraints.weightx = 1;
    add(groupComboBox, gridBagConstraints);

    allSlavesList.setModel(new DefaultListModel());

    for (int i = 0; i < allSlaves.length; i++) {
        ((DefaultListModel)allSlavesList.getModel()).addElement(allSlaves[i]);
    }

    allSlavesList.setVisibleRowCount(4);
    jScrollPane2.setViewportView(allSlavesList);
    jScrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);


    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 3;
    gridBagConstraints.gridwidth = 3;
    gridBagConstraints.gridheight = 2;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.weightx = 0.45;
    gridBagConstraints.weighty = 1.0;
    add(jScrollPane2, gridBagConstraints);

    slavesInGroupList.setModel(new DefaultListModel());
    slavesInGroupList.setVisibleRowCount(4);
    jScrollPane3.setViewportView(slavesInGroupList);
    jScrollPane3.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 4;
    gridBagConstraints.gridy = 3;
    gridBagConstraints.gridwidth = 3;
    gridBagConstraints.gridheight = 2;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.weightx = 0.45;
    gridBagConstraints.weighty = 1.0;
    add(jScrollPane3, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 2;
    gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
    add(allSlavesLabel, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 4;
    gridBagConstraints.gridy = 2;
    gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
    add(slavesInGroupLabel, gridBagConstraints);

    addSlaveButton.setIcon(GeneralObjects.getrightIcon());
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 3;
    gridBagConstraints.gridy = 3;
    gridBagConstraints.weightx = 0.1;
    gridBagConstraints.weighty = 1.0;
    add(addSlaveButton, gridBagConstraints);

    deleteSlaveButton.setIcon(GeneralObjects.getleftIcon());
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 3;
    gridBagConstraints.gridy = 4;
    gridBagConstraints.weightx = 0.1;
    gridBagConstraints.weighty = 1.0;
    add(deleteSlaveButton, gridBagConstraints);

    renameButton.setText(messages.getString("centrum.slavegroup.rename"));

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 6;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    add(renameButton, gridBagConstraints);

    deleteButton.setText(messages.getString("centrum.slavegroup.delete"));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 5;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    add(deleteButton, gridBagConstraints);

但正如您在随附的屏幕截图中看到的那样,文本字段和添加按钮之间有两个间隙。删除和重命名按钮之间也会出现这种差距。但是我不想要那些差距。我没有定义插入,我有两个文本字段一个组合框 weightx = 1;fill = java.awt.GridBagConstraints.HORIZONTAL; 所以我希望它们尽可能地水平扩展而没有间隙。但是为什么会出现这些差距呢?

其次,您可以清楚地看到右手边的 Jlist 比左手边的要宽。但是,我的两个 JLists(实际上是包含 JLists 的 ScrollPanes)都将 gridwidthweightxfill 参数设置为相同的值。所以我希望它们的大小相同。看起来我错过了一些东西。

SSCCE 添加如下:

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

public class SSCCE {

private javax.swing.JButton addGroupButton;
private javax.swing.JTextField addGroupTextField;
private javax.swing.JButton addSlaveButton;
private javax.swing.JList allSlavesList;
private javax.swing.JButton deleteButton;
private javax.swing.JButton deleteSlaveButton;
private javax.swing.JComboBox groupComboBox;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JButton renameButton;
private javax.swing.JLabel groupNameLabel;
private javax.swing.JLabel allSlavesLabel;
private javax.swing.JLabel slavesInGroupLabel;
private javax.swing.JList slavesInGroupList;

public SSCCE() {

}

public JPanel createPanel(){
    JPanel panel = new JPanel();
    panel.setLayout(new java.awt.GridBagLayout());


    addGroupButton=new javax.swing.JButton();
    addGroupTextField=new javax.swing.JTextField();
    addSlaveButton=new javax.swing.JButton();
    allSlavesList=new javax.swing.JList();
    deleteButton=new javax.swing.JButton();
    deleteSlaveButton=new javax.swing.JButton();
    groupComboBox=new javax.swing.JComboBox();
    jScrollPane2=new javax.swing.JScrollPane();
    jScrollPane3=new javax.swing.JScrollPane();
    renameButton=new javax.swing.JButton();
    groupNameLabel=new javax.swing.JLabel();
    allSlavesLabel=new javax.swing.JLabel();
    slavesInGroupLabel=new javax.swing.JLabel();
    slavesInGroupList=new javax.swing.JList();

    allSlavesList.setModel(new DefaultListModel());
    slavesInGroupList.setModel(new DefaultListModel());



    GridBagConstraints gridBagConstraints;

    addGroupButton.setText("add");
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 6;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    panel.add(addGroupButton, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 1;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.gridwidth = 5;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.weightx = 1.0;
    panel.add(addGroupTextField, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.gridwidth = 1;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    panel.add(groupNameLabel, gridBagConstraints);

    groupComboBox.setModel(new DefaultComboBoxModel(new Object[]{"one","two","three"}));
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.gridwidth = 5;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    gridBagConstraints.weightx = 1;
    panel.add(groupComboBox, gridBagConstraints);



    allSlavesList.setVisibleRowCount(4);
    jScrollPane2.setViewportView(allSlavesList);
    jScrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);


    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 3;
    gridBagConstraints.gridwidth = 3;
    gridBagConstraints.gridheight = 2;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.weightx = 0.45;
    gridBagConstraints.weighty = 1.0;
    panel.add(jScrollPane2, gridBagConstraints);

    slavesInGroupList.setVisibleRowCount(4);
    jScrollPane3.setViewportView(slavesInGroupList);
    jScrollPane3.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 4;
    gridBagConstraints.gridy = 3;
    gridBagConstraints.gridwidth = 3;
    gridBagConstraints.gridheight = 2;
    gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
    gridBagConstraints.weightx = 0.45;
    gridBagConstraints.weighty = 1.0;
    panel.add(jScrollPane3, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 2;
    gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
    panel.add(allSlavesLabel, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 4;
    gridBagConstraints.gridy = 2;
    gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
    panel.add(slavesInGroupLabel, gridBagConstraints);

    //addSlaveButton.setIcon(GeneralObjects.getrightIcon());
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 3;
    gridBagConstraints.gridy = 3;
    gridBagConstraints.weightx = 0.1;
    gridBagConstraints.weighty = 1.0;
    panel.add(addSlaveButton, gridBagConstraints);

    //deleteSlaveButton.setIcon(GeneralObjects.getleftIcon());
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 3;
    gridBagConstraints.gridy = 4;
    gridBagConstraints.weightx = 0.1;
    gridBagConstraints.weighty = 1.0;
    panel.add(deleteSlaveButton, gridBagConstraints);

    renameButton.setText("rename");

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 6;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    panel.add(renameButton, gridBagConstraints);

    deleteButton.setText("delete");
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 5;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST;
    panel.add(deleteButton, gridBagConstraints);




    ((DefaultListModel)allSlavesList.getModel()).addElement("one");
    ((DefaultListModel)allSlavesList.getModel()).addElement("two");
    ((DefaultListModel)allSlavesList.getModel()).addElement("three");

    ((DefaultListModel)slavesInGroupList.getModel()).addElement("one");
    ((DefaultListModel)slavesInGroupList.getModel()).addElement("two");
    ((DefaultListModel)slavesInGroupList.getModel()).addElement("three");
    panel.setPreferredSize(new Dimension(600,300));


    return panel;

}

public static void main(String[] args){
    SSCCE a = new SSCCE();
    JOptionPane.showConfirmDialog(null, a.createPanel(), "centrum.manageGroups", JOptionPane.OK_CANCEL_OPTION);
}


}

【问题讨论】:

    标签: java swing jpanel joptionpane gridbaglayout


    【解决方案1】:

    你应该尝试使用更多的嵌套,因为你不能在平面布局中设置这样的布局。

    从你的描述,我明白了:

    • 包含 3 行的根面板(使用 GridBagLayout 进行设置并将所有额外的垂直空间留给最后一行)
    • 第 1 行:您的标签、您的文本字段和一个按钮--> 使用 BorderLayout
    • 第 2 行:一个组合框和 2 个按钮 --> 使用 GridBagLayout 并将所有额外空间留给组合框
    • 第 3 行:2 个标签、2 个列表和 2 个按钮 --> 使用 GridBagLayout 进行设置

    现在,要了解GridBagLayout 的一件事是weightx/weighty 不是它将分配的宽度/高度的百分比,而是如何分配“额外”空间。它将首先为每个组件指定其首选大小,然后,如果有任何额外的空间,它将根据每个组件的重量分配该空间。

    对于最后一行,每个“列”的宽度基于 2 个标签的首选大小(一个明显比另一个宽)和 2 个 JList 的首选大小(基于JList)。

    这是您的 SSCCE 的更新(尽管我不得不对其进行大量修改,因为代码有点混乱:尝试按顺序做事,首先设置您的组件,然后按照它们出现的顺序排列它们,它更易于阅读)。

    import java.awt.BorderLayout;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    
    import javax.swing.DefaultComboBoxModel;
    import javax.swing.DefaultListModel;
    import javax.swing.JDialog;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.SwingUtilities;
    
    public class SSCCE {
    
        private javax.swing.JButton addGroupButton;
        private javax.swing.JTextField addGroupTextField;
        private javax.swing.JButton addSlaveButton;
        private javax.swing.JList allSlavesList;
        private javax.swing.JButton deleteButton;
        private javax.swing.JButton deleteSlaveButton;
        private javax.swing.JComboBox groupComboBox;
        private javax.swing.JScrollPane jScrollPane2;
        private javax.swing.JScrollPane jScrollPane3;
        private javax.swing.JButton renameButton;
        private javax.swing.JLabel allSlavesLabel;
        private javax.swing.JLabel slavesInGroupLabel;
        private javax.swing.JList slavesInGroupList;
        private JLabel groupNameLabel;
    
        public SSCCE() {
    
        }
    
        public JPanel createPanel() {
            JPanel panel = new JPanel();
            panel.setLayout(new java.awt.GridBagLayout());
    
            addGroupButton = new javax.swing.JButton();
            addGroupTextField = new javax.swing.JTextField();
            addSlaveButton = new javax.swing.JButton();
            allSlavesList = new javax.swing.JList();
            deleteButton = new javax.swing.JButton();
            deleteSlaveButton = new javax.swing.JButton();
            groupComboBox = new javax.swing.JComboBox();
            jScrollPane2 = new javax.swing.JScrollPane();
            jScrollPane3 = new javax.swing.JScrollPane();
            renameButton = new javax.swing.JButton();
            allSlavesLabel = new javax.swing.JLabel("All slaves");
            slavesInGroupLabel = new javax.swing.JLabel("Devices in this group");
            groupNameLabel = new JLabel("Groupd name:");
            slavesInGroupList = new javax.swing.JList();
            groupComboBox.setModel(new DefaultComboBoxModel(new Object[] { "one", "two", "three" }));
            addGroupButton.setText("add");
            allSlavesList.setModel(new DefaultListModel());
            slavesInGroupList.setModel(new DefaultListModel());
            renameButton.setText("rename");
            deleteButton.setText("delete");
            addSlaveButton.setText("->");
            deleteSlaveButton.setText("<-");
            allSlavesList.setVisibleRowCount(4);
            jScrollPane2.setViewportView(allSlavesList);
            jScrollPane2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            ((DefaultListModel) allSlavesList.getModel()).addElement("one");
            ((DefaultListModel) allSlavesList.getModel()).addElement("two");
            ((DefaultListModel) allSlavesList.getModel()).addElement("three");
    
            ((DefaultListModel) slavesInGroupList.getModel()).addElement("one");
            ((DefaultListModel) slavesInGroupList.getModel()).addElement("two");
            ((DefaultListModel) slavesInGroupList.getModel()).addElement("three");
            slavesInGroupList.setVisibleRowCount(4);
            jScrollPane3.setViewportView(slavesInGroupList);
            jScrollPane3.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    
            // Let's split your display in 3 rows
            panel = new JPanel(new GridBagLayout());
            JPanel row1 = new JPanel(new BorderLayout(3, 3));
            JPanel row2 = new JPanel(new GridBagLayout());
            JPanel row3 = new JPanel(new GridBagLayout());
    
            // Use GBL to make three rows and give all extra vertical space to the last one
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1.0;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.insets = new Insets(3, 3, 3, 3);
            panel.add(row1, gbc);
            panel.add(row2, gbc);
            // Gives all extra v-space to last row
            gbc.weighty = 1.0;
            panel.add(row3, gbc);
    
            GridBagConstraints gridBagConstraints;
    
            // Set up row 1
            row1.add(groupNameLabel, BorderLayout.WEST);
            row1.add(addGroupButton, BorderLayout.EAST);
            row1.add(addGroupTextField);// In the middle so that it takes all the width and it won't stretch vertically because row1 has weighty
                                        // set to 0.0
    
            // Set up row 2
            // We give all extra space to the combo box
            gbc = new java.awt.GridBagConstraints();
            gbc.insets = new Insets(3, 3, 3, 3);
            gbc.fill = java.awt.GridBagConstraints.HORIZONTAL;
            gbc.weightx = 1;
            row2.add(groupComboBox, gbc);
            gbc.weightx = 0;
            row2.add(deleteButton, gbc);
            row2.add(renameButton, gbc);
    
            // Set up row3
            gbc = new java.awt.GridBagConstraints();
            gbc.insets = new Insets(3, 3, 3, 3);
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.weightx = 1.0;
            gbc.anchor = GridBagConstraints.WEST;
            row3.add(allSlavesLabel, gbc);
            gbc.gridx = 2;
            row3.add(slavesInGroupLabel, gbc);
    
            gbc.weighty = 1.0;
            gbc.weightx = 1.0;
            gbc.gridheight = 2;
            gbc.gridx = 0;
            gbc.gridy = 1;
            gbc.fill = GridBagConstraints.BOTH;
    
            row3.add(jScrollPane2, gbc);
            gbc.fill = GridBagConstraints.NONE;
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.gridheight = 1;
            gbc.gridx = 1;
            gbc.weightx = 0;
            row3.add(addSlaveButton, gbc);
            gbc.gridy = 2;
            row3.add(deleteSlaveButton, gbc);
    
            gbc.gridheight = 2;
            gbc.gridx = 2;
            gbc.gridy = 1;
            gbc.fill = GridBagConstraints.BOTH;
    
            row3.add(jScrollPane3, gbc);
    
            return panel;
    
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    SSCCE a = new SSCCE();
                    JDialog dialog = new JDialog();
                    dialog.add(a.createPanel());
                    dialog.pack();
                    dialog.setLocationRelativeTo(null);
                    dialog.setVisible(true);
                    // JOptionPane.showConfirmDialog(null, a.createPanel(), "centrum.manageGroups", JOptionPane.OK_CANCEL_OPTION);
                }
            });
        }
    
    }
    

    【讨论】:

    • 感谢您的回复。但是我的实际问题是,右侧的 Jlist 比左侧的 Jlist 宽仍然存在于您的代码中。我通过添加 panel.setPreferredSize(new Dimension(600,300)); 使面板更宽。在返回语句之前。这样标签与 Jlist 相比变得更小(因此它不应该对 Jlist 大小产生影响)但是正确的 Jlist 仍然很宽。这将如何解决。
    • @Alptugay 如上所述,问题在于您有 2 个宽度不同的标签,它们是影响这些列大小的标签。由于“此组中的设备”比“所有设备”宽得多,因此列的宽度不同。到目前为止,我还没有真正找到一个真正干净的解决方案。一种方法是根据两个标签的最大首选大小设置这两个标签的首选大小,但这不是很干净,并且不支持在运行时切换 L&F。
    • 就可以了。将两个标签的 prefferedSize 设置为更宽标签的 maximumSize 就可以了。这对我来说已经足够了。感谢您的帮助。
    • @Alptugay 请记住,这是一个丑陋的技巧,您应该尽量避免设置首选大小。设置首选尺寸几乎总是会让事情变得更糟。
    猜你喜欢
    • 1970-01-01
    • 2011-01-05
    • 2019-10-11
    • 2013-02-06
    • 2018-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多