【问题标题】:Java GridBagLayout : make component align to leftJava GridBagLayout:使组件左对齐
【发布时间】:2012-10-05 19:54:32
【问题描述】:

我有这个布局使用GridBagLayout:

public class Example extends JFrame {
    public Example() {
        Border outline = BorderFactory.createLineBorder(Color.black);
        GridBagLayout gbl = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();
        JPanel pane = new JPanel(gbl);

        gbc.weighty = 1.0;
        gbc.weightx = 1.0;

        JLabel unitLbl = new JLabel("Unit");
        unitLbl.setBorder(outline);
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.ipadx = 30;
        gbc.ipady = 10;
        gbl.setConstraints(unitLbl, gbc);
        pane.add(unitLbl);

        JLabel typeLbl = new JLabel("Type");
        typeLbl.setBorder(outline);
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.ipadx = 30;
        gbc.ipady = 10;
        gbl.setConstraints(typeLbl, gbc);
        pane.add(typeLbl);

        JTextField unitField = new JTextField();
        typeLbl.setBorder(outline);
        gbc.gridx = 1;
        gbc.gridy = 0;
        gbc.ipadx = 30;
        gbc.ipady = 10;
        gbl.setConstraints(unitField, gbc);
        pane.add(unitField);

        String[] type = {"All", "Verb", "Noun", "Adjective"};
        JComboBox<String> comboBox = new JComboBox<String>(type);
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.ipadx = 30;
        gbc.ipady = 10;
        gbl.setConstraints(comboBox, gbc);
        pane.add(comboBox);


        add(pane, BorderLayout.CENTER);
        setSize(new Dimension(400, 300));
        getContentPane().setBackground(Color.WHITE);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Example();
            }
        });
    }
}

在这个例子中,当运行时,似乎每个组件都在框架的中心。但我想要的是:

  1. 两个JLabelunitLbltypelbl)将位于框架的左侧
  2. JTextFieldJComboBox 将分别位于两个 JLabel 的右侧,两者之间的距离很小。
  3. 此外,我想在网格的位置 (3,0) 添加一个新的JButton,但这个位置的高度是两个JLabel 高度的总和。这意味着,此按钮高度在“两行”上。

如何修复此代码以实现此目标?请帮帮我。

谢谢:)

