Java GUI alignment
So I have my shortcuts and everything added, but I still have problems with formatting and aligning everything. Obviously, the calculate button should be centered. I understand that using a gridbag splits the frame into a coordinate system, and when one column is larger than the others, it will adjust the others and throw it away (right?). But I don't understand how to fix this. And there is still a problem with aligning everything to the left so that it doesn't start towards the center.
When compiled heres a window
Here is what I'm trying to get, looks like I haven't added everything yet.
JPanel p = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
//0 Column
gc.gridx = 0;
gc.gridy = 0;
gc.anchor = GridBagConstraints.EAST;
p.add(new JLabel("Mortgage amount:"),gc);
gc.gridx = 0;
gc.gridy =1;
p.add(new JLabel("Mortgage term:"),gc);
gc.gridx = 0;
gc.gridy = 2;
p.add(new JLabel("Interest rate:"),gc);
gc.gridx = 0;
gc.gridy = 3;
p.add(new JLabel("Mortgage start date:"),gc);
gc.gridx = 0;
gc.gridy= 4;
p.add(new JLabel("Monthly Payments:"),gc);
gc.gridx = 0;
gc.gridy = 7;
p.add(new JLabel("Extra payments"),gc);
gc.gridx = 0;
gc.gridy = 8;
p.add(new JLabel("Adding: "),gc);
gc.gridx = 0;
gc.gridy = 9;
p.add(new JLabel("Adding: "),gc);
gc.gridx = 0;
gc.gridy = 10;
p.add(new JLabel("Adding: "),gc);
gc.gridx = 0;
gc.gridy = 11;
p.add(new JLabel("Changes paid off date to:"),gc);
//1 Column
gc.gridx = 1;
gc.gridy = 0;
p.add(new JLabel("$"),gc);
gc.gridx = 1;
gc.gridy = 4;
p.add(new JLabel("$"),gc);
gc.gridx = 1;
gc.gridy = 8;
p.add(new JLabel("$"),gc);
gc.gridx = 1;
gc.gridy = 9;
p.add(new JLabel("$"),gc);
gc.gridx = 1;
gc.gridy = 10;
p.add(new JLabel("$"),gc);
//2 column
gc.gridx = 2;
gc.gridy = 0;
p.add(new JTextField(8),gc);
gc.gridx = 2;
gc.gridy =1;
p.add(new JTextField(8),gc);
gc.gridx = 2;
gc.gridy = 2;
p.add(new JTextField(8),gc);
gc.gridx = 2;
gc.gridy = 3;
p.add(new JComboBox(month),gc);
gc.gridx= 2;
gc.gridy = 4;
p.add(new JTextField(8),gc);
gc.gridx = 2;
gc.gridy = 8;
p.add(new JTextField(8),gc);
gc.gridx = 2;
gc.gridy = 9;
p.add(new JTextField(8),gc);
gc.gridx = 2;
gc.gridy = 10;
p.add(new JTextField(8),gc);
//3 column
gc.gridx = 3;
gc.gridy = 1;
p.add(new JLabel(" years or "),gc);
gc.gridx = 3;
gc.gridy = 2;
p.add(new JLabel(" % per year"),gc);
gc.gridx = 3;
gc.gridy = 3;
p.add(new JComboBox(days),gc);
gc.gridx = 3;
gc.gridy = 8;
p.add(new JLabel("to your monthly mortgage payment"),gc);
gc.gridx = 3;
gc.gridy = 9;
p.add(new JLabel("as an extra yearly mortgage payment every "),gc);
gc.gridx = 3;
gc.gridy = 10;
p.add(new JLabel("as a one-time payment in "),gc);
//4 column
gc.gridx = 4;
gc.gridy = 1;
p.add(new JTextField(8),gc);
gc.gridx = 4;
gc.gridy=3;
p.add(new JComboBox(years),gc);
//5 column
gc.gridx = 5;
gc.gridy = 1;
p.add(new JLabel(" months"),gc);
gc.gridy=5;
gc.anchor = GridBagConstraints.CENTER;
p.add(new JButton("Calculate"),gc);
add(p, BorderLayout.NORTH);
}
}
source to share
Since you didn't specify the resizing behavior, many layout managers can be used to produce very similar results. As @MadProgrammer mentioned, the 2 panels are probably a good approach, where for the top one I used GridBagLayout
for educational purposes and the bottom one I left blank for you to implement yourself, although it will not benefit from GridBagLayout
and a simpler layout manager can be used ( for example BoxLayout
).
public class Mort extends JFrame {
public static void main(String[] args) {
new Mort();
}
Mort() {
JPanel topPanel = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JPanel tempPanel;
gc.anchor = GridBagConstraints.LINE_START;
// Top
// 0 Column
gc.gridx = 0;
gc.gridy = 0;
topPanel.add(new JLabel("Mortgage amount:"), gc);
gc.gridy = 1;
topPanel.add(new JLabel("Mortgage term:"), gc);
gc.gridy = 2;
topPanel.add(new JLabel("Interest rate:"), gc);
gc.gridy = 3;
topPanel.add(new JLabel("Mortgage start date:"), gc);
gc.gridy = 4;
topPanel.add(new JLabel("Monthly Payments:"), gc);
gc.gridy = 5;
gc.gridwidth = GridBagConstraints.REMAINDER;
gc.anchor = GridBagConstraints.CENTER;
topPanel.add(new JButton("Calculate"), gc);
gc.gridwidth = 1;
gc.anchor = GridBagConstraints.LINE_START;
// 1 Column
gc.gridx = 1;
gc.gridy = 0;
tempPanel = new JPanel();
tempPanel.add(new JLabel("$"));
tempPanel.add(new JTextField(8));
topPanel.add(tempPanel, gc);
gc.gridy = 1;
tempPanel = new JPanel();
tempPanel.add(new JTextField(8));
tempPanel.add(new JLabel("years of"));
tempPanel.add(new JTextField(8));
tempPanel.add(new JLabel("months"));
topPanel.add(tempPanel, gc);
gc.gridy = 2;
tempPanel = new JPanel();
tempPanel.add(new JTextField(8));
tempPanel.add(new JLabel("% per year"));
topPanel.add(tempPanel, gc);
gc.gridy = 3;
tempPanel = new JPanel();
tempPanel.add(new JComboBox());
tempPanel.add(new JComboBox());
tempPanel.add(new JComboBox());
topPanel.add(tempPanel, gc);
gc.gridy = 4;
tempPanel = new JPanel();
tempPanel.add(new JLabel("$"));
tempPanel.add(new JTextField(8));
topPanel.add(tempPanel, gc);
// Bottom
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JLabel("BottomPanel"));
// Main
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
mainPanel.add(new JLabel("Mortgage Calculator"));
mainPanel.add(new JSeparator());
mainPanel.add(topPanel);
mainPanel.add(new JSeparator());
mainPanel.add(bottomPanel);
getContentPane().add(mainPanel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
To answer your special concerns:
-
You were missing a line
gc.anchor = GridBagConstraints.LINE_START;
that aligns everything to the left as you wanted. -
It doesn't make sense to have more than two columns because there are only 2 spaces to be vertically aligned.
-
The Calculate button is outside the column alignment (it is centered on both columns). Row
gc.gridwidth = GridBagConstraints.REMAINDER;
means that it should span (fill) the rest of the columns to the right, and the rowgc.anchor = GridBagConstraints.CENTER;
aligns it to the center.
I keep all visuals (colors, fonts, spacers, inserts, etc.).
source to share