Related
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.
I am trying to get a JScrollPane to appear on my JTable. I passed the table to the scrollpane when i created an instance of the component. But to no avail it has yet to show on my table.
table = new JTable();
scrollPane = new JScrollPane(table);
table.setPreferredSize(new Dimension(200,100));
I dont know how i can fix this issue, i cant seem to find an issue that would cause it to fail. Here is the rest of the GUI code. It is very long. Adding the jtable to a jpanel starts at line 152.
/*
* 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 javasql;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.awt.event.ActionEvent;
import javax.swing.table.DefaultTableModel;
/**
*
* #author KJ4CC
*/
public class UserInterface implements ActionListener {
DefaultTableModel dtm = new DefaultTableModel(0, 0);
public UserInterface() {
startGui();
}
JFrame frame = new JFrame();
Javasql sql = new Javasql();
JPanel buttom = new JPanel(new GridBagLayout());
JPanel commandPane = new JPanel(new GridBagLayout());
JPanel top = new JPanel(new GridBagLayout());
JPanel buttons = new JPanel(new GridBagLayout());
JPanel label = new JPanel(new GridBagLayout());
JButton connect = new JButton("Connect To Database");
JButton clr = new JButton("Clear Command");
JButton exeSql = new JButton("Execute SQL Command");
JButton clrRes = new JButton("Clear Result Window");
JLabel infoLabel = new JLabel("Enter Database Information ");
JLabel driverLabel = new JLabel("JDBC Driver: ");
JLabel dbLabel = new JLabel("Database URL: ");
JLabel userLabel = new JLabel("Username: ");
JLabel passLabel = new JLabel("Password: ");
JLabel sqlLabel = new JLabel("Enter SQL Command: ");
JLabel connectionLabel = new JLabel("No Connection Now ");
JLabel exeLabel = new JLabel("SQL Execution Result: ");
//creating an instance of the new table
public JTable table;
public JScrollPane scrollPane;
JComboBox driverSelect = new JComboBox();
JComboBox url = new JComboBox();
JTextField username = new JTextField();
JTextField pass = new JTextField();
JTextArea command = new JTextArea(1, 1);
public void startGui() {
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GridBagConstraints c = new GridBagConstraints();
System.out.println("sdf");
c.insets = new Insets(0, 0, 0, 10);
c.fill = 0;
c.weightx = 1;
//adding all of the compoenets to their panel and then to the frame.
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
top.add(infoLabel, c);
c.gridx = 0;
c.gridy = 1;
top.add(driverLabel, c);
c.gridx = 1;
c.gridy = 1;
c.ipadx = 150;
c.fill = GridBagConstraints.HORIZONTAL;
top.add(driverSelect, c);
c.gridx = 0;
c.gridy = 2;
c.fill = 0;
top.add(dbLabel, c);
c.gridx = 1;
c.gridy = 2;
c.fill = GridBagConstraints.HORIZONTAL;
top.add(url, c);
c.gridx = 0;
c.gridy = 3;
c.fill = 0;
c.fill = 0;
top.add(userLabel, c);
c.gridx = 1;
c.gridy = 3;
c.fill = GridBagConstraints.HORIZONTAL;
top.add(username, c);
c.gridx = 0;
c.gridy = 4;
c.fill = 0;
c.fill = 0;
top.add(passLabel, c);
c.gridx = 1;
c.gridy = 4;
c.fill = GridBagConstraints.HORIZONTAL;
top.add(pass, c);
//add the driver and url to the comboboxes
c.gridx = 2;
c.gridy = 0;
commandPane.add(sqlLabel, c);
c.gridx = 2;
c.gridy = 1;
c.ipadx = 150;
c.ipady = 75; //sql text area for command
c.fill = GridBagConstraints.FIRST_LINE_END;
c.fill = GridBagConstraints.HORIZONTAL;
commandPane.add(command, c);
c.insets = new Insets(0, 0, 0, 20);
c.ipadx = 9;
c.ipady = 1;
c.gridx = 0;
c.gridy = 0;
//buttons
label.add(connectionLabel, c);
c.gridx = 1;
c.gridy = 0;
//c.insets = new Insets(0, 0, 0, 50);
buttons.add(connect, c);
connect.addActionListener(this);
c.gridx = 2;
buttons.add(clr, c);
clr.addActionListener(this);
c.gridx = 3;
buttons.add(exeSql, c);
exeSql.addActionListener(this);
//adding the label and buttons above and below the tabel.
c.gridx = 0;
c.gridy = 1;
buttom.add(exeLabel, c);
c.gridx = 0;
c.gridy = 2;
//-----------------------------------------------------------------Table here
table = new JTable();
scrollPane = new JScrollPane(table);
table.setPreferredSize(new Dimension(200, 100));
c.fill = GridBagConstraints.HORIZONTAL;
buttom.add(table, c);
buttom.add(scrollPane);
c.gridx = 0;
c.gridy = 3;
buttom.add(clrRes, c);
c.weightx = 2;
c.weighty = 2;
c.gridx = 0;
c.gridy = 0;
frame.setLayout(new GridLayout(3, 2));
frame.add(top);
c.gridx = 2;
c.gridy = 1;
frame.add(commandPane);
frame.add(label);
frame.add(buttons);
frame.add(buttom, BorderLayout.SOUTH);
//adding the content panel to the jframe.
frame.pack();
frame.setSize(1000, 550);
frame.setVisible(true);
//adding items to both of the combo boxes.
driverSelect.addItem("com.mysql.jdbc.Driver");
url.addItem("jdbc:mysql://localhost:3306/project3");
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == connect) {
sql.connect(this);
} else if (e.getSource() == clr) {
command.setText("");
} else if (e.getSource() == exeSql) {
sql.exeCommand(this);
}
}
}
You can not add the table twice :
table = new JTable();
scrollPane = new JScrollPane(table); //here
table.setPreferredSize(new Dimension(200, 100));
c.fill = GridBagConstraints.HORIZONTAL;
buttom.add(table, c); //here
buttom.add(scrollPane);
If you add it to the scrollPane, just add the scrollpane. A Component can't have two parents.
I did not check your complete code but try
buttom.add(scrollPane,c);
instead of this
buttom.add(table, c); //here
buttom.add(scrollPane);
scrollPane = new JScrollPane(table);
table.setPreferredSize(new Dimension(200, 100));
c.fill = GridBagConstraints.HORIZONTAL;
buttom.add(table, c);
buttom.add(scrollPane);
here you add the table twice, directly in the first line and (implicitly) along with the ScrollPane at the last line.
In Swing this is not possible. Therefore the JTable is removed from the Scrollpane at the first line, when you add it directly to the bottom panel, and in turn at the last line an empty scrollpane is added, removing the JTable added earlier.
just remove the first line.
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));
}
}
My problem is that the last 2 columns of my second gridbagconstraints variable are spaced out too much. I have used one gridbagconstraint to manage the first column and the second one deals with the last 3.
Sadly, I cannot provide a screenshot due to being a new user :(
import java.awt.*;
import javax.swing.*;
public class Main_Window_Frame extends JFrame{
//The tabbed pane object is constructed
JTabbedPane TabGroup = new JTabbedPane();
//Jpanels to be added to TabGroup
JPanel panelAddEmployee = new JPanel();//This will create the first tab "Add Employee"
JPanel panelSearchEmployee = new JPanel();//This will create the second tab "Search for an Employee
JPanel panelRemoveEmployee = new JPanel();//This will create the third tab "Remove an Employee"
JPanel panelListAllEmployees = new JPanel();//This will create the fourth tab "List all Employees"
JPanel panelSysOptions = new JPanel();//This will create the fifth tab "System options"
//Construct GridBagConstraints for the objects within panelAddEmployee JPanel
GridBagConstraints c = new GridBagConstraints();
GridBagConstraints gbc = new GridBagConstraints();
//Add employee panel Label declarations
JLabel lblAddEmployee;
JLabel lblEmpID;
JLabel lblEmpIDout;
JLabel lblForename;
JLabel lblSurname;
JLabel lblGender;
JLabel lblDateBirth;
JLabel lblAddress;
JLabel lblPhoneNo;
JLabel lblEmail;
JLabel lblJobTitle;
JLabel lblSalary;
JLabel lblNatNo;
JLabel lblStartDate;
//Add employee panel TextField declarations
JTextField txtForename;
JTextField txtSurname;
JTextField txtAddress;
JTextField txtPhoneNo;
JTextField txtEmail;
JTextField txtJobTitle;
JTextField txtSalary;
JTextField txtNatNo;
//Add employee panel RadioButton declarations
JRadioButton radMale;
JRadioButton radFemale;
//Add employee panel ComboBox declarations
JComboBox cbDob1;
JComboBox cbDob2;
JComboBox cbDob3;
JComboBox cbDateStart1;
JComboBox cbDateStart2;
JComboBox cbDateStart3;
//Add employee panel label array
JLabel[] addEmployeeLabels = new JLabel[13];
//Add employee panel textField array
JTextField[] addEmployeeTextFields = new JTextField[8];
protected String[] DDBirthDate = {"01","02","03","04","05","06","07",
"08","09","10","11","12",
"13","14","15","16","17","18","19",
"20","21","22","23","24","25","26",
"27","28","29","30","31"};
protected String[] MMBirthDate = {"01","02","03","04","05","06","07",
"08","09","10","11","12"};
protected String[] YYYYBirthDate = {"1996","1995","1994","1993","1992",
"1991","1990","1989","1988","1987",
"1986","1985","1984","1983","1982",
"1981","1980 "," 1979 ","1978","1977",
"1976","1975","1974","1973","1972","1971",
"1970","1969","1968","1967 ","1966",
"1965","1964","1963","1962","1961","1960",
"1959","1958","1957","1956","1955",
"1954","1953","1952","1951","1950",
"1949","1948","1947","1946","1945",
"1944","1943","1942","1941"};
protected String[] YYYYStartDate = {"2012","2011","2010"};
public Main_Window_Frame() {
super("Employee Record System");
setSize(750,500); //set the size of the form
//This creates the template for the multiple tabs using JTabbedPane
getContentPane().add(TabGroup);
//Add the GridBagLayout manager to the panelAddEmployee JPanel
panelAddEmployee.setLayout(new GridBagLayout());
//Add the GridBagLayout manager to the panelAddEmployee JPanel
panelSearchEmployee.setLayout(new GridBagLayout());
generateEmployeeAttributeLabels();
addEmployeePanelObjects();
addListAllEmployeesPanelObjects();
addSystemOptionsPanelObjects();
//This adds the first, second, third and final tab to the tabbedPanel Object
TabGroup.addTab("Add Employee", panelAddEmployee);
TabGroup.addTab("Search for an Employee", panelSearchEmployee);
TabGroup.addTab("Remove an Employee", panelRemoveEmployee);
TabGroup.addTab("List all Employees", panelListAllEmployees);
TabGroup.addTab("System Options", panelSysOptions);
}
public void generateEmployeeAttributeLabels(){
//Labels are assigned to a label array
addEmployeeLabels[0] = lblAddEmployee = new JLabel(); lblAddEmployee.setText("Add Employee"); //Set the text to "Add Employee"
addEmployeeLabels[1] = lblEmpID = new JLabel(); lblEmpID.setText("Employee ID:");
addEmployeeLabels[2] = lblForename = new JLabel(); lblForename.setText("Forename:");
addEmployeeLabels[3] = lblSurname = new JLabel(); lblSurname.setText("Surname:");
addEmployeeLabels[4] = lblGender = new JLabel(); lblGender.setText("Gender:");
addEmployeeLabels[5] = lblDateBirth = new JLabel(); lblDateBirth.setText("Date of Birth:");
addEmployeeLabels[6] = lblAddress = new JLabel(); lblAddress.setText("Address:");
addEmployeeLabels[7] = lblPhoneNo = new JLabel(); lblPhoneNo.setText("Phone Number:");
addEmployeeLabels[8] = lblEmail = new JLabel(); lblEmail.setText("Email Address:");
addEmployeeLabels[9] = lblJobTitle = new JLabel(); lblJobTitle.setText("Job Title:");
addEmployeeLabels[10] = lblSalary = new JLabel(); lblSalary.setText("Salary:");
addEmployeeLabels[11] = lblNatNo = new JLabel(); lblNatNo.setText("National Insurance no:");
addEmployeeLabels[12] = lblStartDate = new JLabel(); lblStartDate.setText("Start Date:");
//GridBagConstraints for the title label "Add Employee"
c.fill = GridBagConstraints.HORIZONTAL;
int j = 0;
//This for loop adds all of the labels to the add employee panel.
//More efficient than multiple lines of code for each label.
for(int i = 0; i < 13; i++){
//If the element is the "Add Employee" label then we give it the appropriate sizes
if(i == 0){
c.insets = new Insets(0,0,0,0); //Insets are 0, assigned to upper-most top left
c.weightx = 0.5; //horizontal weight is 0.5
c.gridx = 0; //Place in column 0
c.gridy = 0; //Place in row 0
addEmployeeLabels[0].setFont(new Font("Arial",Font.BOLD,24));
}else{
//If the element is the "Start Date" Label then
if (i == 12){
c.weighty = 1.0; //vertical weight is 0.5
c.anchor = GridBagConstraints.PAGE_START; //Ensures last label is at the edge of its display area
c.gridx = 0; //Place in column 0
c.gridy = 12; //Place in column 12
addEmployeeLabels[12].setFont(new Font("Arial",Font.PLAIN,12));
//For every other label, a default size and relational location is assigned.
}else{
c.insets = new Insets(15,5,0,0);
c.weightx = 0.5;
c.gridx = 0; //Place in column 0
c.gridy = i; //Place in column i (relational positioning based on element index value)
addEmployeeLabels[i].setFont(new Font("Arial",Font.PLAIN,12));
}
}
//Adds each label in the array to the "panelAddEmployee" Panel
panelAddEmployee.add(addEmployeeLabels[i], c);
//Adds each label in the array to the "panelAddEmployee" Panel
//panelSearchEmployee.add(addEmployeeLabels[i], c);
}
}
public void addEmployeePanelObjects(){
gbc.gridwidth = 1;
//Construct lblEmpIDout label
lblEmpIDout = new JLabel();
lblEmpIDout.setText("0");
//Construct radMale radio button
radMale = new JRadioButton();
radMale.setText("Male?");
//Construct radFemale radio button
radFemale = new JRadioButton();
radFemale.setText("Female?");
cbDob1 = new JComboBox();
cbDateStart1 = new JComboBox();
for(int i = 0; i < DDBirthDate.length; i++){
cbDob1.addItem(DDBirthDate[i]);
cbDateStart1.addItem(DDBirthDate[i]);
}
cbDob2 = new JComboBox();
cbDateStart2 = new JComboBox();
for(int i = 0; i < MMBirthDate.length; i++){
cbDob2.addItem(MMBirthDate[i]);
cbDateStart2.addItem(MMBirthDate[i]);
}
cbDob3 = new JComboBox();
cbDateStart3 = new JComboBox();
for(int i = 0; i < YYYYBirthDate.length; i++){
cbDob3.addItem(YYYYBirthDate[i]);
cbDateStart3.addItem(YYYYBirthDate[i]);
}
//TextFields are assigned to a TextField array
addEmployeeTextFields[0] = txtForename = new JTextField();
addEmployeeTextFields[1] = txtSurname = new JTextField();
addEmployeeTextFields[2] = txtAddress = new JTextField();
addEmployeeTextFields[3] = txtPhoneNo = new JTextField();
addEmployeeTextFields[4] = txtEmail = new JTextField();
addEmployeeTextFields[5] = txtJobTitle = new JTextField();
addEmployeeTextFields[6] = txtSalary = new JTextField();
addEmployeeTextFields[7] = txtNatNo = new JTextField();
int j = 0;
//This for loop adds all of the labels to the add employee panel.
//More efficient than multiple lines of code for each label.
for(int i = 0; i < 13; i++){
gbc.insets = new Insets(15,5,0,0);
gbc.gridy = i;
gbc.gridx = 0;
gbc.weightx = 1;
gbc.weighty = 1;
if (i == 0 || i == 1 ||i == 4 || i == 5 || i == 12 ){
if(i==1){
panelAddEmployee.add(lblEmpIDout, gbc);
}
if(i==4){
panelAddEmployee.add(radMale,gbc);
gbc.gridx = 1;
panelAddEmployee.add(radFemale,gbc);
gbc.gridx = 0;
}
if(i==5){
panelAddEmployee.add(cbDob1,gbc);
gbc.gridx = 1;
panelAddEmployee.add(cbDob2,gbc);
gbc.gridx = 2;
panelAddEmployee.add(cbDob3,gbc);
gbc.gridx = 0;
}
if(i==12){
panelAddEmployee.add(cbDateStart1,gbc);
gbc.gridx = 1;
panelAddEmployee.add(cbDateStart2,gbc);
gbc.gridx = 2;
panelAddEmployee.add(cbDateStart3,gbc);
gbc.gridx = 0;
}
//Do not add a text box to title, ID
//gender, date of birth or start date
}else{
//Adds each textfield in the array to the "panelAddEmployee" Panel
panelAddEmployee.add(addEmployeeTextFields[j], gbc);
j++;
}
}
}
public void addSearchEmployeePanelObjects(){
}
public void addListAllEmployeesPanelObjects(){
}
public void addSystemOptionsPanelObjects(){
}
}
Screenshot
The UI I am working on displays a panel which lets a user select a movie and play. There are controls to play, pause, etc.
The layout seems to look the way I want. The panel uses a GridBagLayout. Row 2 displays a text area for status messages and row 3 displays a panel with buttons and a progress bar.
The problem I am running into is that when I have too many lines of text in the text area, the buttons in row 3 wrap around. This is irrespective of the height of the outer frame.
The height in row 2 is affecting the width in row 3. I don't understand this behavior. I am wondering if someone can tell me what is it that I am doing wrong and how I can fix it? I have attached the code.
On a slightly different topic, if you are looking at the code, can you also suggest a way to leave a margin between the bottom-most component and the outermost panel?
Thank you in advance for your help.
Regards,
Peter
private static JButton CreateImageButton(String fileName) {
JButton retVal = new JButton("xxx");
return retVal;
}
public MoviePanel() {
this.setLayout(new GridBagLayout());
this.setBackground(Color.WHITE);
JButton btnRefresh = CreateImageButton("refresh.png");
GridBagConstraints c = new GridBagConstraints();
c.gridx=0;
c.gridy=0;
c.fill = GridBagConstraints.NORTH;
c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
this.add(btnRefresh, c);
JComboBox cbMovieList = new JComboBox();
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets.right = 10; c.insets.top = 10;
c.weightx = 1.0;
this.add(cbMovieList, c);
JButton btnAuthorize = new JButton("Get Info");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.WEST;
c.insets.top = 10;
this.add(btnAuthorize, c);
JTextArea txtInfo = new JTextArea();
txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
txtInfo.setBackground(Color.cyan);
// txtInfo.setText("abc\ndef");
txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 2;
c.anchor = GridBagConstraints.NORTHWEST;
c.weighty = 1.0;
c.insets.top = 10;
this.add(txtInfo, c);
JPanel controllerOuter = new JPanel();
controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());
FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
controllerLayout.setHgap(0);
JPanel controller = new JPanel(controllerLayout);
controller.setBorder(new EmptyBorder(10, 10, 10, 10));
Dimension dim = new Dimension(60, 40);
JButton btnPlay = CreateImageButton("play.png");
btnPlay.setPreferredSize(dim);
controller.add(btnPlay);
JButton btnPause = CreateImageButton("pause.png");
btnPause.setPreferredSize(dim);
controller.add(btnPause);
JButton btnStop = CreateImageButton("stop.png");
btnStop.setPreferredSize(dim);
controller.add(btnStop);
JButton btnForward = CreateImageButton("forward.png");
btnForward.setPreferredSize(dim);
controller.add(btnForward);
JComboBox cbAspectRatio = new JComboBox();
cbAspectRatio.setPreferredSize(new Dimension(100, 40));
cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
controller.add(cbAspectRatio);
controllerOuter.add(controller);
JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setPreferredSize(new Dimension(350, 40));
pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
pbProgress.setValue(50);
pbProgress.setString("50/100");
pbProgress.setStringPainted(true);
pbProgress.setForeground(Color.BLUE);
pbProgress.setBorderPainted(true);
controllerOuter.add(pbProgress);
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 3;
c.gridwidth = 2;
c.weightx = 1.0;
this.add(controllerOuter, c);
}
I see several things in your code:
You force the preferredSize of the JButton's. If possible, I would remove that because this will often get you more problems than solutions. If you want to force the preferredSize, you should also pay attention to set the minimum and maximum sizes as well, otherwise you get weird behaviour like the one you are observing
You use a BoxLayout to display the controls. While this is perfectly acceptable, BoxLayout also relies on min/max size to perform the layout, which you did not set.
You use imbricated layouts. This is fine too, but why not use only the GridBagLayout of your MoviePanel?
Usually TextAreas are wrapped in JScrollPane, in case the text is too big. You can also setLineWrap(true) on the TextArea, so that it does not go too far on the right. By setting rows/columns on the TextArea, you will define its preferreSize (to prevent it from depending of the text it contains).
On your GridBagConstraints, the fill property can only be: NONE, VERTICAL, HORIZONTAL or BOTH (You used VERTICAL for one of them). Also, it is not needed to recreate a new instance, you can reuse the same GridBagConstraint over and over, it is automatically cloned by the LayoutManager when you set the constraint for the component.
Now for the solutions, I found several:
When you add the contollerOuter, also specify c.fill = GridBagConstraints.HORIZONTAL; (This is the easiest way to solve your issues)
When you set the preferredSize of the JButtons, also force their minimumSize to the same value.
Use only the GridBagLayout to layout all components. (This would be my favorite)
Replace the FlowLayout by a BoxLayout with a X_AXIS.
Rember that GridBagConstraints properties :
gridx, gridy: specifies the location
gridwidth, gridheight: specifies the colspan/rowspan
weightx, weighty: specifies who gets the extra horizontal/vertical space and in what proportion
anchor: specifies the alignement of the component withing its "cell", if the "cell" is bigger than the component
fill: specifies if the component should stretch to the cell width/height
Just adding one JPanel each for Center and Bottom will do the trick for you, so till your JTextArea your GridBagLayout will server the purpose and after that the BorderLayout of the MAIN JPanel will do. Moreover, adding JScrollPane also to the whole thing reduces the effort needed at other areas. Have a look at the code and output :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class JTextPaneExample extends JPanel
{
private Icon info = UIManager.getIcon("OptionPane.informationIcon");
private Icon error = UIManager.getIcon("OptionPane.errorIcon");
private static JButton CreateImageButton(String fileName) {
JButton retVal = new JButton("xxx");
return retVal;
}
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("JTextPane Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
this.setBackground(Color.WHITE);
JPanel centerPanel = new JPanel();
centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
centerPanel.setLayout(new GridBagLayout());
centerPanel.setBackground(Color.WHITE);
JButton btnRefresh = CreateImageButton("refresh.png");
GridBagConstraints c = new GridBagConstraints();
c.gridx=0;
c.gridy=0;
c.fill = GridBagConstraints.NORTH;
c.insets.left = 10; c.insets.right = 10; c.insets.top = 10;
centerPanel.add(btnRefresh, c);
JComboBox cbMovieList = new JComboBox();
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.insets.right = 10; c.insets.top = 10;
c.weightx = 1.0;
centerPanel.add(cbMovieList, c);
JButton btnAuthorize = new JButton("Get Info");
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.WEST;
c.insets.top = 10;
centerPanel.add(btnAuthorize, c);
JTextArea txtInfo = new JTextArea();
txtInfo.setFont( new Font("SansSerif", Font.BOLD, 12));
txtInfo.setBackground(Color.cyan);
// txtInfo.setText("abc\ndef");
txtInfo.setText("abc\ndef\nghi\njkl\nmno\npqr\nstu\nvwx\nyz");
JScrollPane scroller = new JScrollPane();
scroller.setViewportView(txtInfo);
c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 2;
c.anchor = GridBagConstraints.NORTHWEST;
c.fill = GridBagConstraints.HORIZONTAL;
c.weighty = 1.0;
c.insets.top = 10;
centerPanel.add(scroller, c);
JPanel controllerOuter = new JPanel();
controllerOuter.setLayout(new BoxLayout(controllerOuter, BoxLayout.Y_AXIS));
controllerOuter.setBorder(BorderFactory.createRaisedBevelBorder());
FlowLayout controllerLayout = new FlowLayout(FlowLayout.CENTER);
controllerLayout.setHgap(0);
JPanel controller = new JPanel(controllerLayout);
controller.setBorder(new EmptyBorder(10, 10, 10, 10));
Dimension dim = new Dimension(60, 40);
JButton btnPlay = CreateImageButton("play.png");
btnPlay.setPreferredSize(dim);
controller.add(btnPlay);
JButton btnPause = CreateImageButton("pause.png");
btnPause.setPreferredSize(dim);
controller.add(btnPause);
JButton btnStop = CreateImageButton("stop.png");
btnStop.setPreferredSize(dim);
controller.add(btnStop);
JButton btnForward = CreateImageButton("forward.png");
btnForward.setPreferredSize(dim);
controller.add(btnForward);
JComboBox cbAspectRatio = new JComboBox();
cbAspectRatio.setPreferredSize(new Dimension(100, 40));
cbAspectRatio.setBorder(new EmptyBorder(0, 10, 0, 0));
controller.add(cbAspectRatio);
controllerOuter.add(controller);
JProgressBar pbProgress = new JProgressBar(0, 100);
pbProgress.setPreferredSize(new Dimension(350, 40));
pbProgress.setBorder(new EmptyBorder(0, 10, 10, 10));
pbProgress.setValue(50);
pbProgress.setString("50/100");
pbProgress.setStringPainted(true);
pbProgress.setForeground(Color.BLUE);
pbProgress.setBorderPainted(true);
controllerOuter.add(pbProgress);
add(centerPanel, BorderLayout.CENTER);
add(controllerOuter, BorderLayout.PAGE_END);
frame.getContentPane().add(this);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new JTextPaneExample().createAndDisplayGUI();
}
});
}
}
Here is the output as you add more lines :