Can't close JFrame, from click inside JPanel - java

I have the following situation:
I have a JFrame(GridBagLayout) with 3 JPanels in it (headerPanel, bodyPanel, footerPanel);
On the bodyPanel I have a login button;
What I want, is to close the JFrame, an open another one;
Main:
package com.system.reservation.airline;
public class Main {
public static void main(String[] args) { // Main function that executes the program
LoginPage loginPage = new LoginPage();
}
}
LoginPage:
public class LoginPage extends JFrame{
HeaderPanel headerPanel = new HeaderPanel();
BodyPanel bodyPanel = new BodyPanel();
FooterPanel footerPanel = new FooterPanel();
public LoginPage(){ // Constructor
this.setTitle("Login"); // Frame title
this.setSize(400, 600); // Frame size
this.setLocationRelativeTo(null); // Center frame, when launched
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Frame function, on close button (will close)
this.getContentPane().setBackground(new Color(240,248,255)); // Light blue
this.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 1;
this.add(headerPanel, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridheight = 1;
this.add(bodyPanel, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridheight = 3;
this.add(footerPanel, gbc);
this.pack();
this.setVisible(true); // Frame visible
}
}
BodyPanel:
package com.system.reservation.airline.panels;
import com.system.reservation.airline.HomePage;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class BodyPanel extends JPanel implements ActionListener { // Listens to events
JButton login_button;
JTextField userName_txb, password_txb;
JLabel tokenResponse;
String username;
String password;
public void setUsername(String newUsername){
username = newUsername;
}
public String getUsername(){
return username;
}
public void setPassword(String newPassword){
password = newPassword;
}
public String getPassword(){
return password;
}
public BodyPanel(){
Color transparent = new Color(1f,0f,0f,0f);
this.setBackground(transparent);
this.setLayout(new BorderLayout());
//this.setBorder(BorderFactory.createLineBorder(Color.green, 3));
//------------ Login Panel ------------------------
JPanel login_panel = new JPanel(new BorderLayout());
login_panel.setBackground(transparent);
login_panel.setPreferredSize(new Dimension(400, 50));
//login_panel.setBorder(BorderFactory.createLineBorder(Color.YELLOW, 5));
JLabel login_label = new JLabel();
login_label.setText("Login");
login_label.setHorizontalAlignment(JLabel.CENTER);
login_label.setFont(new Font("Arial", Font.PLAIN, 20));
login_panel.add(login_label, BorderLayout.CENTER);
//------------ Login Panel ------------------------
//------------ Input Panel ------------------------
JPanel input_fields_panel = new JPanel(new GridBagLayout());
input_fields_panel.setBackground(transparent);
//input_fields_panel.setPreferredSize(new Dimension(400, 150));
//input_fields_panel.setBorder(BorderFactory.createLineBorder(Color.black, 5));
GridBagConstraints gbc = new GridBagConstraints();
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
//-------------
JLabel userName_label = new JLabel("Username: ");
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.insets = new Insets(0,10,0,0);
input_fields_panel.add(userName_label, gbc);
userName_txb = new JTextField();
userName_txb.setPreferredSize(new Dimension(250,30));
gbc.gridx = 3;
gbc.insets = new Insets(5,0,5,20);
input_fields_panel.add(userName_txb, gbc);
//-------------
//-------------
JLabel password_label = new JLabel("Password: ");
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.insets = new Insets(0,10,0,0);
input_fields_panel.add(password_label, gbc);
password_txb = new JTextField();
password_txb.setPreferredSize(new Dimension(250,30));
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 3;
gbc.gridheight = 1;
gbc.insets = new Insets(5,0,5,20);
input_fields_panel.add(password_txb, gbc);
//-------------
//------ Login Button -----------
login_button = new JButton("Login");
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 4;
gbc.gridheight = 1;
gbc.insets = new Insets(10,150,5,150);
login_button.addActionListener(this);
input_fields_panel.add(login_button, gbc);
//------ Login Button -----------
tokenResponse = new JLabel("");
tokenResponse.setHorizontalAlignment(JLabel.CENTER);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 4;
gbc.gridheight = 1;
gbc.insets = new Insets(0,0,0,0);
input_fields_panel.add(tokenResponse, gbc);
//------------ Input Panel ------------------------
//-------------------------------------
this.add(login_panel, BorderLayout.NORTH);
this.add(input_fields_panel, BorderLayout.CENTER);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == login_button) {
System.out.println("Olá");
//-------------------------
if(userName_txb.getText().replaceAll("\\s+","").equals("") || password_txb.getText().replaceAll("\\s+","").equals("")){ // removes white spaces
// If either of the text fields are empty, a label is displayed
System.out.println("It's empty!");
tokenResponse.setText("The input fields are empty!");
} else {
String userName_value = userName_txb.getText();
String userPassword_value = password_txb.getText();
// User inputs are stored
setUsername(userName_value);
setPassword(userPassword_value);
// User inputs are initialized
//-----------------------
try{
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/user_login", "root", "***********");
// Connect to the database;
Statement statement = connection.createStatement();
// It will initiate a command;
ResultSet resultSet = statement.executeQuery("select customer_username, customer_password from user_authentication");
// Execute the command; // column // table
while (resultSet.next()){ // While there are results, it will print them;
String name = resultSet.getString("customer_username");
String password = resultSet.getString("customer_password");
if(!getUsername().equals(name) || !getPassword().equals(password)){
tokenResponse.setText("The username or the password are incorrect!");
System.out.println("It does not match!");
//break;
} else {
// CLOSE JFRAME
System.out.println("It matches!");
HomePage homePage = new HomePage();
break;
}
}
}catch(Exception e2){
e2.printStackTrace();
}
}
}
}
}
After I click login the JFrame on the left shows up.
I want to close the one on the right.
Any help would be appreciated, thanks.

Answer from #camickr, managed to close Jframe, from click inside Jpanel:
login_button = (JButton) e.getSource();
SwingUtilities.windowForComponent(login_button).dispose();

Related

How to update Jpanel using JComboBox

i'm new in java language, and i'm trying to create a GUI which it has JComboBox to allow the user to select one of the choices and based on the selected option the panel is updated by adding more text fields.
currently i'm facing an issue which is the panel doesn't updated if I choosed (choice 1) it should appear 5 text fields with their labels.
My question is: how can I update the panel to add more text fields based on the selected option from JComboBox by the user?
Also, I'm facing another issue which i couldn't find a way to setting the size of JFrame
Here is my code:
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class RTSS extends JFrame implements ActionListener {
private JComboBox cb;
JPanel main;
JPanel panel3;
JPanel panel2;
JPanel panel1;
GridBagConstraints gbc;
String[] choices;
JLabel Label1;
JLabel Label2;
JLabel Label3;
JLabel Label4;
JLabel Label5;
JTextField tf1;
JTextField tf2;
JTextField tf3;
JTextField tf4;
JTextField tf5;
public RTSS() {
Border blackline = BorderFactory.createLineBorder(Color.black);
EmptyBorder b1 = new EmptyBorder(5, 0, 0, 0);
main = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel3 = new JPanel(new FlowLayout(FlowLayout.LEFT));
panel3.setAlignmentX(1);
panel3.setPreferredSize(new Dimension(800, 35));
panel3.setBorder(b1);
main.add(panel3);
panel2 = new JPanel();
panel1 = new JPanel();
panel1.setPreferredSize(new Dimension(700, 500));
panel1.setBorder(blackline);
panel1.setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
choices = new String[]{ "","Choice 1", "Choice 2", "Choice 3 "};
cb = new JComboBox(choices);
//Main inputs (labels)
Label1 = new JLabel("Label 1 ");
Label2 = new JLabel("Label 2 ");
Label3 = new JLabel("Label 3");
Label4 = new JLabel("Label 4 ");
Label5 = new JLabel("Label 5 ");
//TextFields
tf1 = new JTextField(10);
tf2 = new JTextField(10);
tf3 = new JTextField(10);
tf4 = new JTextField(10);
tf5 = new JTextField(10);
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.insets = new Insets(10, 3, 5, 0);
panel3.add(cb);
panel2.add(panel1);
gbc.gridx = 0;
gbc.gridy = 0;
panel1.add(Label1, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
panel1.add(Label2, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
panel1.add(Label3, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
panel1.add(tf1, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
panel1.add(tf2, gbc);
gbc.weightx = 0.5;
gbc.weighty = 0.5;
gbc.gridx = 1;
gbc.gridy = 2;
panel1.add(tf3, gbc);
main.add(panel2);
add(main);
}
#Override
public void actionPerformed(ActionEvent e) {
String Choice = cb.getSelectedItem().toString();
if ("Choice 1".equals(Choice)) {
gbc.gridx = 0;
gbc.gridy = 3;
panel1.add(Label4, gbc);
gbc.gridx = 1;
gbc.gridy = 3;
panel1.add(tf4, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
panel1.add(Label5, gbc);
gbc.weightx = 6;
gbc.weighty = 1;
gbc.gridx = 1;
gbc.gridy = 4;
panel1.add(tf5, gbc);
}
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new RTSS().setVisible(true);
}
});
}
}
Add the following lines to the end of the RTSS constructor:
public RTSS() {
//your code
//this lines
pack();
setLocationRelativeTo(null);
cb.addActionListener(this);
}
These 3 lines will 1.set the layout, 2. center the frame and 3. activate the ActionListener.
If you now make a selection in the ComboBox, your code will be executed in the ActionListener.
After a selection in the ComboBox that changes the layout, call pack() again.
#Override
public void actionPerformed(ActionEvent e) {
String Choice = cb.getSelectedItem().toString();
if ("Choice 1".equals(Choice)) {
// your code
pack();
}
}

JRadioButton is not show properly

I want to create a simple food ordering system, now i'm creating the interface of an order form. I used GridBagLayout for create the form layout, my problem is when I want to assign 3 radio button in same row, it's only show me 1 of the button....I hope somebody can help me pls....
Here is my java code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;
/**
*
* #author user
*/
public class ChickenChopOrderingSystem
{
JFrame frame;
JPanel mainPanel, p1, p2, p3, p4;
JLabel lblTitle, lblName, lblPhoneNum, lblFlavour, lblChickenPart;
JTextField txtName, txtPhoneNum;
String flavour[] = {"Black Pepper Sauce", "Hainanese", "Grilled", "Lemon"};
JComboBox box;
ButtonGroup bg = new ButtonGroup();
JRadioButton btnWhole, btnHalf, btnQuarter;
JButton btnDone, btnExit;
public ChickenChopOrderingSystem()
{
frame = new JFrame("Chicken Chop Ordering System");
mainPanel = new JPanel();
mainPanel.setPreferredSize(new Dimension(700,700));
mainPanel.setBackground(Color.yellow);
lblName = new JLabel("Customer's Name: ");
txtName = new JTextField(20);
lblPhoneNum = new JLabel("Phone Number: ");
txtPhoneNum = new JTextField(11);
lblChickenPart = new JLabel("Select Part of Chicken: ");
btnWhole = new JRadioButton("Whole");
btnWhole.addItemListener(new OperationListener());
btnHalf = new JRadioButton("Half");
btnHalf.addItemListener(new OperationListener());
btnQuarter = new JRadioButton("Quarter");
btnQuarter.addItemListener(new OperationListener());
bg.add(btnWhole);
bg.add(btnHalf);
bg.add(btnQuarter);
lblFlavour = new JLabel("Select a flavour: ");
box = new JComboBox(flavour);
btnDone = new JButton("Done");
btnExit = new JButton("Exit");
btnExit.addActionListener(new ButtonListener());
//GridBaglayout
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
//Label
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.5;
gbc.weighty = 0.5;
mainPanel.add(lblName, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 0.5;
mainPanel.add(lblPhoneNum, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 0.5;
mainPanel.add(lblChickenPart, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.weightx = 0.5;
mainPanel.add(lblFlavour, gbc);
//TextField
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 3;
mainPanel.add(txtName, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 3;
mainPanel.add(txtPhoneNum, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 2;
mainPanel.add(btnWhole, gbc);
gbc.gridx = 2;
gbc.gridy = 2;
mainPanel.add(btnHalf, gbc);
gbc.gridx = 3;
gbc.gridy = 2;
mainPanel.add(btnHalf, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 3;
mainPanel.add(box, gbc);
//frame setting
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(mainPanel, new GridBagConstraints());
frame.setSize(new Dimension(1000, 1000));
frame.setVisible(true);
}
public class OperationListener implements ItemListener
{
#Override
public void itemStateChanged(ItemEvent ie) {
if (ie.getSource() == btnWhole)
{
if (ie.getStateChange() == ItemEvent.SELECTED)
{
box.removeAllItems();
box.addItem(flavour[2]);
}
} if (ie.getSource() == btnHalf)
{
if (ie.getStateChange() == ItemEvent.SELECTED)
{
box.removeAllItems();
box.addItem(flavour[0]);
box.addItem(flavour[2]);
box.addItem(flavour[3]);
}
} if (ie.getSource() == btnQuarter)
{
if (ie.getStateChange() == ItemEvent.SELECTED)
{
box.removeAllItems();
box.addItem(flavour[0]);
box.addItem(flavour[1]);
box.addItem(flavour[3]);
}
}
}
}
public class ButtonListener implements ActionListener
{
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource() == btnExit)
{
int s = JOptionPane.showConfirmDialog(null, "Are you sure you want to exit?",
"Exit", JOptionPane.YES_NO_OPTION);
if (s == JOptionPane.YES_OPTION)
{
System.exit(0);
}
}
}
}
public static void main(String[] args)
{
ChickenChopOrderingSystem run = new ChickenChopOrderingSystem();
}
}
Click here to view output
For something like this:
Use this code:
import java.awt.*;
import javax.swing.*;
public class ChickenChopOrderingSystem {
JFrame frame;
JPanel mainPanel, p1, p2, p3, p4;
JLabel lblTitle, lblName, lblPhoneNum, lblFlavour, lblChickenPart;
JTextField txtName, txtPhoneNum;
String flavour[] = {"Black Pepper Sauce", "Hainanese", "Grilled", "Lemon"};
JComboBox box;
ButtonGroup bg = new ButtonGroup();
JRadioButton btnWhole, btnHalf, btnQuarter;
JButton btnDone, btnExit;
public ChickenChopOrderingSystem() {
frame = new JFrame("Chicken Chop Ordering System");
mainPanel = new JPanel();
// GUESSWORK!
//mainPanel.setPreferredSize(new Dimension(700,700));
mainPanel.setBackground(Color.yellow);
lblName = new JLabel("Customer's Name: ");
txtName = new JTextField(20);
lblPhoneNum = new JLabel("Phone Number: ");
txtPhoneNum = new JTextField(11);
lblChickenPart = new JLabel("Select Part of Chicken: ");
btnWhole = new JRadioButton("Whole");
btnHalf = new JRadioButton("Half");
btnQuarter = new JRadioButton("Quarter");
bg.add(btnWhole);
bg.add(btnHalf);
bg.add(btnQuarter);
lblFlavour = new JLabel("Select a flavour: ");
box = new JComboBox(flavour);
btnDone = new JButton("Done");
btnExit = new JButton("Exit");
//GridBaglayout
mainPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
int s = 20;
gbc.insets = new Insets(s,s,s,s);
//Label
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.5;
gbc.weighty = 0.5;
mainPanel.add(lblName, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weightx = 0.5;
mainPanel.add(lblPhoneNum, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 2;
gbc.weightx = 0.5;
mainPanel.add(lblChickenPart, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.weightx = 0.5;
mainPanel.add(lblFlavour, gbc);
//TextField
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.gridwidth = 3;
mainPanel.add(txtName, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 3;
mainPanel.add(txtPhoneNum, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.weightx = 1d/6d;
mainPanel.add(btnWhole, gbc);
gbc.gridx = 2;
gbc.gridy = 2;
mainPanel.add(btnHalf, gbc);
gbc.gridx = 3;
gbc.gridy = 2;
mainPanel.add(btnQuarter, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 3;
gbc.gridwidth = 3;
mainPanel.add(box, gbc);
//frame setting
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(mainPanel, new GridBagConstraints());
// GUESSWORK!
//frame.setSize(new Dimension(1000, 1000));
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
ChickenChopOrderingSystem run = new ChickenChopOrderingSystem();
}
}
The problems in the original code were many. (Trawling memory..)
The constraints of the last element were not set back to grid width of 3, confusing the layout manager.
The ItemListener was doing strange stuff with removing components, don't do that.
The preferred size of the panel, and the size of the frame, were guesswork. Use pack() to have the correct size calculated. (Add a standard Inserts to the initial constraints for white space.)

GridBagLayout - Vertically positioning components

Trying to align a form next to my JTable with GridBagLayout and I am struggling to get my components to the top of the panel. I need the price label and fields just underneath the item label and field but I cannot get it to move from the bottom of the panel.
If I use anchor = GridConstraints.NORTHWEST, this moves the item label and field to the top, but then I lose the ability to anchor it with LINE_END. Unless there is a way to do both? Please see my image where I have attempted to demonstrate the area I want to place my form. Appreciate any help.
GridBagConstraints gbc = new GridBagConstraints();
// TEST COMPONENTS
JLabel lblItem = new JLabel("Item: ");
JLabel lblPrice = new JLabel("Price: ");
JLabel lblQuantity = new JLabel ("Quantity: ");
JTextField itemField = new JTextField(15);
JTextField pricePoundsField = new JTextField(3);
JTextField pricePenceField = new JTextField(2);
JTextField quantityField = new JTextField(3);
gbc.gridx = 0;
gbc.gridy = 0;
//gbc.weightx = 1.0;
//gbc.weighty = 1.0;
gbc.anchor = GridBagConstraints.LINE_START;
panelStockTable.add(jsp, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_END;
panelStockTable.add(lblItem, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
panelStockTable.add(lblPrice, gbc);
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridx = 2;
gbc.gridy = 0;
panelStockTable.add(itemField, gbc);
gbc.gridx = 2;
gbc.gridy = 1;
panelStockTable.add(pricePoundsField, gbc);
The more complex a UI becomes, the more you want to focus on isolating the functionality and layouts to their own containers/classes.
This is where the concept of compounding layouts becomes very powerful. Rather then laying the fields out directly onto the same container as the table, use a separate container for them
Here, the right panel is standing in for the table and the blue panel is demonstrating the compounding container...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JPanel stockTableProxy = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 150);
}
};
stockTableProxy.setBackground(Color.RED);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.LINE_START;
add(stockTableProxy, gbc);
JPanel fieldsPanel = new JPanel(new GridBagLayout());
fieldsPanel.setBackground(Color.BLUE);
// TEST COMPONENTS
JLabel lblItem = new JLabel("Item: ");
JLabel lblPrice = new JLabel("Price: ");
JLabel lblQuantity = new JLabel("Quantity: ");
JTextField itemField = new JTextField(15);
JTextField pricePoundsField = new JTextField(3);
JTextField pricePenceField = new JTextField(2);
JTextField quantityField = new JTextField(3);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_END;
fieldsPanel.add(lblItem, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
fieldsPanel.add(lblPrice, gbc);
gbc.anchor = GridBagConstraints.LINE_START;
gbc.gridx = 2;
gbc.gridy = 0;
fieldsPanel.add(itemField, gbc);
gbc.gridx = 2;
gbc.gridy = 1;
fieldsPanel.add(pricePoundsField, gbc);
gbc.gridx = 0;
gbc.gridy = 20;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weighty = 1;
fieldsPanel.add(new JLabel(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.VERTICAL;
add(fieldsPanel, gbc);
}
}
}
But wait, there is more...
gbc.gridx = 0;
gbc.gridy = 20;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weighty = 1;
fieldsPanel.add(new JLabel(), gbc);
This is a little trick you can use to force component to move to different edges of the container, here, I've used it to push all the fields to the top of the container.
All it does is add a transparent component (in this a JLabel) and provides all the left over space to it, neat

Java GridBagLayout : make component align to left

I have this layout using GridBagLayout:
public class Example extends JFrame {
public Example() {
Border outline = BorderFactory.createLineBorder(Color.black);
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
JPanel pane = new JPanel(gbl);
gbc.weighty = 1.0;
gbc.weightx = 1.0;
JLabel unitLbl = new JLabel("Unit");
unitLbl.setBorder(outline);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 30;
gbc.ipady = 10;
gbl.setConstraints(unitLbl, gbc);
pane.add(unitLbl);
JLabel typeLbl = new JLabel("Type");
typeLbl.setBorder(outline);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 30;
gbc.ipady = 10;
gbl.setConstraints(typeLbl, gbc);
pane.add(typeLbl);
JTextField unitField = new JTextField();
typeLbl.setBorder(outline);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.ipadx = 30;
gbc.ipady = 10;
gbl.setConstraints(unitField, gbc);
pane.add(unitField);
String[] type = {"All", "Verb", "Noun", "Adjective"};
JComboBox<String> comboBox = new JComboBox<String>(type);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.ipadx = 30;
gbc.ipady = 10;
gbl.setConstraints(comboBox, gbc);
pane.add(comboBox);
add(pane, BorderLayout.CENTER);
setSize(new Dimension(400, 300));
getContentPane().setBackground(Color.WHITE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
}
In this example, when run, It seems that every component is at the center of the frame. But what I want is :
Two JLabel (unitLbl and typelbl) will be on the left of frame
JTextField and JComboBox will be on the right of two JLabel, respectively with a small distance between.
Moreover, I want to add a new JButton at location (3,0) of the grid, but the height of this location sum of two JLabel height. It means, this button height is on "two line".
How can I fix this code to achieve this goal ? Please help me.
Thanks :)
Something like this should do the trick:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
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.SwingUtilities;
public class Example extends JFrame {
public Example() {
GridBagLayout gbl = new GridBagLayout();
GridBagConstraints gbc = new GridBagConstraints();
JPanel pane = new JPanel(gbl);
gbc.anchor = GridBagConstraints.WEST;
JLabel unitLbl = new JLabel("Unit");
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(3, 3, 3, 30);
gbl.setConstraints(unitLbl, gbc);
pane.add(unitLbl);
JLabel typeLbl = new JLabel("Type");
gbc.gridx = 0;
gbc.gridy = 1;
gbl.setConstraints(typeLbl, gbc);
pane.add(typeLbl);
gbc.weightx = 1.0;
gbc.insets = new Insets(3, 3, 3, 3);
JTextField unitField = new JTextField();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbl.setConstraints(unitField, gbc);
pane.add(unitField);
String[] type = { "All", "Verb", "Noun", "Adjective" };
JComboBox<String> comboBox = new JComboBox<String>(type);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.NONE;
gbl.setConstraints(comboBox, gbc);
pane.add(comboBox);
final JButton someButton = new JButton("Click me");
someButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(someButton, "You have clicked " + someButton.getText());
}
});
gbc.gridx = 3;
gbc.gridy = 0;
gbc.gridheight = 2;
gbc.fill = GridBagConstraints.VERTICAL;
pane.add(someButton, gbc);
add(pane, BorderLayout.CENTER);
setSize(new Dimension(400, 300));
getContentPane().setBackground(Color.WHITE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
}
You need to use appropriately weightx/weighty (how is the extra horizontal/vertical space redistributed)
Use the appropriate fill attribute (is the component stretched vertically/horizontally/both?)
Use the appropriate anchor attribute (if the component is not stretched, or at least not in both direction, where should it be located within its cell)
I usually prefer to use insets instead of padding, therefore, I prefer insets over ipadx/ipady (extra white-space should be added around the component or inside the component)
You want to use GridBagConsraints#anchor to define the position within the cell that you want to align the component to.
To allow a component to span over number of cells, you want to use GridBagConstraints#gridwidth and GridBagConstraints#gridheight (the default is 1)
public class TestLayout09 {
public static void main(String[] args) {
new TestLayout09();
}
public TestLayout09() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new LayoutPane());
frame.setBackground(Color.WHITE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class LayoutPane extends JPanel {
public LayoutPane() {
Border outline = BorderFactory.createLineBorder(Color.black);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
// I'm not sure this really is what you want, but I may be mistaken
// gbc.weighty = 1.0;
// gbc.weightx = 1.0;
JLabel unitLbl = new JLabel("Unit");
unitLbl.setBorder(outline);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 30;
gbc.ipady = 10;
gbc.anchor = GridBagConstraints.WEST;
add(unitLbl, gbc);
JLabel typeLbl = new JLabel("Type");
typeLbl.setBorder(outline);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 30;
gbc.ipady = 10;
add(typeLbl, gbc);
JTextField unitField = new JTextField();
typeLbl.setBorder(outline);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.ipadx = 30;
gbc.ipady = 10;
gbc.anchor = GridBagConstraints.EAST;
add(unitField, gbc);
String[] type = {"All", "Verb", "Noun", "Adjective"};
JComboBox<String> comboBox = new JComboBox<String>(type);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.ipadx = 30;
gbc.ipady = 10;
add(comboBox, gbc);
JButton btn = new JButton("Test");
gbc.gridx = 3;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.gridheight = 2;
add(btn, gbc);
}
}
}
Some answers:
Put the anchor for unitlbl to WEST.
gbc.anchor = GridBagConstraints.WEST;
And the anchor for unitField to EAST.
gbc.anchor = GridBagConstraints.EAST;
And for the button:
JButton button = new JButton("Test");
gbc.fill = GridBagConstraints.VERTICAL;
gbc.gridx = 3;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 2;
gbc.weighty = 1;
pane.add(button, gbc);

Messed-up GUI: Lot of Blank Space

Please have a look at the following code
package email;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SendEmail extends JDialog
{
private JLabel to, cc, bcc, subject, account;
private JTextField toTxt, ccTxt, bccTxt, subjectTxt;
private JTextArea messageTxt;
private JButton send;
private JComboBox accountBox;
private JScrollPane scroll;
private GridBagLayout gbl;
private GridBagConstraints gbc;
public SendEmail()
{
//Declaring instance variables
to = new JLabel("To: ");
cc = new JLabel("CC: ");
bcc = new JLabel("BCC: ");
subject = new JLabel("Subject: ");
account = new JLabel("Select an Account: ");
toTxt = new JTextField(20);
ccTxt = new JTextField(20);
bccTxt = new JTextField(20);
subjectTxt = new JTextField(20);
messageTxt = new JTextArea(500,500);
scroll = new JScrollPane(messageTxt);
accountBox = new JComboBox();
accountBox.addItem("Yahoo");
accountBox.addItem("GMail");
accountBox.addItem("MSN");
//accountBox.addItem("Yahoo");
//accountBox.addItem("Yahoo");
//Creating thr GUI
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
this.setLayout(gbl);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
this.add(account,gbc);
gbc.gridx = 2;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
this.add(accountBox,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
this.add(to,gbc);
gbc.gridx = 2;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
this.add(toTxt,gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.BOTH;
this.add(bcc,gbc);
gbc.gridx = 2;
gbc.gridy = 3;
gbc.fill = GridBagConstraints.BOTH;
this.add(bccTxt,gbc);
gbc.gridx = 1;
gbc.gridy = 4;
gbc.fill = GridBagConstraints.BOTH;
this.add(cc,gbc);
gbc.gridx = 2;
gbc.gridy = 4;
gbc.fill = GridBagConstraints.BOTH;
this.add(ccTxt,gbc);
gbc.gridx = 1;
gbc.gridy = 5;
gbc.fill = GridBagConstraints.BOTH;
this.add(subject,gbc);
gbc.gridx = 2;
gbc.gridy = 5;
gbc.fill = GridBagConstraints.BOTH;
this.add(subjectTxt,gbc);
gbc.gridx = 1;
gbc.gridy = 6;
gbc.fill = GridBagConstraints.BOTH;
this.add(scroll,gbc);
this.setSize(new Dimension(200,500));
this.setVisible(true);
}
}
In here, the GUI seems very bad. I need to have enough space for all the fields. In the JTextArea, you can see it is not even visible. I need it's height to be 2 columns; it seems like all these problems are occurring because it is trying to set the large JTextArea to one column. For your information, this is an "Compose Email" GUI, so you can be clear of what I am asking. I used this.pack() but it made everything worst!
As I mentioned above in the comments:
Don't call setSize(). Instead pack() the GUI and let the component's natural preferred sizes and the layouts dictate the size of the GUI. If pack() makes things worse, then you should fix the problem from that side of things, not by calling setSize().
For instance, I would
make the JTextArea a reasonable size, not 500 rows by 500 cols!
Don't set size of things
Do call pack()
Don't forget to use weightx and weighty (added to the code) and insets (not yet added).
Avoid magic numbers.
Consider nesting easier to use layouts and minimizing use of GridBagLayout.
Give the JScrollPane extra gridwidth to allow it to fill up the bottom. For instance:
SendEmail.java:
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
#SuppressWarnings("serial")
public class SendEmail extends JDialog {
public final static String[] LABEL_TEXTS = { "Select an Account:", "To:",
"BCC:", "CC:", "Subject:" };
public final static String[] ACCOUNT_TEXTS = { "Yahoo", "GMail", "MSN" };
private static final int TEXT_FIELD_LENGTH = 20;
private static final int T_AREA_ROWS = 20;
private static final int T_AREA_COLS = 50;
private static final int INSET_GAP = 1;
private static final int RIGHT_INSET_GAP = 15;
private Map<String, JTextField> fieldMap = new HashMap<String, JTextField>();
private JTextArea messageTxt;
private JButton send;
private JComboBox<String> accountBox;
private JScrollPane scroll;
public SendEmail(JFrame frame) {
super(frame, "Dialog", true);
messageTxt = new JTextArea(T_AREA_ROWS, T_AREA_COLS);
scroll = new JScrollPane(messageTxt);
accountBox = new JComboBox<String>(ACCOUNT_TEXTS);
this.setLayout(new GridBagLayout());
int ebGap = 5;
((JPanel) getContentPane()).setBorder(BorderFactory.createEmptyBorder(
ebGap, ebGap, ebGap, ebGap));
for (int i = 0; i < LABEL_TEXTS.length; i++) {
JLabel label = new JLabel(LABEL_TEXTS[i]);
addLabel(0, i, label);
if (i == 0) {
addField(1, i, accountBox);
} else {
JTextField tField = new JTextField(TEXT_FIELD_LENGTH);
fieldMap.put(LABEL_TEXTS[i], tField);
addField(1, i, tField);
}
}
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = LABEL_TEXTS.length;
gbc.gridwidth = 2;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(INSET_GAP, INSET_GAP, INSET_GAP, INSET_GAP);
this.add(scroll, gbc);
pack();
this.setVisible(true);
}
private void addField(int x, int y, JComponent comp) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 1.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(INSET_GAP, INSET_GAP, INSET_GAP, INSET_GAP);
gbc.anchor = GridBagConstraints.EAST;
this.add(comp, gbc);
}
private void addLabel(int x, int y, JComponent comp) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(INSET_GAP, INSET_GAP, INSET_GAP, RIGHT_INSET_GAP);
gbc.anchor = GridBagConstraints.EAST;
this.add(comp, gbc);
}
public String getTextFieldText(String key) {
JTextField tField = fieldMap.get(key);
if (tField == null) {
String text = "key, " + key + " not a valid argument for fieldMap";
throw new IllegalArgumentException(text);
}
return tField.getText();
}
public String getAccountText() {
return accountBox.getSelectedItem().toString();
}
public String getMessageTxt() {
return messageTxt.getText();
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
new SendEmail(frame);
frame.dispose();
}
}
which when run would look like:

Categories

Resources