Reputation: 55
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
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.
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);
}
});
}
}
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.
Upvotes: 1