I am coding a custom JPanel, call it MyPanel, by hand which contains two JLabels and two JTextBoxes. This JPanel will be used in a JFrame which contains other JPanels using a CardLayout. The JFrame is non-resizeable; its size is fixed based on the JPanel which has the most components.
Since MyPanel is sparse on controls, I am trying to figure out the best layout manager to use. I want the labels and text fields to appear close to the top with all the extra space at the bottom. I believe GridBagLayout provides the functionality to get this panel to look the way I want. MyPanel has the following initComponents() method which is called from the constructor:
public class MyPanel extends JPanel {
public static void main(String[] args) {
JFrame frame = new JFrame("MyPanel Test");
frame.add(new MyPanel(null));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 425);
frame.setVisible(true);
}
public MyPanel() {
initComponents();
}
private void initComponents() {
this.setLayout(new GridBagLayout());
JLabel cardYearLabel = new JLabel("Card Year:");
cardYearLabel.setFont(new Font("Tahoma", 0, 14)); // NOI18N
GridBagConstraints yearLabelConstraints = new GridBagConstraints();
yearLabelConstraints.gridx = 0;
yearLabelConstraints.gridy = 0;
yearLabelConstraints.weightx = 1;
yearLabelConstraints.weighty = 1;
yearLabelConstraints.anchor = GridBagConstraints.WEST;
yearLabelConstraints.insets = new Insets(20, 50, 10, 10);
this.add(cardYearLabel, yearLabelConstraints);
this.yearTextField = new JFormattedTextField();
this.yearTextField.setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter(new DecimalFormat("#0"))));
this.yearTextField.setFont(new Font("Tahoma", 0, 14)); // NOI18N
this.yearTextField.setColumns(10);
this.yearTextField.addFocusListener(new UpdateInstructionsFocusListener("Enter card year."));
GridBagConstraints yearTextFieldConstraints = new GridBagConstraints();
yearTextFieldConstraints.gridx = 1;
yearTextFieldConstraints.gridy = 0;
yearTextFieldConstraints.weightx = 2;
yearTextFieldConstraints.weighty = 1;
yearTextFieldConstraints.fill = GridBagConstraints.HORIZONTAL;
yearTextFieldConstraints.insets = new Insets(20, 10, 10, 50);
this.add(this.yearTextField, yearTextFieldConstraints);
JLabel cardNumberLabel = new JLabel("Card Number:");
cardNumberLabel.setFont(new Font("Tahoma", 0, 14)); // NOI18N
GridBagConstraints numberLabelConstraints = new GridBagConstraints();
numberLabelConstraints.gridx = 0;
numberLabelConstraints.gridy = 1;
numberLabelConstraints.weightx = 1;
numberLabelConstraints.weighty = 1;
numberLabelConstraints.anchor = GridBagConstraints.WEST;
numberLabelConstraints.insets = new Insets(10, 50, 0, 10);
this.add(cardNumberLabel, numberLabelConstraints);
this.numberTextField = new JFormattedTextField();
this.numberTextField.setFormatterFactory(new DefaultFormatterFactory(new NumberFormatter(new DecimalFormat("#0"))));
this.numberTextField.setFont(new Font("Tahoma", 0, 14)); // NOI18N
this.numberTextField.setColumns(10);
this.numberTextField.addFocusListener(new UpdateInstructionsFocusListener("Enter card number."));
GridBagConstraints numberTextFieldConstraints = new GridBagConstraints();
numberTextFieldConstraints.gridx = 1;
numberTextFieldConstraints.gridy = 1;
numberTextFieldConstraints.weightx = 2;
numberTextFieldConstraints.weighty = 1;
numberTextFieldConstraints.fill = GridBagConstraints.HORIZONTAL;
numberTextFieldConstraints.insets = new Insets(10, 10, 0, 50);
this.add(this.numberTextField, numberTextFieldConstraints);
JPanel filler = new JPanel();
GridBagConstraints fillerConstraints = new GridBagConstraints();
fillerConstraints.gridx = 0;
fillerConstraints.gridy = 2;
fillerConstraints.gridwidth = 2;
fillerConstraints.weightx = 1;
fillerConstraints.weighty = 100;
this.add(filler, fillerConstraints);
}
}
I cringe at using a blank JPanel to fill up the empty space at the bottom of MyPanel. Is there a better, more elegant way to do this? (I’m not stuck on using GridBagLayout. If another standard LayoutManager can do this, I’m all for it.)
One way to achieve this is to put the controls in a panel, then add that panel to the
PAGE_STARTof a 2nd panel with aBorderLayout.