I am trying to make an UI with Swing using only one Container with the GridBagLayout !
My problem is that I want to regroup some JtextFields and Jlabels under one title (TitledBorder) in my interface, is there a way to add the border directly in my container, or should I create another JPanel to regroup my components and then add the hole Panel to my GridBagLayout ?
Based on the pic you provided, the typical solution would be to have 2 separate panels, each with their own TitledBorder, and then place both of these panels on a third outer panel.
However, you could create a similar effect on a single panel by replacing the TitledBorders with a combination of a JLabel followed by a JSeparator.
The difference is that the logical "group" of fields is now only defined by title that isn't surrounding the whole group. Some people prefer this, others do not.
Here's a sample of your pic to give you the idea:
import java.awt.*;
import javax.swing.*;
public class Test implements Runnable
{
private JTextField firstName;
private JTextField lastName;
private JTextField title;
private JTextField nickname;
private JComboBox format;
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Test());
}
public Test()
{
firstName = new JTextField(20);
lastName = new JTextField(20);
title = new JTextField(20);
nickname = new JTextField(20);
format = new JComboBox();
}
public void run()
{
JFrame frame = new JFrame();
frame.getContentPane().add(createPanel());
frame.pack();
frame.setVisible(true);
}
private JPanel createPanel()
{
JPanel p = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4,4,4,4);
gbc.ipadx = 1;
gbc.ipady = 1;
gbc.anchor = GridBagConstraints.WEST;
JLabel nameHeader = new JLabel("Name:");
nameHeader.setForeground(Color.RED.darker());
p.add(nameHeader, gbc);
gbc.gridx = 1;
gbc.gridwidth = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
p.add(new JSeparator(JSeparator.HORIZONTAL), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
p.add(new JLabel("First Name"), gbc);
gbc.gridx = 1;
p.add(firstName, gbc);
gbc.gridx = 2;
p.add(new JLabel("Last Name"), gbc);
gbc.gridx = 3;
p.add(lastName, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
p.add(new JLabel("Title"), gbc);
gbc.gridx = 1;
p.add(title, gbc);
gbc.gridx = 2;
p.add(new JLabel("Nickname"), gbc);
gbc.gridx = 3;
p.add(nickname, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
p.add(new JLabel("Format"), gbc);
gbc.gridx = 1;
gbc.gridwidth = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
p.add(format, gbc);
return p;
}
}
You could play with the constraints to polish this up a bit, but you get the idea.
An upside to this approach is that when adding more fields for the Email section, you can get them to line up with the fields in the Name section. With separate panels, this would be more difficult (you could use a bunch of Box.createHorizontalStrut(...) for this).
The downside to this approach is that you now have a large panel with many fields, and it could get a bit unwieldy to maintain if you need to add more fields.
Try This :
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
class SwingLayoutDemo {
private JFrame mainFrame;
private JLabel headerLabel;
private JLabel statusLabel;
private JPanel controlPanel;
private JLabel msglabel;
public SwingLayoutDemo(){
prepareGUI();
}
public static void main(String[] args){
SwingLayoutDemo swingLayoutDemo = new SwingLayoutDemo();
swingLayoutDemo.showGridBagLayoutDemo();
}
private void prepareGUI(){
mainFrame = new JFrame("Java SWING Examples");
mainFrame.setSize(400,400);
mainFrame.setLayout(new GridLayout(3, 1));
headerLabel = new JLabel("",JLabel.CENTER );
statusLabel = new JLabel("",JLabel.CENTER);
statusLabel.setSize(350,100);
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
controlPanel = new JPanel();
controlPanel.setBorder(new TitledBorder (
new LineBorder (Color.black, 5),
"Title String"));
controlPanel.add(new JLabel("TitledBorder using LineBorder"));
controlPanel.setLayout(new FlowLayout());
mainFrame.add(headerLabel);
mainFrame.add(controlPanel);
mainFrame.add(statusLabel);
mainFrame.setVisible(true);
}
private void showGridBagLayoutDemo(){
headerLabel.setText("Layout in action: GridBagLayout");
JPanel panel = new JPanel();
panel.setBackground(Color.darkGray);
panel.setSize(300,300);
GridBagLayout layout = new GridBagLayout();
panel.setLayout(layout);
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(new JButton("Button 1"),gbc);
gbc.gridx = 1;
gbc.gridy = 0;
panel.add(new JButton("Button 2"),gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.ipady = 20;
gbc.gridx = 0;
gbc.gridy = 1;
panel.add(new JButton("Button 3"),gbc);
gbc.gridx = 1;
gbc.gridy = 1;
panel.add(new JButton("Button 4"),gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = 2;
panel.add(new JButton("Button 5"),gbc);
controlPanel.add(panel);
mainFrame.setVisible(true);
}
}
Related
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();
}
}
I have this code that displays a label, a textfield and a button:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Form extends JFrame implements ActionListener {
private JLabel label = new JLabel("What's your name:");
private JTextField field = new JTextField(15);
private JButton button = new JButton("Send");
public Form() {
setTitle("Name Form");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 1);
gbc.anchor = GridBagConstraints.LINE_END;
gbc.gridx = 0;
gbc.gridy = 0;
add(label, gbc);
gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 1;
gbc.gridy = 0;
add(field, gbc);
gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
gbc.anchor = GridBagConstraints.LINE_END;
gbc.gridx = 0;
gbc.gridy = 1;
add(button, gbc);
}
#Override
public void actionPerformed(ActionEvent event) {
}
public static void main(String[] args) {
Form myFrame = new Form();
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.pack();
myFrame.setVisible(true);
}
}
It shows this:
I need the button to be horizontally centered like this:
How do I do this with GridBagLayout? I tried different values for anchor but nothing worked.
EDIT:
Adding gbc.gridwidth = 2 showed this:
The button needs to stretch over the two columns, so set the gridwidth.
gbc.gridwidth = 2;
(Btw, you don't need to create a new GridBagConstraints for each component. Just reuse the say one and only change the properties that are different.)
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
Is it possible i can have a top panel for a login. Then a middle and bottom panel underneath.
I'm using gridbaglayout and i have assigned 2 panels. One panel has components linked to it for login details and the other panel has other components linked to it. However, it's not going occurring to plan.
Ive tried using Box/Borderlayout to do this, but then i'm not able to create the spacing i want.
Here is a sketch of what i want.
public class GUI extends JFrame{
private JPanel myTopPL, myTopPL2;
private JTextField myUsernameTF;
private JTextField myPasswordTF;
private JTextField myMessageTF;
private JLabel myUsernameLBL;
private JLabel myPasswordLBL;
private JLabel myItemsLBL;
private JTextArea myMainTA;
private JButton myLoginBN;
private JButton myConnectBN;
private JButton mySendBN;
private JComboBox myItemsCB;
public GUI () {
super("GUI ");
setLayout(new GridBagLayout());
myTopPL = new JPanel();
myTopPL2 = new JPanel();
myTopPL.setLayout(new GridBagLayout());
myTopPL2.setLayout(new GridBagLayout());
GridBagConstraints myTopPLGBC = new GridBagConstraints();
myTopPLGBC.weightx = 1;
myTopPLGBC.weighty = 1;
GridBagConstraints myTopPLGBC2 = new GridBagConstraints();
myTopPLGBC.weightx = 2;
myTopPLGBC.weighty = 2;
myUsernameLBL = new JLabel("Username: ");
myUsernameLBL.setFont(new Font("Arial", Font.BOLD, 13));
myTopPLGBC.gridx = 1;
myTopPLGBC.gridy = 1;
myTopPLGBC.insets = new Insets(5,5,5,5);
myTopPL.add(myUsernameLBL, myTopPLGBC);
myUsernameTF = new JTextField(10);
myTopPLGBC.gridx = 2;
myTopPLGBC.gridy = 1;
myTopPLGBC.insets = new Insets(5,5,5,5);
myTopPL.add(myUsernameTF,myTopPLGBC);
myPasswordLBL = new JLabel("Password: ");
myPasswordLBL.setFont(new Font("Arial", Font.BOLD, 13));
myTopPLGBC.gridx = 3;
myTopPLGBC.gridy = 1;
myTopPLGBC.insets = new Insets(5,5,5,5);
myTopPL.add(myPasswordLBL, myTopPLGBC);
myPasswordTF = new JTextField(10);
myTopPLGBC.gridx = 4;
myTopPLGBC.gridy = 1;
myTopPLGBC.insets = new Insets(5,5,5,5);
myTopPL.add(myPasswordTF,myTopPLGBC);
myLoginBN = new JButton("Login");
myTopPLGBC.gridx = 5;
myTopPLGBC.gridy = 1;
myTopPLGBC.insets = new Insets(5,5,5,5);
myTopPL.add(myLoginBN,myTopPLGBC);
myItemsLBL = new JLabel("Items: ");
myItemsLBL.setFont(new Font("Arial", Font.BOLD, 13));
myTopPLGBC2.gridx = 1;
myTopPLGBC2.gridy = 3;
myTopPLGBC2.insets = new Insets(5,5,5,5);
myTopPL2.add(myItemsLBL, myTopPLGBC2);
myItemsCB = new JComboBox();
myItemsCB.addItem(" Select an Item ");
myTopPLGBC2.gridx = 1;
myTopPLGBC2.gridy = 4;
myTopPLGBC2.insets = new Insets(5,5,5,5);
myTopPL2.add(myItemsCB, myTopPLGBC2);
myConnectBN = new JButton("Connect");
myTopPLGBC2.gridx = 2;
myTopPLGBC2.gridy = 4;
myTopPLGBC2.insets = new Insets (5,5,5,5);
myTopPL2.add(myConnectBN, myTopPLGBC2);
GridBagConstraints GBC = new GridBagConstraints();
GBC.anchor = GridBagConstraints.NORTHWEST;
GBC.weightx = 1;
GBC.weighty = 1;
this.add(myTopPL,GBC);
GridBagConstraints GBC2 = new GridBagConstraints();
GBC2.anchor = GridBagConstraints.NORTHWEST;
GBC2.weightx = 2;
GBC2.weighty = 2;
this.add(myTopPL2,GBC2);
}
public static void main(String[] args) {
GUI GUI = new GUI ();
GUI .setDefaultCloseOperation(RMIAuctionHouse.EXIT_ON_CLOSE);
GUI .setSize(750,500);
GUI .setVisible(true);
}
}
I'd break down the application into it's individual areas of responsibilities and focus on creating the UI elements to support it. This will allow you to focus on the needs of each section of your application, it also allows you the opportunity to change around the layout as you need
public class TestLayout15 {
public static void main(String[] args) {
new TestLayout15();
}
public TestLayout15() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MainPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MainPane extends JPanel {
private JTextField messageField;
private JButton sendButton;
public MainPane() {
setBorder(new EmptyBorder(4, 4, 4, 4));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new LoginPane(), gbc);
gbc.gridy++;
add(new ConnectPane(), gbc);
gbc.gridy++;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(new JScrollPane(new JTextArea(5, 20)), gbc);
gbc.gridwidth = 1;
messageField = new JTextField(10);
sendButton = new JButton("Send");
gbc.gridy++;
gbc.weighty = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(messageField, gbc);
gbc.gridx++;
gbc.weightx = 0;
add(sendButton, gbc);
}
}
public class ConnectPane extends JPanel {
private JComboBox comboBox;
private JButton connectButton;
public ConnectPane() {
comboBox = new JComboBox();
connectButton = new JButton("Connect");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
add(comboBox, gbc);
gbc.gridx++;
gbc.weightx = 1;
add(connectButton, gbc);
}
}
public class LoginPane extends JPanel {
private JTextField userNameField;
private JPasswordField passwordField;
private JButton loginButton;
public LoginPane() {
userNameField = new JTextField(10);
passwordField = new JPasswordField(10);
loginButton = new JButton("Login");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
add(new JLabel("User name:"), gbc);
gbc.gridx++;
add(userNameField, gbc);
gbc.gridx++;
add(new JLabel("Password:"), gbc);
gbc.gridx++;
add(passwordField, gbc);
gbc.gridx++;
gbc.weightx = 1;
add(loginButton, gbc);
}
}
}
To start with, replace the call to GUI.setSize(750,500) with GUI.pack(). That will size the window to fit your content. After doing that you'll see the second panel is appearing to the right of the first. This is because you did not set gridx/gridy on GBC2 so it defaults to putting myTopPL2 to the right of myTopPL1, not below it.
I rarely explicitly set the gridx/gridy when using GridBagLayout. For your first row of the display, I would use default values for all but myLoginBN where I would set gridwidth to GridBagConstraints.REMAINDER. That tells GridBagLayout that nothing else goes on this row. The next item added with a default gbc will be placed at the start of the second row.
Minor nits:
Use standard Java capitalization:
Class name are camelcase with a leading uppercase character. So, "Gui", not "GUI".
Instance names are camelcase with a leading lowercase character. So, "gbc1" not "GBC1"
Use SwingUtilities.InvokeLater to start the Gui on the EDT
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GUI GUI = new GUI ();
GUI .setDefaultCloseOperation(RMIAuctionHouse.EXIT_ON_CLOSE);
GUI .setSize(750,500);
GUI .setVisible(true);
}});
Seems you are not familiar with Java layouts, so i recomend you to try null(absolute) Layout:
setLayout(null);
...
component.setBounds( x, y, width, heigh );
add(component);
Here example
package gui;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class GUI extends JFrame{
private JTextField myUsernameTF;
private JLabel myUsernameLBL;
public GUI() {
super("GUI ");
setLayout(null);
myUsernameLBL = new JLabel("Username: ");
myUsernameLBL.setFont(new Font("Arial", Font.BOLD, 13));
myUsernameLBL.setBounds(50,30,80,20);
add(myUsernameLBL);
myUsernameTF = new JTextField(10);
myUsernameTF.setBounds(190,30,80,20);
add(myUsernameTF);
// and so on ...
}
public static void main(String[] args) {
GUI frame = new GUI();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(750,500);
frame.setVisible(true);
}
}
Good luck on thorny way to handle java swing =)
I have the structure as you can see in the picture.
For both panels, GridBagLayout is used.
The problem is that the text field inside the scrollpane is not entirely visible.
The parent panel stretches only for the buttons to become visible, but when the scroll bar appears, it just overlap with the text field.
Is there an easy solution to fix this (don't want to deal with setting custom / preferred / minimum heights)?
Panel structure :
Problem :
Ok, here is an SSCCE
public class Main {
JFrame frame;
private JPanel mainPanel;
private JButton button1;
private JButton button2;
private JTextField someTextTextField;
public static void main(String[] args) {
Main main = new Main();
main.show();
}
private void show() {
frame = new JFrame("Frame");
frame.setContentPane(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
{
$$$setupUI$$$();
}
/**
* Method generated by IntelliJ IDEA GUI Designer
* >>> IMPORTANT!! <<<
* DO NOT edit this method OR call it in your code!
*
* #noinspection ALL
*/
private void $$$setupUI$$$() {
mainPanel = new JPanel();
mainPanel.setLayout(new GridBagLayout());
mainPanel.setPreferredSize(new Dimension(209, 30));
final JPanel panel1 = new JPanel();
panel1.setLayout(new GridBagLayout());
GridBagConstraints gbc;
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 0.5;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
mainPanel.add(panel1, gbc);
button1 = new JButton();
button1.setText("Button");
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel1.add(button1, gbc);
button2 = new JButton();
button2.setText("Button");
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel1.add(button2, gbc);
final JScrollPane scrollPane1 = new JScrollPane();
scrollPane1.setAlignmentX(0.0f);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 0.5;
gbc.weighty = 1.0;
gbc.fill = GridBagConstraints.BOTH;
mainPanel.add(scrollPane1, gbc);
someTextTextField = new JTextField();
someTextTextField.setText("some text");
scrollPane1.setViewportView(someTextTextField);
}
/**
* #noinspection ALL
*/
public JComponent $$$getRootComponent$$$() {
return mainPanel;
}
}
Try and use a JTextArea instead of a JTextField. And if you don't want to set custom/preferred/minimum sizes, you can use the JTextArea.setRows(int rows) method. I hope that helps.