SeverelyConfused
SeverelyConfused

Reputation: 55

Aligning objects with GridBagLayout

I'm trying to create a calculator that computes the area and circumference/perimeters of triangles, circles, and rectangles. I have almost everything done but can't for the life of me figure out how to get the GridBagLayout to work. Here is an album of what I currently have and what I want it to look like. I've pasted my GridBagLayout for just my triangle calculations since that is giving me the most difficult time.

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

In between here I have an ActionListener set up for the "Calculate" button. In the ActionListener I have another panel that shows up after the calculate button is pressed. Then finally I add the panel to the frame and set the frame as visible.

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

Upvotes: 0

Views: 175

Answers (1)

Jan Bodnar
Jan Bodnar

Reputation: 11637

You have to pass the instance of the GridBagConstrains to the add() method.

Also note that it is not necessary to write "Enter height:" (it is probably even against the design guidelines), instead we write "Height:".

GridBagLayout example:

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);
            }
        });
    }
}

Instead of the image, I have used a panel with an etched border.

GridBaglayout triangle

Your layout is a very simple one and you are having difficult time for a reason. While GridBagLayout is a flexible layout manager, it is a complicated one. This stems from the fact that we need to define each cell individually.

I have also created two examples with MigLayout manager and GroupLayout manager. They are easier to use and more portable. (One of the big drawbacks of the GridBagLayout manager is that it is not resolution independent.)

MigLayout solution

MigLayout is a very flexible third-party layout manager. I find it always the easiest to create a layout with this manager. The manager is resolution independent.

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);
            }
        });
    }
}

MigLayout triangle

GroupLayout solution

GroupLayout is IMO the most powerful built-in manager. The interesting thing about this manager is that is has only a few options to set but it is very capable. The manager is also resolution independent. GroupLayout is also the default manager used by NetBeans GUI builder.

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);
            }
        });
    }
}

The groups were judiciously chosen in order to have the labels right-aligned.

GroupLayout triangle

Upvotes: 1

Related Questions