i have GridBagLayout where I add a JLabel, a JTextfield. But it come out with unpredictable range
Source
public void siswa(){
panel_siswa = new JPanel(); //The Panel
panel_siswa.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(0, 0, 0, 0);
gbc.anchor = GridBagConstraints.CENTER;
label = new JLabel("CEK NILAI");
label.setFont(new Font("Arial", Font.BOLD, 18));
label_id = new JLabel("ID :");
label_name = new JLabel("Name :");
label_id2 = new JLabel("");
label_name2 = new JLabel("");
label_semester = new JLabel("Semester :");
label_semester2 = new JLabel("");
label_jurusan = new JLabel("Jurusan :");
label_jurusan2 = new JLabel("");
label_nilai1 = new JLabel(MP1);
label_nilai2 = new JLabel(MP2);
label_nilai3 = new JLabel(MP3);
label_nilai4 = new JLabel(MP4);
label_nilai5 = new JLabel(MP5);
tf_nilai1 = new JTextField();
tf_nilai2 = new JTextField();
tf_nilai3 = new JTextField();
tf_nilai4 = new JTextField();
tf_nilai5 = new JTextField();
send = new JButton("Send to my email");
gbc.weightx = 0.0;
gbc.gridwidth = 4;
gbc.gridx = 1;
gbc.gridy = 0;
panel_siswa.add(label,gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
panel_siswa.add(label_id,gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 1;
panel_siswa.add(label_id2,gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 1;
panel_siswa.add(label_jurusan,gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 4;
gbc.gridy = 1;
panel_siswa.add(label_jurusan2,gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 2;
panel_siswa.add(label_name, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 2;
panel_siswa.add(label_name2, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 2;
panel_siswa.add(label_semester,gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 4;
gbc.gridy = 2;
panel_siswa.add(label_semester2,gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 4;
panel_siswa.add(label_nilai1, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 4;
panel_siswa.add(tf_nilai1, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 5;
panel_siswa.add(label_nilai2, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 5;
panel_siswa.add(tf_nilai2, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 6;
panel_siswa.add(label_nilai3, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 6;
panel_siswa.add(tf_nilai3, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 7;
panel_siswa.add(label_nilai4, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 7;
panel_siswa.add(tf_nilai4, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 8;
panel_siswa.add(label_nilai5, gbc);
gbc.weightx = 0.5;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 3;
gbc.gridy = 8;
panel_siswa.add(tf_nilai5, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridy++;
panel_siswa.add(send);
}
}
Output
Problem Statement
I was expecting it will come out like picture below but its not. i think i have a problem on the source.
Question
is my source about gridbaglayout already great ? how to design it properly ?
You create a GUI like this with nested JPanels. Each JPanel can use the layout manager that's best suited for the particular JPanel.
Here's the GUI:
I created a main JPanel to hold all of the subordinate JPanels. The main JPanel uses a BoxLayout, page orientation.
The JPanel that holds the title uses a FlowLayout.
The JPanel that holds the student information uses a GridBagLayout.
The JPanel that holds the MP information uses a different GridBagLayout.
The JPanel that holds the submit button uses a FlowLayout.
Here's the code. This is what is meant by a short, self-contained, runnable example of the solution.
package com.ggl.testing;
import java.awt.Component;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class StudentDataEditor implements Runnable {
private static final Insets normalInsets = new Insets(10, 10, 0, 10);
private static final Insets topInsets = new Insets(30, 10, 0, 10);
private Student student;
public static void main(String[] args) {
SwingUtilities.invokeLater(new StudentDataEditor());
}
public StudentDataEditor() {
this.student = new Student("00000017108", "Sutandi",
"Information Systems", 2);
}
#Override
public void run() {
JFrame frame = new JFrame("Student Data Editor");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(createTitlePanel());
panel.add(createStudentPanel());
panel.add(createMPPanel());
panel.add(Box.createVerticalStrut(30));
panel.add(createEmailPanel());
panel.add(Box.createVerticalStrut(10));
return panel;
}
private JPanel createTitlePanel() {
JPanel panel = new JPanel();
JLabel titleLabel = new JLabel("CEK NILAI");
titleLabel.setFont(titleLabel.getFont().deriveFont(24F));
panel.add(titleLabel);
return panel;
}
private JPanel createStudentPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
int gridy = 0;
JLabel idLabel = new JLabel("ID:");
addComponent(panel, idLabel, 0, gridy, 1, 1, topInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField idTextField = new JTextField(15);
idTextField.setEditable(false);
idTextField.setText(student.getId());
addComponent(panel, idTextField, 1, gridy, 1, 1, topInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel jurusanLabel = new JLabel("Jurusan:");
addComponent(panel, jurusanLabel, 2, gridy, 1, 1, topInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField jurusanTextField = new JTextField(15);
jurusanTextField.setEditable(false);
jurusanTextField.setText(student.getJurusan());
addComponent(panel, jurusanTextField, 3, gridy++, 1, 1, topInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel nameLabel = new JLabel("Name:");
addComponent(panel, nameLabel, 0, gridy, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField nameTextField = new JTextField(15);
nameTextField.setEditable(false);
nameTextField.setText(student.getName());
addComponent(panel, nameTextField, 1, gridy, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel semesterLabel = new JLabel("Semester:");
addComponent(panel, semesterLabel, 2, gridy, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField semesterTextField = new JTextField(15);
semesterTextField.setEditable(false);
semesterTextField.setText(Integer.toString(student.getSemester()));
addComponent(panel, semesterTextField, 3, gridy++, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
return panel;
}
private JPanel createMPPanel() {
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
int gridy = 0;
JLabel mp1Label = new JLabel("MP1");
addComponent(panel, mp1Label, 0, gridy, 1, 1, topInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField mp1TextField = new JTextField(25);
addComponent(panel, mp1TextField, 1, gridy++, 1, 1, topInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel mp2Label = new JLabel("MP2");
addComponent(panel, mp2Label, 0, gridy, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField mp2TextField = new JTextField(25);
addComponent(panel, mp2TextField, 1, gridy++, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel mp3Label = new JLabel("MP3");
addComponent(panel, mp3Label, 0, gridy, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField mp3TextField = new JTextField(25);
addComponent(panel, mp3TextField, 1, gridy++, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel mp4Label = new JLabel("MP4");
addComponent(panel, mp4Label, 0, gridy, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField mp4TextField = new JTextField(25);
addComponent(panel, mp4TextField, 1, gridy++, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JLabel mp5Label = new JLabel("MP5");
addComponent(panel, mp5Label, 0, gridy, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
JTextField mp5TextField = new JTextField(25);
addComponent(panel, mp5TextField, 1, gridy++, 1, 1, normalInsets,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL);
return panel;
}
private JPanel createEmailPanel() {
JPanel panel = new JPanel();
JButton submitButton = new JButton("Send to my email");
panel.add(submitButton);
return panel;
}
private void addComponent(Container container, Component component,
int gridx, int gridy, int gridwidth, int gridheight, Insets insets,
int anchor, int fill) {
GridBagConstraints gbc = new GridBagConstraints(gridx, gridy,
gridwidth, gridheight, 0.0D, 0.0D, anchor, fill, insets, 0, 0);
container.add(component, gbc);
}
public class Student {
private final int semester;
private final String id;
private final String name;
private final String jurusan;
public Student(String id, String name, String jurusan, int semester) {
this.id = id;
this.name = name;
this.jurusan = jurusan;
this.semester = semester;
}
public int getSemester() {
return semester;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getJurusan() {
return jurusan;
}
}
}
Related
I have a little Java swing GUI with a GridBagLayout. I have set the GridBagConstraints.fill = GridBagConstraints.BOTH but don't want that my buttons or text fields to get resized vertically. Furthermore, I only want my JTextArea to be resized and tried putting in maximum size for the components I don't want to size up, but it is not working. Any ideas on how I can make the GBC.fill only applicable for some components?
Reproducible example:
public class Main {
static JFrame frame = new JFrame("Create New Entry");
static JPanel wrapper = new JPanel();
static JTextField title = new JTextField(20);
static JLabel titleLabel = new JLabel("Title");
static JTextField username = new JTextField(20);
static JLabel usernameLabel = new JLabel("Username");
static JTextField email = new JTextField(20);
static JLabel emailLabel = new JLabel("Email Address");
static JPasswordField password = new JPasswordField(20);
static JLabel passwordLabel = new JLabel("Password");
static JButton generatePassword = new JButton("Generate Password");
static JPasswordField confirmPassword = new JPasswordField();
static JLabel confirmPasswordLabel = new JLabel("Confirm Password");
static JToggleButton showPassword = new JToggleButton("Show Password");
static JButton submit = new JButton("Submit Entry");
static JLabel notesLabel = new JLabel("Notes");
static JTextArea textArea = new JTextArea(5, 0);
static JScrollPane scrollPane = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public static void main(String[] args) {
GridBagConstraints gbc = new GridBagConstraints();
wrapper.setLayout(new GridBagLayout());
gbc.gridwidth = GridBagConstraints.RELATIVE;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(10, 10, 10, 10);
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 0;
wrapper.add(titleLabel, gbc);
gbc.gridx = 1;
gbc.gridwidth = 2;
wrapper.add(title, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 1;
wrapper.add(usernameLabel, gbc);
gbc.gridx = 1;
gbc.gridwidth = 2;
wrapper.add(username, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 2;
wrapper.add(emailLabel, gbc);
gbc.gridx = 1;
gbc.gridwidth = 2;
wrapper.add(email, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 3;
wrapper.add(passwordLabel, gbc);
gbc.gridx = 1;
wrapper.add(password, gbc);
gbc.gridx = 2;
wrapper.add(generatePassword, gbc);
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy = 4;
wrapper.add(confirmPasswordLabel, gbc);
gbc.gridx = 1;
wrapper.add(confirmPassword, gbc);
gbc.gridx = 2;
wrapper.add(showPassword, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
wrapper.add(notesLabel, gbc);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 1;
gbc.gridwidth = 2;
wrapper.add(scrollPane, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 3;
gbc.gridy = 6;
wrapper.add(submit, gbc);
password.setPreferredSize(new Dimension(300, 26));
confirmPassword.setPreferredSize(new Dimension(300, 26));
title.setPreferredSize(new Dimension(300, 26));
username.setPreferredSize(new Dimension(300, 26));
email.setPreferredSize(new Dimension(300, 26));
frame.add(wrapper);
frame.pack();
frame.setMinimumSize(frame.getSize());
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Any ideas on how I can make the GBC.fill only applicable for some components?
Yes. Don't have all components use a GridBagConstraints object whose fill field is .BOTH. Each component should be added with its own GBC object, and the ones you want filled both horizontally and vertically should have the fill property set to .BOTH, and the components that should only expand horizontally should have GBC fill field of .HORIZONTAL. When I use the GridBagLayout, I often create helper method(s) for creating constraint objects, methods that know what settings to use based on parameters passed into them, and I suggest that you consider doing the same.
As Abra mentions, yes, you can modify a GridBagConstraints (GBC) object, by changing the settings of one or more fields as necessary, and I sometimes do this too, but more often, I use helper methods to create GBC objects on the fly. It just works better for me that way.
For example:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.*;
public class Main2 extends JPanel {
private static final long serialVersionUID = 1L;
private static final int FIELD_COLS = 20;
private static final int TA_ROWS = 10;
private static final int INGS_GAP = 10;
private JLabel titleLabel = new JLabel("Title");
private JLabel userNameLabel = new JLabel("Username");
private JLabel emailAddrLabel = new JLabel("EmailAddress");
private JLabel passwordLabel = new JLabel("Password");
private JLabel confirmPasswordLabel = new JLabel("Confirm Password");
private JLabel notesLabel = new JLabel("Notes");
private JTextField titleField = new JTextField(FIELD_COLS);
private JTextField userNameField = new JTextField(FIELD_COLS);
private JTextField emailField = new JTextField(FIELD_COLS);
private JPasswordField passwordField = new JPasswordField(FIELD_COLS);
private JPasswordField confirmPasswordField = new JPasswordField(FIELD_COLS);
private JTextArea NotesArea = new JTextArea(TA_ROWS, FIELD_COLS);
private JScrollPane textAreaScrollPane = new JScrollPane(NotesArea);
private JButton generatePasswordBtn = new JButton("Generate Password");
private JButton showPasswordBtn = new JButton("Show Password");
private JButton submitEntryBtn = new JButton("Submit Entry");
public Main2() {
setLayout(new GridBagLayout());
// basic GBC use
int row = 0;
GridBagConstraints gbc = createGbc(0, row, GridBagConstraints.HORIZONTAL);
add(titleLabel, gbc);
gbc = createGbc(1, row, GridBagConstraints.HORIZONTAL, 2, 1);
add(titleField, gbc);
row++;
gbc = createGbc(0, row, GridBagConstraints.HORIZONTAL);
add(userNameLabel, gbc);
gbc = createGbc(1, row, GridBagConstraints.HORIZONTAL, 2, 1);
add(userNameField, gbc);
row++;
gbc = createGbc(0, row, GridBagConstraints.HORIZONTAL);
add(emailAddrLabel, gbc);
gbc = createGbc(1, row, GridBagConstraints.HORIZONTAL, 2, 1);
add(emailField, gbc);
row++;
gbc = createGbc(0, row, GridBagConstraints.HORIZONTAL);
add(passwordLabel, gbc);
gbc = createGbc(1, row, GridBagConstraints.HORIZONTAL);
add(passwordField, gbc);
gbc = createGbc(2, row, GridBagConstraints.HORIZONTAL);
add(generatePasswordBtn, gbc);
row++;
gbc = createGbc(0, row, GridBagConstraints.HORIZONTAL);
add(confirmPasswordLabel, gbc);
gbc = createGbc(1, row, GridBagConstraints.HORIZONTAL);
add(confirmPasswordField, gbc);
gbc = createGbc(2, row, GridBagConstraints.HORIZONTAL);
add(showPasswordBtn, gbc);
// here we set the GBC weighty to non-0 value to allow vertical expansion
// of added components
row++;
int txtAreaRows = TA_ROWS;
gbc = createGbc(0, row, GridBagConstraints.HORIZONTAL);
gbc.anchor = GridBagConstraints.WEST;
gbc.weighty = 1.0;
add(notesLabel, gbc);
gbc = createGbc(1, row, GridBagConstraints.BOTH, 2, txtAreaRows);
gbc.weighty = 1.0;
add(textAreaScrollPane, gbc);
textAreaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
row += txtAreaRows;
gbc = createGbc(0, row, GridBagConstraints.HORIZONTAL);
add(new JLabel(""), gbc);
gbc = createGbc(1, row, GridBagConstraints.HORIZONTAL, 2, 1);
add(submitEntryBtn, gbc);
}
private static GridBagConstraints createGbc(int x, int y, int fill, int width, int height) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.fill = fill;
// allow horizontal expansion *unless* at left-most position in row
gbc.weightx = x == 0 ? 0.0 : 1.0;
gbc.weighty = 0.0; // default to no vertical expansion
gbc.insets = new Insets(INGS_GAP, INGS_GAP, INGS_GAP, INGS_GAP);
return gbc;
}
private static GridBagConstraints createGbc(int x, int y, int fill) {
return createGbc(x, y, fill, 1, 1);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
Main2 mainPanel = new Main2();
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
putting a JPanel in a JFrame: setContentPane() and add() both seem to work. Is there any technical difference?
One example from web has the following. Changing frame.setContentPane(panel) to frame.add(panel) seems to produce the same behavior.
//file: Calculator.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Calculator extends JPanel implements ActionListener {
GridBagConstraints gbc = new GridBagConstraints();
JTextField theDisplay = new JTextField();
public Calculator() {
gbc.weightx = 1.0; gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
ContainerListener listener = new ContainerAdapter() {
public void componentAdded(ContainerEvent e) {
Component comp = e.getChild();
if (comp instanceof JButton)
((JButton)comp).addActionListener(Calculator.this);
}
};
addContainerListener(listener);
gbc.gridwidth = 4;
addGB(this, theDisplay, 0, 0);
// make the top row
JPanel topRow = new JPanel();
topRow.addContainerListener(listener);
gbc.gridwidth = 1;
gbc.weightx = 1.0;
addGB(topRow, new JButton("C"), 0, 0);
gbc.weightx = 0.33;
addGB(topRow, new JButton("%"), 1, 0);
gbc.weightx = 1.0;
addGB(topRow, new JButton("+"), 2, 0 );
gbc.gridwidth = 4;
addGB(this, topRow, 0, 1);
gbc.weightx = 1.0; gbc.gridwidth = 1;
// make the digits
for(int j=0; j<3; j++)
for(int i=0; i<3; i++)
addGB(this, new JButton("" + ((2-j)*3+i+1) ), i, j+2);
// -, x, and divide
addGB(this, new JButton("-"), 3, 2);
addGB(this, new JButton("x"), 3, 3);
addGB(this, new JButton("\u00F7"), 3, 4);
// make the bottom row
JPanel bottomRow = new JPanel();
bottomRow.addContainerListener(listener);
gbc.weightx = 1.0;
addGB(bottomRow, new JButton("0"), 0, 0);
gbc.weightx = 0.33;
addGB(bottomRow, new JButton("."), 1, 0);
gbc.weightx = 1.0;
addGB(bottomRow, new JButton("="), 2, 0);
gbc.gridwidth = 4;
addGB(this, bottomRow, 0, 5);
}
void addGB(Container cont, Component comp, int x, int y) {
if ((cont.getLayout() instanceof GridBagLayout) == false)
cont.setLayout(new GridBagLayout());
gbc.gridx = x; gbc.gridy = y;
cont.add(comp, gbc);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("C"))
theDisplay.setText("");
else
theDisplay.setText(theDisplay.getText()
+ e.getActionCommand());
}
public static void main(String[] args) {
JFrame frame = new JFrame("Calculator");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize(200, 250);
frame.setLocation(200, 200);
frame.setContentPane(new Calculator());
frame.setVisible(true);
}
}
Another has the following. Changing frame.add(panel) to frame.setContentPane(panel) seems to produce the same behavior.
import javax.swing.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
public class recMod {
public enum RecFieldNames {
FIRST_NAME("First Name:"),
LAST_NAME("Last Name:"),
VENDOR("Vendor:"),
VENDOR_LOC_CODE("Vendor Location Code:"),
USER_EMAIL("User Email Address:"),
USER_NAME("Username:"),
PASSWORD("Password:"),
USER_CODE("User Code:");
private String name;
private RecFieldNames(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
private static final int FIELD_COLS = 7;
private Map<RecFieldNames, JTextField> recFieldMap =
new HashMap<RecFieldNames, JTextField>();
//JButton[] recButtons = new JButton[3];
public recMod() {
JFrame frame = new JFrame("Record Modify");
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
addLabelField(panel, RecFieldNames.FIRST_NAME, 0, 0, 1, 1,
GridBagConstraints.WEST, GridBagConstraints.CENTER);
addLabelField(panel, RecFieldNames.LAST_NAME, 2, 0, 1, 1,
GridBagConstraints.CENTER, GridBagConstraints.EAST);
addLabelField(panel, RecFieldNames.VENDOR, 0, 1, 1, 1,
GridBagConstraints.WEST, GridBagConstraints.CENTER);
addLabelField(panel, RecFieldNames.VENDOR_LOC_CODE, 2, 1, 1, 1,
GridBagConstraints.CENTER, GridBagConstraints.WEST);
addLabelField(panel, RecFieldNames.USER_EMAIL, 0, 2, 1, 1,
GridBagConstraints.WEST, GridBagConstraints.WEST);
addLabelField(panel, RecFieldNames.USER_NAME, 0, 3, 1, 1,
GridBagConstraints.WEST, GridBagConstraints.CENTER);
addLabelField(panel, RecFieldNames.PASSWORD, 2, 3, 1, 1,
GridBagConstraints.CENTER, GridBagConstraints.WEST);
addLabelField(panel, RecFieldNames.USER_CODE, 0, 4, 1, 1,
GridBagConstraints.WEST, GridBagConstraints.WEST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
//frame.getContentPane().setPreferredSize(new Dimension(500, 400));
((JComponent) frame.getContentPane()).
setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public String getFieldText(RecFieldNames rfn) {
return recFieldMap.get(rfn).getText();
}
private void addLabelField(JPanel p, RecFieldNames recFieldNames, int x,
int y, int width, int height, int labelAlign, int fieldAlign) {
GridBagConstraints gbc = new GridBagConstraints();
JLabel label = new JLabel(recFieldNames.getName());
JTextField textField = new JTextField(FIELD_COLS);
recFieldMap.put(recFieldNames, textField);
gbc.gridx = x;
gbc.gridy = y;
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
int midInset = (x == 2) ? 40 : 5;
gbc.insets = new Insets(5, midInset, 5, 5);
gbc.anchor = labelAlign;
gbc.fill = GridBagConstraints.HORIZONTAL;
p.add(label, gbc);
gbc.gridx = x + 1;
gbc.anchor = fieldAlign;
gbc.insets = new Insets(5, 5, 5, 5);
p.add(textField, gbc);
}
public static void main(String args[]) {
new recMod();
}
}
The content pane of the frame is a JPanel.
So if you use frame.add( another panel ), then you have a structure like:
- JFrame
- content pane
- another panel
If you use frame setContentPane( another panel ) you have:
- JFrame
- another panel
See the section from the Swing tutorial on Adding Components to the Content Pane.
Suppose you have a panel initialized like so
JPanel panel_playerBuffs = new JPanel();
panel_playerBuffs.setBounds(249, 165, 71, 227);
panel_playerBuffs.setOpaque(false);
panel_playerBuffs.setLayout(new GridBagLayout());
getContentPane().add(panel_playerBuffs);
And its layout is GridBayLayout with the following constraints
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = gbc.weighty = 1.0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridx = 1;
gbc.gridy = 1;
panel_playerBuffs.add(new JLabel("located at 1, 1"), gbc);
gbc.gridx = 1;
gbc.gridy = 3;
panel_playerBuffs.add(new JLabel("located at 1, 3"), gbc);
As you can see, this adds a JLabel at (1, 1) and another one at (1, 3). Now I'm trying to add a conditional somewhere else in the program to check whether or not there's a label at a given position. For instance, I would like to find out if the position (1, 2) has a label (in this case it doesn't). What method should I use for this?
How about using the GridBagLayout#getLayoutDimensions()
If the width or height of the given position is 0, there is empty.
import java.awt.*;
import java.util.Arrays;
import javax.swing.*;
public class GridBayLayoutSlotTest {
private JComponent makeUI() {
GridBagLayout layout = new GridBagLayout();
JPanel panel_playerBuffs = new JPanel();
panel_playerBuffs.setLayout(layout);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = gbc.weighty = 1.0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.gridx = 1;
gbc.gridy = 1;
panel_playerBuffs.add(new JLabel("located at 1, 1"), gbc);
gbc.gridx = 3;
gbc.gridy = 1;
panel_playerBuffs.add(new JLabel("located at 3, 1"), gbc);
EventQueue.invokeLater(() -> {
int[][] a = layout.getLayoutDimensions();
System.out.println(Arrays.deepToString(a));
System.out.format("isEmpty(%d, %d): %s%n", 2, 1, isEmpty(a, 2, 1));
System.out.format("isEmpty(%d, %d): %s%n", 3, 1, isEmpty(a, 3, 1));
});
return panel_playerBuffs;
}
private static boolean isEmpty(int[][] a, int x, int y) {
int[] w = a[0];
int[] h = a[1];
return w[x] == 0 || h[y] == 0;
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new GridBayLayoutSlotTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}
I am trying to make multiple lines of a JTextArea visible.I am using GridBagLayout to add the components. Here is a code snippet:
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
public class SSCE {
SSCE(){
JFrame f1=new JFrame();
GridBagLayout gbl=new GridBagLayout();
JButton btnAddAcc=new JButton("Add Acount");
JButton insertId=new JButton("Insert");
JButton insertTweet=new JButton("Insert2");
JButton tweetButton=new JButton("TweetButton");
JLabel accountStatusHeader=new JLabel("account status Header");
JLabel accountDisplayNameHeader=new JLabel("account displayname Header");
JLabel enterInterval=new JLabel("enter Interval!!");
final JTextArea accountDispName = new JTextArea(50, 50);
final JTextArea statusDisplay = new JTextArea(50, 50);
final JTextArea jTextAreaId = new JTextArea(20, 50);
final JTextArea jTextAreaTweets = new JTextArea(20, 50);
jTextAreaId.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,
Color.PINK, Color.GREEN));
final JTextArea tweetLog = new JTextArea(100, 100);
tweetLog.setPreferredSize(new Dimension(1000, 5000));
JScrollPane tweetLogPaneScroll = new JScrollPane(tweetLog);
JScrollPane idScrollPane = new JScrollPane(jTextAreaId);
JScrollPane tweetScrollPane = new JScrollPane(jTextAreaTweets);
final JTextField timeIntervalInput = new JTextField(20);
final JTextField tagIdInsertTextBox = new JTextField(50);
final JTextField tweetInsertTextBox = new JTextField(50);
f1.setLayout(gbl);
f1.add(btnAddAcc,makeGbc(0,0,1,2));
f1.add(accountDisplayNameHeader,makeGbc(1,0));
f1.add(accountStatusHeader,makeGbc(1,1));
f1.add(accountDispName,makeGbc(2,0));
f1.add(statusDisplay,makeGbc(2,1));
f1.add(enterInterval,makeGbc(3,0));
f1.add(timeIntervalInput,makeGbc(3,1));
f1.add(new JLabel("Twitter Ids"),makeGbc(4,0));
f1.add(new JLabel("Tweets"),makeGbc(4,1));
f1.add(idScrollPane,makeGbc(5,0,5));
f1.add(tweetScrollPane,makeGbc(5,1,5));
f1.add(tagIdInsertTextBox,makeGbc(10,0));
f1.add(tweetInsertTextBox,makeGbc(10,1));
f1.add(insertId,makeGbc(11,0));
f1.add(insertTweet,makeGbc(11,1));
f1.add(tweetButton,makeGbc(12,0,1,2));
f1.add(tweetLogPaneScroll,makeGbc(13,0,6,2));
f1.setSize(800,400);
f1.setVisible(true);
f1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
accountDispName.setVisible(false);
statusDisplay.setVisible(false);
}
private GridBagConstraints makeGbc(int y, int x) {
GridBagConstraints gbc = new GridBagConstraints();
// gbc.gridwidth = 1;
// gbc.gridheight = 1;
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = (y == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
private GridBagConstraints makeGbc(int y, int x,int gridheight) {
GridBagConstraints gbc = new GridBagConstraints();
// gbc.gridwidth = 1;
gbc.gridheight = gridheight;
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = (y == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
private GridBagConstraints makeGbc(int y, int x,int gridheight,int gridwidth) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gridwidth;
gbc.gridheight = gridheight;
gbc.gridx = x;
gbc.gridy = y;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = (y == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
public static void main(String args[]){
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
SSCE a1;
a1 = new SSCE();
}
});
}
}
Please note the following lines:
f1.add(idScrollPane,makeGbc(5,0,5));
f1.add(tweetScrollPane,makeGbc(5,1,5));
In above, I am passing the third paramenter(the gridheight) as 5 but still I see only one row. I want to set the row span to 5.
And Also the following:
f1.add(tweetLogPaneScroll,makeGbc(13,0,6,2));
Here again, I am passing the third param(gridheight) as 6.But yet I see only one Row of textarea. So what is going wrong?? And whats the solution?
Your SSCCE helps me to see everything -- thanks! I've voted to open your question and have up-voted it. You're killing yourself with your unrealistic JTextArea row numbers, and then setting the size of your GUI. Get rid of all setSize(...) and setPreferredSize(...) method calls. Make your JTextArea row counts 5 or 10, not 50, not 100. Call pack() before setVisible(true).
For example, please see the changes I've made below as well as comments with !! in them. Note that I've tried to get rid of most of your magic numbers, but you still need to do the same with the column counts. I've also added text to your text components for the sake of debugging, so that I can see at a glance which text component goes with which variable. You'll of course not want to have this text present in the presentation code, but again, it's a useful debugging tool:
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.awt.*;
public class SSCE {
private static final int SMALL_ROWS = 5; // !! was 20!
private static final int BIG_ROWS = 10; // !! was 50!
SSCE() {
JFrame f1 = new JFrame();
GridBagLayout gbl = new GridBagLayout();
JButton btnAddAcc = new JButton("Add Acount");
JButton insertId = new JButton("Insert");
JButton insertTweet = new JButton("Insert2");
JButton tweetButton = new JButton("TweetButton");
JLabel accountStatusHeader = new JLabel("account status Header");
JLabel accountDisplayNameHeader = new JLabel(
"account displayname Header");
JLabel enterInterval = new JLabel("enter Interval!!");
final JTextArea accountDispName = new JTextArea("accountDispName JTA",
BIG_ROWS, 50);
final JTextArea statusDisplay = new JTextArea("statusDisplay JTA",
BIG_ROWS, 50);
final JTextArea jTextAreaId = new JTextArea("jTextAreaId JTA",
SMALL_ROWS, 50);
final JTextArea jTextAreaTweets = new JTextArea("jTextAreaTweets JTA",
SMALL_ROWS, 50);
jTextAreaId.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED,
Color.PINK, Color.GREEN));
final JTextArea tweetLog = new JTextArea("tweetLog JTA", BIG_ROWS, 100); // was
// 100!
// !! tweetLog.setPreferredSize(new Dimension(1000, 5000));
JScrollPane tweetLogPaneScroll = new JScrollPane(tweetLog);
JScrollPane idScrollPane = new JScrollPane(jTextAreaId);
JScrollPane tweetScrollPane = new JScrollPane(jTextAreaTweets);
final JTextField timeIntervalInput = new JTextField(
"timeIntervalInput JTF", 20);
final JTextField tagIdInsertTextBox = new JTextField(
"tagIdInsertTextBox JTF", 50);
final JTextField tweetInsertTextBox = new JTextField(
"tweetInsertTextBox JTF", 50);
f1.setLayout(gbl);
f1.add(btnAddAcc, makeGbc(0, 0, 1, 2));
f1.add(accountDisplayNameHeader, makeGbc(1, 0));
f1.add(accountStatusHeader, makeGbc(1, 1));
f1.add(accountDispName, makeGbc(2, 0));
f1.add(statusDisplay, makeGbc(2, 1));
f1.add(enterInterval, makeGbc(3, 0));
f1.add(timeIntervalInput, makeGbc(3, 1));
f1.add(new JLabel("Twitter Ids"), makeGbc(4, 0));
f1.add(new JLabel("Tweets"), makeGbc(4, 1));
f1.add(idScrollPane, makeGbc(5, 0, 5));
f1.add(tweetScrollPane, makeGbc(5, 1, 5));
f1.add(tagIdInsertTextBox, makeGbc(10, 0));
f1.add(tweetInsertTextBox, makeGbc(10, 1));
f1.add(insertId, makeGbc(11, 0));
f1.add(insertTweet, makeGbc(11, 1));
f1.add(tweetButton, makeGbc(12, 0, 1, 2));
f1.add(tweetLogPaneScroll, makeGbc(13, 0, 6, 2));
// !! f1.setSize(800, 400);
f1.pack(); // !!
f1.setVisible(true);
f1.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
accountDispName.setVisible(false);
statusDisplay.setVisible(false);
}
private GridBagConstraints makeGbc(int y, int x) {
GridBagConstraints gbc = new GridBagConstraints();
// gbc.gridwidth = 1;
// gbc.gridheight = 1;
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = (y == 0) ? GridBagConstraints.LINE_START
: GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.BOTH;
System.out.printf("gridwidth, gridheight: [%d, %d]%n", gbc.gridwidth,
gbc.gridheight);
return gbc;
}
private GridBagConstraints makeGbc(int y, int x, int gridheight) {
GridBagConstraints gbc = new GridBagConstraints();
// gbc.gridwidth = 1;
gbc.gridheight = gridheight;
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = (y == 0) ? GridBagConstraints.LINE_START
: GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
private GridBagConstraints makeGbc(int y, int x, int gridheight,
int gridwidth) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = gridwidth;
gbc.gridheight = gridheight;
gbc.gridx = x;
gbc.gridy = y;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = (y == 0) ? GridBagConstraints.LINE_START
: GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
public static void main(String args[]) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
SSCE a1;
a1 = new SSCE();
}
});
}
}
This results in a GUI that looks like so:
Note, I would also change the GridBagConstraints for JTextFields from BOTH to HORIZONTAL.
Edit
You state in comment:
One more question if u dont mind answering.the TimeIntervalInput is appearing so wide although I have defined it to hold at max 20 chars.Any solution to that?
You need to continue to play with your grid bag constraints as the ones you're using are quite restrictive. For example, note what happens when I use more exacting constraints on the GBC for that JTextField:
GridBagConstraints gbc = makeGbc(3, 1);
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.WEST;
f1.add(timeIntervalInput, gbc);
I have JPanel inside vertical JSplitPane. JPanel contains jlabels and jtextfields. When I shrink height of JPanel by moving JSplitPane's divider All components in jpanel are resized themselves. How to tell them not to resize when height of parent jpanel shrinks.
I cannot size minSize for JPanel because it makes impossible for JSplitPane to move divider.
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
splitPane.setDividerSize(10);
splitPane.setOneTouchExpandable(true);
JPanel searchPanel = createSearchPanel();
splitPane.setDividerLocation(searchPanel.getPreferredSize().height + 5);
splitPane.setTopComponent(searchPanel);
As you see there is searchPanel. Let's see it:
JPanel searchPanel = new JPanel(new GridBagLayout()) {
Dimension minSize = new Dimension(200, 0);
#Override
public Dimension getMinimumSize() {
return minSize;
}
};
searchPanel.setBorder(BorderFactory.createTitledBorder("Search query"));
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL,
new Insets(5, 2, 5, 3), 0, 0);
searchPanel.add(eventLabel, gbc);
gbc.gridx = 1;
gbc.gridwidth = 3;
searchPanel.add(eventLabelField, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
searchPanel.add(timestampLabel, gbc);
gbc.gridx = 1;
searchPanel.add(timestampStartField, gbc);
gbc.gridx = 2;
searchPanel.add(timestammpToLabel, gbc);
gbc.gridx = 3;
searchPanel.add(timestampEndField, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
searchPanel.add(locationLabel, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 3;
searchPanel.add(locationField, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 1;
searchPanel.add(durationMagnitudeLabel, gbc);
gbc.gridx = 1;
gbc.gridy = 3;
searchPanel.add(durationMagnitudeMinField, gbc);
gbc.gridx = 2;
searchPanel.add(durationToLabel, gbc);
gbc.gridx = 3;
searchPanel.add(durationMagnitudeMaxField, gbc);
gbc.gridx = 1;
gbc.gridy = 4;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.PAGE_END;
gbc.weighty = 1.0;
gbc.ipadx = 2;
gbc.ipady = 2;
gbc.insets = new Insets(15, 0, 0, 0);
searchPanel.add(searchButton, gbc);
When I move up vertical divider the height of searchPanel shrinks and components look like:
You see that jtextFields got much smaller than they were after I moved divider up
Please, help me here.
I have changed your code. Use weightx property of GridBagConstraint with GridBagConstraints.HORIZONTAL fill, it helps components to fill their cell properly.
Example code:
JPanel searchPanel = new JPanel(new GridBagLayout()) {
Dimension minSize = new Dimension(200, 0);
#Override
public Dimension getMinimumSize() {
return minSize;
}
};
searchPanel.setBorder(BorderFactory.createTitledBorder("Search query"));
GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 0, 0,
GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL,
new Insets(5, 2, 5, 3), 0, 0);
searchPanel.add(new JLabel("1"), gbc);
gbc.gridx = 1;
gbc.gridwidth = 3;
gbc.weightx = 1;
searchPanel.add(new JTextField(), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.weightx = 0;
searchPanel.add(new JLabel("1"), gbc);
gbc.gridx = 1;
gbc.weightx = 1;
searchPanel.add(new JTextField(), gbc);
gbc.gridx = 2;
gbc.weightx = 0;
searchPanel.add(new JLabel("1"), gbc);
gbc.gridx = 3;
gbc.weightx = 1;
searchPanel.add(new JTextField(), gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 0;
searchPanel.add(new JLabel("1"), gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 3;
gbc.weightx = 1;
searchPanel.add(new JTextField(), gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.weightx = 0;
searchPanel.add(new JLabel("1"), gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.weightx = 1;
searchPanel.add(new JTextField(), gbc);
gbc.gridx = 2;
gbc.weightx = 0;
searchPanel.add(new JLabel("1"), gbc);
gbc.gridx = 3;
gbc.weightx = 1;
searchPanel.add(new JTextField(), gbc);
gbc.gridx = 1;
gbc.gridy = 4;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.PAGE_END;
gbc.weighty = 1.0;
gbc.ipadx = 2;
gbc.ipady = 2;
gbc.insets = new Insets(15, 0, 0, 0);
gbc.weightx = 0;
searchPanel.add(new JButton("b"), gbc);
return searchPanel;
Watch docs How to use GridBagLayout
Results:
Edit: Sorry, I'm using awful names for labels)
Add a dummy JPanel to the bottom and set weightY=1 for the JPanel. ALl the rest component should have weightY=0. Thus on height increasing all the additional pixels are targeted to the dummy JPanel.