【问题标题】:Aligning objects with GridBagLayout使用 GridBagLayout 对齐对象
【发布时间】:2014-08-05 23:28:09
【问题描述】:

我正在尝试创建一个计算器来计算三角形、圆形和矩形的面积和周长/周长。我几乎完成了所有工作,但我一生都无法弄清楚如何让 GridBagLayout 工作。 Here 是一张我目前拥有的专辑以及我想要它的样子。我粘贴了我的 GridBagLayout 仅用于我的三角形计算,因为这给了我最困难的时间。

final JPanel triPanel = new JPanel(new GridBagLayout());    
final GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 0, 0);

    gbc.gridx = 0;
    gbc.gridy = 0;
    triPanel.add(heightInt); //height instructions
    gbc.gridx = 1;
    gbc.gridy = 0;
    triPanel.add(triHeight); //height textfield
    gbc.gridx = 2;
    gbc.gridy = 0;
    triPanel.add(baseInt); //base instructions
    gbc.gridx = 3;
    gbc.gridy = 0;
    triPanel.add(triBase); //base textfield
    gbc.gridx = 0;
    gbc.gridy = 1;
    triPanel.add(side2Int); //side2 instructions
    gbc.gridx = 1;
    gbc.gridy = 1;
    triPanel.add(triSide2); //side2 textfield
    gbc.gridx = 2;
    gbc.gridy = 1;
    triPanel.add(side3Int); //side3 instructions
    gbc.gridx = 3;
    gbc.gridy = 1;
    triPanel.add(triSide3); //side3 textfield
    gbc.gridx = 0;
    gbc.gridy = 2;
    triPanel.add(rectCalc); //calculate button
    gbc.gridx = 0;
    gbc.gridy = 3;
    triPanel.add(Triangle); //image

在这之间,我为“计算”按钮设置了一个 ActionListener。在 ActionListener 中,按下计算按钮后会显示另一个面板。最后,我将面板添加到框架中并将框架设置为可见。

triJFRame.add(triPanel);
triJFRame.setVisible(true);

【问题讨论】:

  • 我想你会发现用更简单的布局做嵌套面板更容易。
  • 是的,嵌套面板或 GridLayout,而不是 GridBagLayout。 GridBagLayout 用于自动化 GUI 布局工具。这是只有电脑才会喜欢的东西。

标签: java gridbaglayout


【解决方案1】:

您必须将GridBagConstrains 的实例传递给add() 方法。

还要注意,不必写“输入高度:”(可能是 甚至违反设计指南),而是写“高度:”。

GridBagLayout 示例

package com.zetcode;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class GridBagLayoutTriangle extends JFrame {

    public GridBagLayoutTriangle() {

        initUI();

        setTitle("Triangle");
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void initUI() {

        JPanel imgPanel = new JPanel();
        imgPanel.setPreferredSize(new Dimension(150, 150));
        imgPanel.setBorder(BorderFactory.createEtchedBorder());

        final JPanel triPanel = new JPanel(new GridBagLayout());
        triPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5));
        final GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets.left = 5;
        gbc.insets.top = 5;

        triPanel.add(new JLabel("Height:"), gbc); 

        gbc.gridx = 1;
        triPanel.add(new JTextField(10), gbc); 

        gbc.gridx = 2;
        triPanel.add(new JLabel("Base:"), gbc); 

        gbc.gridx = 3;
        triPanel.add(new JTextField(10), gbc); 

        gbc.gridx = 0;
        gbc.gridy = 1;
        triPanel.add(new JLabel("Side 2:"), gbc); 

        gbc.gridx = 1;
        triPanel.add(new JTextField(10), gbc); 

        gbc.gridx = 2;
        triPanel.add(new JLabel("Side 3:"), gbc); 

        gbc.gridx = 3;
        triPanel.add(new JTextField(10), gbc); 

        gbc.gridx = 0;
        gbc.gridy = 2;
        gbc.gridwidth = 4;
        gbc.insets.top = 10;
        gbc.fill = GridBagConstraints.CENTER;
        triPanel.add(new JButton("Calculate"), gbc); 

        gbc.gridy = 3;
        gbc.insets.bottom = 10;
        triPanel.add(imgPanel, gbc); 

        add(triPanel);

        pack();
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                GridBagLayoutTriangle ex = new GridBagLayoutTriangle();
                ex.setVisible(true);
            }
        });
    }
}

我使用了带有蚀刻边框的面板,而不是图像。

您的布局非常简单,您遇到困难是有原因的。 虽然GridBagLayout 是一个灵活的布局管理器,但它是一个复杂的管理器。 这源于我们需要单独定义每个单元格的事实。

我还使用MigLayout manager 和GroupLayout manager 创建了两个示例。 它们更易于使用且更便携。 (GridBagLayout 的一大缺点 manager 是它不是独立于分辨率的。)