【问题讨论】:

    标签: java swing gridbaglayout


    【解决方案1】:

    这样的事情应该可以解决问题:

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    
    public class Example extends JFrame {
        public Example() {
            GridBagLayout gbl = new GridBagLayout();
            GridBagConstraints gbc = new GridBagConstraints();
            JPanel pane = new JPanel(gbl);
            gbc.anchor = GridBagConstraints.WEST;
    
            JLabel unitLbl = new JLabel("Unit");
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(3, 3, 3, 30);
            gbl.setConstraints(unitLbl, gbc);
            pane.add(unitLbl);
    
            JLabel typeLbl = new JLabel("Type");
            gbc.gridx = 0;
            gbc.gridy = 1;
            gbl.setConstraints(typeLbl, gbc);
            pane.add(typeLbl);
    
            gbc.weightx = 1.0;
            gbc.insets = new Insets(3, 3, 3, 3);
    
            JTextField unitField = new JTextField();
            gbc.gridx = 1;
            gbc.gridy = 0;
            gbc.fill = GridBagConstraints.BOTH;
            gbl.setConstraints(unitField, gbc);
            pane.add(unitField);
    
            String[] type = { "All", "Verb", "Noun", "Adjective" };
            JComboBox<String> comboBox = new JComboBox<String>(type);
            gbc.gridx = 1;
            gbc.gridy = 1;
            gbc.fill = GridBagConstraints.NONE;
            gbl.setConstraints(comboBox, gbc);
            pane.add(comboBox);
    
            final JButton someButton = new JButton("Click me");
            someButton.addActionListener(new ActionListener() {
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    JOptionPane.showMessageDialog(someButton, "You have clicked " + someButton.getText());
                }
            });
    
            gbc.gridx = 3;
            gbc.gridy = 0;
            gbc.gridheight = 2;
            gbc.fill = GridBagConstraints.VERTICAL;
            pane.add(someButton, gbc);
            add(pane, BorderLayout.CENTER);
            setSize(new Dimension(400, 300));
            getContentPane().setBackground(Color.WHITE);
            setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Example();
                }
            });
        }
    }
    
    • 需要适当使用weightx/weighty(多余的横向/纵向空间如何重新分配)
    • 使用适当的fill 属性(组件是否垂直/水平/同时拉伸?)
    • 使用适当的anchor 属性(如果组件没有被拉伸,或者至少不是双向拉伸,那么它应该位于其单元格内的哪个位置)
    • 我通常更喜欢使用 insets 而不是 padding,因此,我更喜欢 insets 而不是 ipadx/ipady(应该在组件周围或组件内部添加额外的空白)

    【讨论】:

      【解决方案2】:

      您想使用GridBagConsraints#anchor 来定义单元格内要将组件对齐到的位置。

      要允许组件跨越多个单元格,您需要使用 GridBagConstraints#gridwidthGridBagConstraints#gridheight(默认为 1)

      public class TestLayout09 {
      
          public static void main(String[] args) {
              new TestLayout09();
          }
      
          public TestLayout09() {
              EventQueue.invokeLater(new Runnable() {
                  @Override
                  public void run() {
                      try {
                          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                      } catch (ClassNotFoundException ex) {
                      } catch (InstantiationException ex) {
                      } catch (IllegalAccessException ex) {
                      } catch (UnsupportedLookAndFeelException ex) {
                      }
      
                      JFrame frame = new JFrame();
                      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                      frame.setLayout(new BorderLayout());
                      frame.add(new LayoutPane());
                      frame.setBackground(Color.WHITE);
                      frame.pack();
                      frame.setLocationRelativeTo(null);
                      frame.setVisible(true);
                  }
      
              });
          }
      
          public class LayoutPane extends JPanel {
      
              public LayoutPane() {
                  Border outline = BorderFactory.createLineBorder(Color.black);
                  setLayout(new GridBagLayout());
                  GridBagConstraints gbc = new GridBagConstraints();
      
                  // I'm not sure this really is what you want, but I may be mistaken
      //            gbc.weighty = 1.0;
      //            gbc.weightx = 1.0;
      
                  JLabel unitLbl = new JLabel("Unit");
                  unitLbl.setBorder(outline);
                  gbc.gridx = 0;
                  gbc.gridy = 0;
                  gbc.ipadx = 30;
                  gbc.ipady = 10;
                  gbc.anchor = GridBagConstraints.WEST;
                  add(unitLbl, gbc);
      
                  JLabel typeLbl = new JLabel("Type");
                  typeLbl.setBorder(outline);
                  gbc.gridx = 0;
                  gbc.gridy = 1;
                  gbc.ipadx = 30;
                  gbc.ipady = 10;
                  add(typeLbl, gbc);
      
                  JTextField unitField = new JTextField();
                  typeLbl.setBorder(outline);
                  gbc.gridx = 1;
                  gbc.gridy = 0;
                  gbc.ipadx = 30;
                  gbc.ipady = 10;
                  gbc.anchor = GridBagConstraints.EAST;
                  add(unitField, gbc);
      
                  String[] type = {"All", "Verb", "Noun", "Adjective"};
                  JComboBox<String> comboBox = new JComboBox<String>(type);
                  gbc.gridx = 1;
                  gbc.gridy = 1;
                  gbc.ipadx = 30;
                  gbc.ipady = 10;
                  add(comboBox, gbc);
      
                  JButton btn = new JButton("Test");
                  gbc.gridx = 3;
                  gbc.gridy = 0;
                  gbc.fill = GridBagConstraints.BOTH;
                  gbc.gridheight = 2;
                  add(btn, gbc);
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        一些答案​​:

        将 unitlbl 的锚点放在 WEST。

        gbc.anchor = GridBagConstraints.WEST;
        

        还有 unitField 到 EAST 的锚点。

        gbc.anchor = GridBagConstraints.EAST;
        

        对于按钮:

        JButton button = new JButton("Test");
        gbc.fill = GridBagConstraints.VERTICAL;
        gbc.gridx = 3;
        gbc.gridy = 0;
        gbc.gridwidth = 1;
        gbc.gridheight = 2;
        gbc.weighty = 1;
        pane.add(button, gbc);
        

        【讨论】:

          猜你喜欢
          • 2014-06-04
          • 2012-07-09
          • 2018-01-13
          • 2021-06-21
          • 2015-04-05
          • 1970-01-01
          • 1970-01-01
          • 2021-10-02
          • 2013-06-10
          相关资源
          最近更新 更多