I am trying to make the layout stabilized and fixed. When I resized the window, it gives me just one line instead of an actual row layout. How do I make the layout neat?
Here is my code:
class BookstoreFrame extends JFrame
{
JButton btnSubmit;
JTextField txtISBN, txtTitle, txtAuthor, txtPrice;
JLabel lblISBN, lblTitle, lblAuthor, lblPrice;
int count = 0;
public BookstoreFrame(String title)
{
FlowLayout layout = new FlowLayout(FlowLayout.CENTER, 5, 20);
setLayout(layout);
lblISBN = new JLabel("ISBN: ");
txtISBN = new JTextField(10);
lblTitle = new JLabel("Book Title: ");
txtTitle = new JTextField(10);
lblAuthor = new JLabel("Author: ");
txtAuthor = new JTextField(10);
lblPrice = new JLabel("Price: ");
txtPrice = new JTextField(10);
btnSubmit = new JButton("Submit");
add(lblISBN);
add(txtISBN);
add(lblTitle);
add(txtTitle);
add(lblAuthor);
add(txtAuthor);
add(lblPrice);
add(txtPrice);
add(btnSubmit);
btnSubmit.addActionListener(new seeTextBookInfo());
}
}
You are using FlowLayout, it adds the components in one direction until there is no more space and then creates a new line.
You could use BoxLayout, to add the elements from left to right: https://docs.oracle.com/javase/8/docs/api/javax/swing/BoxLayout.html
BoxLayout layout = BoxLayout(this, BoxLayout.X_AXIS);
How do I make the layout neat?
We have no idea what "neat" means to you?
Typically you would have label/text field pairs on a single row, then maybe the button on its own row.
I would suggest you might want to use the GridBagLayout as it allows you to have flexible row and column grids for your components.
The basic code might be something like:
setLayout( new GridBagLayout() );
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
add(lblISBN, gbc);
gbc.gridx = 1;
add(txtISBN, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
add(lblTitle);
gbc.gridx = 1;
add(txtTitle);
... // add other components here
gbc.gridx = 0;
gbc.gridy = ?;
gbc.gridwidth = 2;
gbc.anchor = ???
add(btnSubmit);
Read the section from the Swing tutorial on How to Use GridBagLayout for more information and examples to get you started.
Trying to build a simple registration form in Java Swing and AWT, but couldn't accomplish what I really want.
Here is the result that I want
Here's the code
import java.awt.*;
import javax.swing.*;
public class MainFrame {
public static void main(String[] args) {
// TODO Auto-generated method stub
// Main Frame
JFrame mainFrame = new JFrame("New Account Registration");
JPanel borderPanel = new JPanel(new BorderLayout());
JPanel gridPanel = new JPanel(new GridLayout(9,2));
JPanel gridGenderPanel = new JPanel(new GridLayout(1,2));
JPanel flowButton = new JPanel(new FlowLayout());
//JLabels
JLabel title = new JLabel("New Account Registration");
JLabel name = new JLabel("Name");
JLabel email = new JLabel("Email Address:");
JLabel createPassword = new JLabel("Create Password:");
JLabel confirmPassword = new JLabel("Confirm Password:");
JLabel gender = new JLabel("Gender:");
JLabel address = new JLabel("Address:");
JLabel state = new JLabel("State:");
JLabel country = new JLabel("Country:");
JLabel phoneNo = new JLabel("Phone No:");
String[] coutriesStrings = { "America", "Japan", "India", "Korea", "Sweden" };
// JTextFields, JRadioButton, JComboBox
JTextField nameField = new JTextField();
JTextField emailField = new JTextField();
JPasswordField passField = new JPasswordField();
JPasswordField confirmPassField = new JPasswordField();
JRadioButton male = new JRadioButton("Male");
JRadioButton female = new JRadioButton("Female");
ButtonGroup group = new ButtonGroup();
group.add(male);
group.add(female);
JTextField addressField = new JTextField();
JComboBox stateBox = new JComboBox(coutriesStrings);
stateBox.setSelectedIndex(1);
JTextField countryField = new JTextField();
JTextField phoneField = new JTextField();
JButton submitButton = new JButton("Submit");
JButton clearButton = new JButton("Clear");
// borderPanel.add(title, BorderLayout.NORTH);
// gridPanel.add(title);
// Name
gridPanel.add(name);
gridPanel.add(nameField);
//Email
gridPanel.add(email);
gridPanel.add(emailField);
// CreatePassword
gridPanel.add(createPassword);
gridPanel.add(passField);
// Confirm Password
gridPanel.add(confirmPassword);
gridPanel.add(confirmPassField);
// Gender
gridGenderPanel.add(gender);
gridGenderPanel.add(male);
gridGenderPanel.add(female);
gridPanel.add(gridGenderPanel);
// Address
gridPanel.add(address);
gridPanel.add(addressField);
// State
gridPanel.add(state);
gridPanel.add(stateBox);
// Country
gridPanel.add(country);
gridPanel.add(countryField);
//Button
flowButton.add(submitButton);
flowButton.add(clearButton);
gridPanel.add(flowButton);
mainFrame.add(gridPanel);
mainFrame.setSize(600, 700);
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Here is the result of the codes
I don't know where did I do wrong, please guide me.
You have to add gender label to gridPanel not to gridGenderPanel
// Gender
//gridGenderPanel.add(gender);//The mistake
gridPanel.add(gender);//add to main panel
gridGenderPanel.add(male);
gridGenderPanel.add(female);
gridPanel.add(gridGenderPanel);
Grid layout has a bad habit of making every single part of the grid the same size as the biggest part of the grid. Making UI that require everything to be the same size - this works great. Try out using a GridBagLayout - it isn't pretty but it definitely works.
public class MainFrame {
public static void main(String[] args) {
// TODO Auto-generated method stub
// Main Frame
JFrame mainFrame = new JFrame("New Account Registration");
JPanel borderPanel = new JPanel(new BorderLayout());
JPanel gridPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JPanel gridGenderPanel = new JPanel(new GridLayout(1, 2));
JPanel flowButton = new JPanel(new FlowLayout());
// JLabels
JLabel title = new JLabel("New Account Registration");
setSize(title);
JLabel name = new JLabel("Name");
setSize(name);
JLabel email = new JLabel("Email Address:");
setSize(email);
JLabel createPassword = new JLabel("Create Password:");
setSize(createPassword);
JLabel confirmPassword = new JLabel("Confirm Password:");
setSize(confirmPassword);
JLabel gender = new JLabel("Gender:");
setSize(gender);
JLabel address = new JLabel("Address:");
setSize(address);
JLabel state = new JLabel("State:");
setSize(state);
JLabel country = new JLabel("Country:");
setSize(country);
JLabel phoneNo = new JLabel("Phone No:");
String[] coutriesStrings = { "America", "Japan", "India", "Korea",
"Sweden" };
// JTextFields, JRadioButton, JComboBox
JTextField nameField = new JTextField(15);
JTextField emailField = new JTextField(15);
JPasswordField passField = new JPasswordField(15);
JPasswordField confirmPassField = new JPasswordField(15);
JRadioButton male = new JRadioButton("Male");
JRadioButton female = new JRadioButton("Female");
ButtonGroup group = new ButtonGroup();
group.add(male);
group.add(female);
JTextField addressField = new JTextField(15);
JComboBox stateBox = new JComboBox(coutriesStrings);
stateBox.setPreferredSize(new Dimension(200, 25));
stateBox.setMinimumSize(new Dimension(200, 25));
stateBox.setSelectedIndex(1);
JTextField countryField = new JTextField(15);
JTextField phoneField = new JTextField(15);
JButton submitButton = new JButton("Submit");
JButton clearButton = new JButton("Clear");
// Name
c.gridx = 0;
c.gridy = 0;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(name, c);
c.gridx = 2;
c.gridy = 0;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(nameField, c);
// Email
c.gridx = 0;
c.gridy = 1;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(email, c);
c.gridx = 2;
c.gridy = 1;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(emailField, c);
// CreatePassword
c.gridx = 0;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(createPassword, c);
c.gridx = 2;
c.gridy = 2;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(passField, c);
// Confirm Password
c.gridx = 0;
c.gridy = 3;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(confirmPassword, c);
c.gridx = 2;
c.gridy = 3;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(confirmPassField, c);
// Gender
c.gridx = 0;
c.gridy = 4;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(gender,c );
c.gridx = 2;
c.gridy = 4;
c.gridheight = 1;
c.gridwidth = 1;
gridPanel.add(male,c);
c.gridx = 3;
c.gridy = 4;
c.gridheight = 1;
c.gridwidth = 1;
gridPanel.add(female,c);
// Address
c.gridx = 0;
c.gridy = 5;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(address, c);
c.gridx = 2;
c.gridy = 5;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(addressField, c);
// State
c.gridx = 0;
c.gridy = 6;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(state, c);
c.gridx = 2;
c.gridy = 6;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(stateBox, c);
// Country
c.gridx = 0;
c.gridy = 7;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(country, c);
c.gridx = 2;
c.gridy = 7;
c.gridheight = 1;
c.gridwidth = 2;
gridPanel.add(countryField, c);
// Button
flowButton.add(submitButton);
flowButton.add(clearButton);
c.gridx = 1;
c.gridy = 8;
c.gridheight = 1;
c.gridwidth = 4;
gridPanel.add(flowButton, c);
mainFrame.add(gridPanel);
mainFrame.setSize(350, 300);
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static void setSize(Component label) {
label.setMinimumSize(new Dimension(120, 15));
label.setPreferredSize(new Dimension(120, 15));
}
}
I am trying to get a basic GUI program. It doesnt have to do much but the buttons at the bottom have to work. I am having trouble placing the components (The text, combobox, etc) in the proper spot. Using the GridBag I am able to change the location with the c.gridx and c.gridy but in a very weird way. If I put the gridy values 0-7 with x being 0 everything is on top of eachother. I try putting the combo box next to the text by changing the gridx value and everything gets messed up. The alignment is off on the components after the one I was trying to move over. How do I fix this? I tried the BorderLayout.DIRECTION with no luck. The actual change doesn't take effect at all (moving then to the bottom). How do I fix this? Thanks
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package javaredesign;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
/**
*
* #author
*/
public class Window extends JFrame {
//Default global variables
private JButton submit;
private JButton cancel;
private JButton reset;
private JPanel panel = new JPanel(new GridBagLayout());
private String searchOutput = "";
//Default constructor
public Window() {
//Title of the window
super("LIBSYS: Search");
//Creating the flow layout to which we can work on and adding panel to frame
setLayout(new FlowLayout());
add(panel, BorderLayout.SOUTH);
//Creating the grid to location of the parts
GridBagConstraints c = new GridBagConstraints();
//Initializing the buttons
submit = new JButton("Submit");
c.insets = new Insets(10, 10, 10, 5);
c.gridx = 1;
c.gridy = 20;
panel.add(submit, c);
reset = new JButton("Reset");
c.gridx = 2;
c.gridy = 20;
panel.add(reset, c);
cancel = new JButton("Cancel");
c.gridx = 3;
c.gridy = 20;
panel.add(cancel, c);
//Handler constructor to do the actionlistening
Handler handler = new Handler();
submit.addActionListener(handler);
reset.addActionListener(handler);
cancel.addActionListener(handler);
//Creating the two dropdowns with the words next to them
JLabel chooseCollection = new JLabel("Choose Collection");
String[] ccString = {"All", "Mostly", "Some", "Few"};
JComboBox ccComboBox = new JComboBox(ccString);
JLabel searchUsing = new JLabel("Search Using");
String[] suString = {"Title", "Artist", "Arthor", "Type"};
JComboBox suComboBox = new JComboBox(suString);
//Adding all the text and dropdown menus to the panel
c.gridx = 0;
c.gridy = 24;
panel.add(chooseCollection, c);
c.gridx = 0;
c.gridy = 25;
panel.add(ccComboBox, c);
c.gridx = 1;
c.gridy = 25;
panel.add(searchUsing, c);
c.gridx = 0;
c.gridy = 27;
panel.add(suComboBox, c);
c.gridx = 1;
c.gridy = 27;
//Setting up the text inputbox
JLabel keyword = new JLabel("Keyword or phrase");
JTextField textField = new JTextField(20);
//Adding lable and text box to the panel
panel.add(keyword);
panel.add(textField);
}
}
I would not try and force the buttons into the same layout as the other components. They are independant and should be free floating evenly spaced.
The button panel should be in a panel set with flowlayout. Then this panel should be added to the frame with borderlayout at SOUTH.
The rest of the components should go into a panel with gridbaglayout and added to the frame at CENTER.
The gridbaglayout panel then should have all its components set at the coordinates listed in the picture. If the component covers more than two cells (ie combo) then set the gridWidth property to 2.
I'd do it by having an outer BorderLayout. In the CENTER would be a GroupLayout for the label/control pairs. In the PAGE_END would be a FlowLayout for the buttons.
This uses a TitledBorder instead of the JLabel to show LIBSYS Search. If it really needs a label, put it in the PAGE_START of the border layout.
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.*;
public class LibSysSearch {
private JComponent ui = null;
LibSysSearch() {
initUI();
}
public void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
// Here is our control. This puts a titled border around it,
// instead of using a label in the PAGE_START
JPanel libSysSearchControl = new JPanel(new BorderLayout());
ui.add(libSysSearchControl);
JPanel actionPanel = new JPanel(
new FlowLayout(FlowLayout.CENTER, 15, 15));
libSysSearchControl.add(actionPanel, BorderLayout.PAGE_END);
String[] actionNames = {"Search", "Reset", "Cancel"};
for (String name : actionNames) {
actionPanel.add(new JButton(name));
}
// Use GroupLayout for the label/cotrnl combos.
// make the arrays for the factory method
String[] labels = {
"Choose Collection", "Search Using",
"Keyword or phrase", "Adjacent words"
};
String[] ccString = {"All", "Mostly", "Some", "Few"};
String[] suString = {"Title", "Artist", "Arthor", "Type"};
JPanel confirmAdjacent = new JPanel(new FlowLayout(FlowLayout.LEADING,5,0));
confirmAdjacent.add(new JRadioButton("Yes", true));
confirmAdjacent.add(new JRadioButton("No"));
JComponent[] controls = {
new JComboBox(ccString),
new JTextField(20),
new JComboBox(suString),
confirmAdjacent
};
libSysSearchControl.add(getTwoColumnLayout(labels, controls));
// throw in a few borders for white space
Border border = new CompoundBorder(
new EmptyBorder(10, 10, 10, 10),
new TitledBorder("LIBSYS Search"));
border = new CompoundBorder(
border,
new EmptyBorder(10, 10, 10, 10));
libSysSearchControl.setBorder(border);
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
LibSysSearch o = new LibSysSearch();
JFrame f = new JFrame("Library System Search");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* Typical fields would be single line textual/input components such as
* JTextField, JPasswordField, JFormattedTextField, JSpinner, JComboBox,
* JCheckBox.. & the multi-line components wrapped in a JScrollPane -
* JTextArea or (at a stretch) JList or JTable.
*
* #param labels The first column contains labels.
* #param fields The last column contains fields.
* #param addMnemonics Add mnemonic by next available letter in label text.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields,
boolean addMnemonics) {
if (labels.length != fields.length) {
String s = labels.length + " labels supplied for "
+ fields.length + " fields!";
throw new IllegalArgumentException(s);
}
JComponent panel = new JPanel();
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
// Turn on automatically adding gaps between components
layout.setAutoCreateGaps(true);
// Create a sequential group for the horizontal axis.
GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
GroupLayout.Group yLabelGroup = layout.createParallelGroup(GroupLayout.Alignment.TRAILING);
hGroup.addGroup(yLabelGroup);
GroupLayout.Group yFieldGroup = layout.createParallelGroup();
hGroup.addGroup(yFieldGroup);
layout.setHorizontalGroup(hGroup);
// Create a sequential group for the vertical axis.
GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
layout.setVerticalGroup(vGroup);
int p = GroupLayout.PREFERRED_SIZE;
// add the components to the groups
for (JLabel label : labels) {
yLabelGroup.addComponent(label);
}
for (Component field : fields) {
yFieldGroup.addComponent(field, p, p, p);
}
for (int ii = 0; ii < labels.length; ii++) {
vGroup.addGroup(layout.createParallelGroup().
addComponent(labels[ii]).
addComponent(fields[ii], p, p, p));
}
if (addMnemonics) {
addMnemonics(labels, fields);
}
return panel;
}
private final static void addMnemonics(
JLabel[] labels,
JComponent[] fields) {
Map<Character, Object> m = new HashMap<Character, Object>();
for (int ii = 0; ii < labels.length; ii++) {
labels[ii].setLabelFor(fields[ii]);
String lwr = labels[ii].getText().toLowerCase();
for (int jj = 0; jj < lwr.length(); jj++) {
char ch = lwr.charAt(jj);
if (m.get(ch) == null && Character.isLetterOrDigit(ch)) {
m.put(ch, ch);
labels[ii].setDisplayedMnemonic(ch);
break;
}
}
}
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* #param labelStrings Strings that will be used for labels.
* #param fields The corresponding fields.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
String[] labelStrings,
JComponent[] fields) {
JLabel[] labels = new JLabel[labelStrings.length];
for (int ii = 0; ii < labels.length; ii++) {
labels[ii] = new JLabel(labelStrings[ii]);
}
return getTwoColumnLayout(labels, fields);
}
/**
* Provides a JPanel with two columns (labels & fields) laid out using
* GroupLayout. The arrays must be of equal size.
*
* #param labels The first column contains labels.
* #param fields The last column contains fields.
* #return JComponent A JPanel with two columns of the components provided.
*/
public static JComponent getTwoColumnLayout(
JLabel[] labels,
JComponent[] fields) {
return getTwoColumnLayout(labels, fields, true);
}
}
The problem is that you need to understand GridBagLayout. You need to layout your components onto a proper grid:
So you should have 5 rows and 12 columns to layout the way you described in your picture. Don't mind the padding (I tried to add that to make it more illustrative). Your first three rows should each have elements of gridwidth = 6 and the first should be at gridx = 0 and the second at gridx = 6. Then your "yes" and "no" buttons should each have gridwidth = 3 at gridx = 6 and gridx = 9, respectively. Finally your last row, the buttons, should each have gridwidth = 2 and gridx = 1, gridx = 5, and gridx = 9, respectively. Instead of using padding, I would just use gbc.anchor = GridBagConstraints.CENTER (for all of the components) so that the components are centered inside of their grid.
I would suggest using gbc.fill = GridBagConstraints.HORIZONTAL for the text field and combo boxes so that they line up "nice and pretty" but don't forget to set that back to gbc.fill = GridBagConstraints.NONE for the radio buttons and regular buttons (unless you want them to stretch as well).
I very haphazardly changed your code (which appeared to be in no logical order):
// Creating the grid to location of the parts
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.CENTER;
// Initializing the buttons
submit = new JButton("Submit");
c.insets = new Insets(10, 10, 10, 5);
c.gridx = 1;
c.gridy = 5;
c.gridwidth = 2;
panel.add(submit, c);
reset = new JButton("Reset");
c.gridx = 5;
// c.gridy = 20;
panel.add(reset, c);
cancel = new JButton("Cancel");
c.gridx = 9;
// c.gridy = 20;
panel.add(cancel, c);
// Handler constructor to do the actionlistening
Handler handler = new Handler();
submit.addActionListener(handler);
reset.addActionListener(handler);
cancel.addActionListener(handler);
// Creating the two dropdowns with the words next to them
JLabel chooseCollection = new JLabel("Choose Collection");
String[] ccString = { "All", "Mostly", "Some", "Few" };
JComboBox ccComboBox = new JComboBox(ccString);
JLabel searchUsing = new JLabel("Search Using");
String[] suString = { "Title", "Artist", "Arthor", "Type" };
JComboBox suComboBox = new JComboBox(suString);
// Adding all the text and dropdown menus to the panel
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 6;
c.anchor = GridBagConstraints.WEST;
panel.add(chooseCollection, c);
c.gridx = 6;
// c.gridy = 25;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(ccComboBox, c);
c.gridx = 0;
c.gridy = 2;
c.fill = GridBagConstraints.NONE;
panel.add(searchUsing, c);
c.gridx = 6;
// c.gridy = 27;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(suComboBox, c);
// Setting up the text inputbox
JLabel keyword = new JLabel("Keyword or phrase");
JTextField textField = new JTextField(20);
// Adding lable and text box to the panel
c.gridx = 0;
c.gridy = 1;
c.fill = GridBagConstraints.NONE;
panel.add(keyword, c);
c.gridx = 6;
panel.add(textField, c);
Which produced the following layout:
i would probably do it like this:
public class Test {
public Test() {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel(new GridLayout(0, 1));
JPanel chooseCollectionPanel = new JPanel(new BorderLayout());
JPanel keywordPanel = new JPanel(new BorderLayout());
JPanel searchCategoryPanel = new JPanel(new BorderLayout());
// ...
mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
chooseCollectionPanel.setBorder(BorderFactory.createEmptyBorder(5, 0,
5, 0));
keywordPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
searchCategoryPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5,
0));
JLabel chooseCollectionLabel = new JLabel("Choose Collection: ");
JComboBox<String> chooseCollectionCB = new JComboBox<String>();
chooseCollectionCB.addItem("All");
chooseCollectionPanel.add(chooseCollectionLabel, BorderLayout.WEST);
chooseCollectionPanel.add(chooseCollectionCB, BorderLayout.CENTER);
JLabel chooseCollectionkeywordLabel = new JLabel("Choose Collection: ");
JTextField keywordCB = new JTextField(10);
keywordPanel.add(chooseCollectionkeywordLabel, BorderLayout.WEST);
keywordPanel.add(keywordCB, BorderLayout.CENTER);
// ...
mainPanel.add(chooseCollectionPanel);
mainPanel.add(keywordPanel);
mainPanel.add(searchCategoryPanel);
// ...
frame.add(mainPanel);
frame.setSize(400, 400);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
new Test();
}
}
This question already has an answer here:
constraint must be a string (or null)
(1 answer)
Closed 8 years ago.
My components are lining up like they are in a flowlayout. I add constraints to them, but it seems to not be following them, for what ever reason. I think I might be accidentally incorporating flowlayout somewhere, but I dont know where.
code:
BorderLayout borderLayout = new BorderLayout();
setLayout(borderLayout);
//Initialize labels, text field, and combo box
enterFirstName = new JLabel ("First Name");
firstName = new JTextField();
enterLastName = new JLabel ("Last Name");
lastName = new JTextField();
enterId = new JLabel ("Identification");
identification = new JTextField();
enterAddress = new JLabel("Address");
streetAddress = new JTextField();
enterCity = new JLabel("City");
city = new JTextField();
selectState = new JLabel("State");
state = new JComboBox();
enterZip = new JLabel("Zip Code");
zipCode = new JTextField();
enterPhone = new JLabel("Phone Number");
phoneNumber = new JTextField();
//Initialize buttons
goBack = new JButton ("Go Back");
purchase = new JButton ("Complete Purchase");
cancel = new JButton ("Cancel");
//making the grid thing
dataPane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
dataPane.add(enterFirstName);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 0;
dataPane.add(firstName);
c.gridx = 0;
c.gridy = 1;
dataPane.add(enterLastName);
dataPane.add(enterLastName);
buttonPane = new JPanel();
buttonPane.add(goBack);
buttonPane.add(purchase);
buttonPane.add(cancel);
add(dataPane);
add(buttonPane, BorderLayout.SOUTH);
}
}
You're not supply constraints for the components...
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
dataPane.add(enterFirstName); // ?? No constraints...
//...
dataPane.add(firstName);
//...
dataPane.add(enterLastName);
// No idea why this is here...
dataPane.add(enterLastName);
Make sure you supply the constraints you want to use...
dataPane.add(enterFirstName, gbc);
Take a look at How to Use GridBagLayout for more details...
This is what my GUI looks like now:
I want it to have the three columns to be equally distributed. To do this, I set each of the weights equal to 1/3. Obviously, it's not working.
Here is my code for creating the Frame:
public static JPanel createLayout(int rows) {
JPanel product = new JPanel(new GridBagLayout());
String[] lables = {"School ", "Advanced #", "Novice # "};
double weight = .3333333333333;
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(3, 3, 3, 3);
c.weightx = weight;
c.fill = GridBagConstraints.HORIZONTAL;
c.anchor = GridBagConstraints.CENTER;
c.gridy = 1;
for (int j = 0; j < lables.length; j++) {
c.gridx = j;
JLabel l = new JLabel(lables[j]);
product.add(l, c);
}
for (int i = 0; i < rows; i++) {
c.gridy++;
for (int j = 0; j < lables.length; j++) {
c.gridx = j;
JTextField f = new JTextField();
product.add(f, c);
}
}
c.gridy++;
c.gridx = 0;
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.NONE;
JPanel b = new JPanel();
JButton add = new JButton("+");
b.add(add);
JButton delete = new JButton("-");
b.add(delete);
product.add(b, c);
return product;
}
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Debate Calculator");
JPanel debates = new JPanel();
frame.add(createLayout(5), BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
}
The problem is that you components are not equally sized to begin with. I can't explain exactly why it does what it does, but the size of your labels is each different because they have a different number of characters. I know you tried to make then the same size, but a " " is not the same as "W".
I changed your code to use the following and it seems to work:
JTextField f = new JTextField(10);
Now the width of each text field is greater than the label, so that is the width that is used to give each column a proportional size.
You might consider using a GridLayout. The default behaviour is to make each cell the same size.
The problem is your button bar at the bottom. Set the gridwidth to REMAINDER on that element.