MigLayout 解决方案

MigLayout 是一个非常灵活的第三方布局管理器。我发现它总是最简单的 使用此管理器创建布局。经理独立于决议。

package com.zetcode;

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;


public class MigLayoutTriangle extends JFrame {

    public MigLayoutTriangle() {

        initUI();

        setTitle("MigLayout triangle");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private void initUI() {

        JPanel imgPanel = new JPanel();
        imgPanel.setPreferredSize(new Dimension(150, 150));
        imgPanel.setBorder(BorderFactory.createEtchedBorder());        

        JPanel pnl = new JPanel(new MigLayout("wrap 5", "[right][][right]"));

        pnl.add(new JLabel("Height:"));
        pnl.add(new JTextField(10));
        pnl.add(new JLabel("Base:"));
        pnl.add(new JTextField(10), "wrap");

        pnl.add(new JLabel("Side 2:"));
        pnl.add(new JTextField(10));
        pnl.add(new JLabel("Side 3:"));
        pnl.add(new JTextField(10), "wrap");      

        pnl.add(new JButton("Calculate"), "spanx, center");
        pnl.add(imgPanel, "spanx, center");

        add(pnl);

        pack();
    }


    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutTriangle ex = new MigLayoutTriangle();
                ex.setVisible(true);
            }
        });
    }
}

GroupLayout 解决方案

GroupLayout 是 IMO 最强大的内置管理器。关于有趣的事情 这个经理只有几个选项可以设置,但它非常有能力。管理者 也是独立于分辨率的。 GroupLayout 也是使用的默认管理器 NetBeans GUI 构建器。

package com.zetcode;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import static javax.swing.GroupLayout.Alignment.BASELINE;
import static javax.swing.GroupLayout.Alignment.CENTER;
import static javax.swing.GroupLayout.Alignment.TRAILING;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle;


public class GroupLayoutTriangle extends JFrame {

    public GroupLayoutTriangle() {

        initUI();

        setTitle("GroupLayout triangle");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private void initUI() {

        Container pane = getContentPane();
        GroupLayout gl = new GroupLayout(pane);
        pane.setLayout(gl);

        JLabel heightLbl = new JLabel("Height:");
        JLabel baseLbl = new JLabel("Base:");
        JLabel side2Lbl = new JLabel("Side 2:");
        JLabel side3Lbl = new JLabel("Side 3:");

        JTextField field1 = new JTextField(10);
        JTextField field2 = new JTextField(10);
        JTextField field3 = new JTextField(10);
        JTextField field4 = new JTextField(10);

        JButton calcBtn = new JButton("Calculate");

        JPanel imgPanel = new JPanel();
        imgPanel.setPreferredSize(new Dimension(150, 150));
        imgPanel.setMaximumSize(new Dimension(150, 150));
        imgPanel.setBorder(BorderFactory.createEtchedBorder());          

        gl.setAutoCreateGaps(true);
        gl.setAutoCreateContainerGaps(true);   

        gl.setHorizontalGroup(gl.createParallelGroup(CENTER)
                .addGroup(gl.createSequentialGroup()
                        .addGroup(gl.createParallelGroup(TRAILING)
                                .addComponent(heightLbl)
                                .addComponent(side2Lbl))
                        .addGroup(gl.createParallelGroup()
                                .addComponent(field1)
                                .addComponent(field3))
                        .addGroup(gl.createParallelGroup(TRAILING)
                                .addComponent(baseLbl)
                                .addComponent(side3Lbl))
                        .addGroup(gl.createParallelGroup()
                                .addComponent(field2)
                                .addComponent(field4)))
                .addComponent(calcBtn)
                .addComponent(imgPanel)
        );

        gl.setVerticalGroup(gl.createSequentialGroup()
                 .addGroup(gl.createParallelGroup(BASELINE)
                        .addComponent(heightLbl)
                        .addComponent(field1)
                        .addComponent(baseLbl)
                        .addComponent(field2))
                .addGroup(gl.createParallelGroup(BASELINE)
                        .addComponent(side2Lbl)
                        .addComponent(field3)
                        .addComponent(side3Lbl)
                        .addComponent(field4))
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(calcBtn)
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(imgPanel)
        );

        pack();
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                GroupLayoutTriangle ex = new GroupLayoutTriangle();
                ex.setVisible(true);
            }
        });
    }
}

为了使标签右对齐,明智地选择了这些组。

【讨论】:

  • 哇,感谢您对 GridBagLayout 替代方案的详尽解释!是的,从 FlowLayout 迁移到 GridBagLayout 对我来说是非常雄心勃勃的。我想我应该对 Java GUI 有更多的经验。你写的正是我想做的。再次感谢!
猜你喜欢
  • 2015-04-05
  • 2012-05-20
  • 2014-06-04
  • 2013-01-23
  • 2012-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多