Bottom of JScrollPane is cut off - java

I am trying to create a simple email client and the bottom of the body is being cut-off. If I add a horizontal scroll bar, it does not appear, and the bottom of the Vertical scroll bar does not appear either.
Here is my code:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
#SuppressWarnings("serial")
public class gui extends JFrame{
gui(String title, int x, int y){
super(title);
setSize(x,y);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
}
public void addElements(){
Font size30 = new Font(null, Font.PLAIN, 30);
JPanel pnl = new JPanel();
Container contentPane = getContentPane();
//--- User Info ---//
JPanel userInfo = new JPanel();
JLabel userLabel = new JLabel("Username: ");
JTextField userField = new JTextField(12);
userInfo.add(userLabel);
userInfo.add(userField);
JLabel passLabel = new JLabel("Password: ");
JTextField passField = new JTextField(10);
userInfo.add(passLabel);
userInfo.add(passField);
JLabel serverLabel = new JLabel("Mail Server: ");
JTextField serverField = new JTextField(10);
userInfo.add(serverLabel);
userInfo.add(serverField);
JLabel portLabel = new JLabel("Server Port: ");
JTextField portField = new JTextField(3);
userInfo.add(portLabel);
userInfo.add(portField);
//--- To: CC: and Subject Fields ---//
JPanel msgInfo = new JPanel();
JLabel toLabel = new JLabel("To: ");
JTextField toField = new JTextField(30);
msgInfo.add(toLabel);
msgInfo.add(toField);
JLabel subLabel = new JLabel("Subject: ");
JTextField subField = new JTextField(30);
msgInfo.add(subLabel);
msgInfo.add(subField);
//--- Body ---//
JPanel bodyPnl = new JPanel(new BorderLayout(10,10));
JLabel bodyLabel = new JLabel("Body");
bodyLabel.setFont(size30);
JTextArea bodyField = new JTextArea(30,70);
bodyField.setLineWrap(true);
bodyField.setWrapStyleWord(true);
JScrollPane bodyScroll = new JScrollPane(bodyField);
bodyScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
bodyScroll.setBounds(getX(), getY(), bodyField.getWidth(), bodyField.getHeight());
bodyPnl.add("South",bodyScroll);
pnl.add(userInfo);
pnl.add(msgInfo);
pnl.add(bodyLabel);
pnl.add(bodyScroll);
contentPane.add("North", pnl);
setVisible(true);
}
}
In my main class I am just creating a new gui and then calling the addElements() function.

FlowLayout doesn't "wrap" well. Consider a different layout, GridBagLayout for example...
Also, stop "trying" to force a size onto your UI, you don't have enough control over the factors which affect sizing to do this.
Instead, rely on the layout managers and API functionality. For example, instead of calling setSize on your frame, call pack...I would have posted soon, but it took me this long to find that call...I was scratching my head wondering why the UI wouldn't layout the way I expected...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
Test frame = new Test("Testing", 400, 400);
}
});
}
Test(String title, int x, int y) {
super(title);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addElements();
pack();
setVisible(true);
// setResizable(false);
}
public void addElements() {
Font size30 = new Font(null, Font.PLAIN, 30);
//--- User Info ---//
JPanel userInfo = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 4, 2);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel userLabel = new JLabel("Username: ");
JTextField userField = new JTextField(12);
userInfo.add(userLabel, gbc);
gbc.gridx++;
userInfo.add(userField, gbc);
JLabel passLabel = new JLabel("Password: ");
JTextField passField = new JTextField(10);
gbc.gridx++;
userInfo.add(passLabel, gbc);
gbc.gridx++;
userInfo.add(passField, gbc);
JLabel serverLabel = new JLabel("Mail Server: ");
JTextField serverField = new JTextField(10);
gbc.gridx++;
userInfo.add(serverLabel, gbc);
gbc.gridx++;
userInfo.add(serverField, gbc);
JLabel portLabel = new JLabel("Server Port: ");
JTextField portField = new JTextField(3);
gbc.gridx++;
userInfo.add(portLabel, gbc);
gbc.gridx++;
userInfo.add(portField, gbc);
gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 4, 2);
gbc.gridx = 0;
gbc.gridy = 0;
//--- To: CC: and Subject Fields ---//
JPanel msgInfo = new JPanel(new GridBagLayout());
JLabel toLabel = new JLabel("To: ");
JTextField toField = new JTextField(30);
msgInfo.add(toLabel, gbc);
gbc.gridx++;
msgInfo.add(toField, gbc);
JLabel subLabel = new JLabel("Subject: ");
JTextField subField = new JTextField(30);
gbc.gridx++;
msgInfo.add(subLabel, gbc);
gbc.gridx++;
msgInfo.add(subField, gbc);
//--- Body ---//
// JPanel bodyPnl = new JPanel(new GridBagLayout());
// gbc = new GridBagConstraints();
// gbc.insets = new Insets(2, 2, 4, 2);
// gbc.gridx = 0;
// gbc.gridy = 0;
JLabel bodyLabel = new JLabel("Body");
bodyLabel.setHorizontalAlignment(JLabel.CENTER);
bodyLabel.setFont(size30);
JTextArea bodyField = new JTextArea(30, 70);
bodyField.setLineWrap(true);
bodyField.setWrapStyleWord(true);
JScrollPane bodyScroll = new JScrollPane(bodyField);
bodyScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
// bodyScroll.setBounds(getX(), getY(), bodyField.getWidth(), bodyField.getHeight());
setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(userInfo, gbc);
gbc.gridy++;
add(msgInfo, gbc);
gbc.gridy++;
gbc.insets = new Insets(10, 10, 4, 10);
add(bodyLabel, gbc);
gbc.gridy++;
gbc.insets = new Insets(4, 10, 10, 10);
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(bodyScroll, gbc);
}
}

The problem is because of FlowLayout Manager is being used. I have solved your problem with a different layout manager.
Before posting the solution here are some tips that you should follow
Change your class name. It should be in camel-case
Try to call pack() instead of setSize() as it will handle it automatically. When I replaced your setSize() with pack(), it was showing a awkward looking GUI which proves your layout and adding elements were not proper.
Font size30 = new Font(null, Font.PLAIN, 30);
JPanel pnl = new JPanel();
pnl.setLayout(new BoxLayout(pnl,BoxLayout.Y_AXIS));
Container contentPane = getContentPane();
//--- User Info ---//
JPanel userInfo = new JPanel();
JLabel userLabel = new JLabel("Username: ");
JTextField userField = new JTextField(12);
userInfo.add(userLabel);
userInfo.add(userField);
JLabel passLabel = new JLabel("Password: ");
JTextField passField = new JTextField(10);
userInfo.add(passLabel);
userInfo.add(passField);
JLabel serverLabel = new JLabel("Mail Server: ");
JTextField serverField = new JTextField(10);
userInfo.add(serverLabel);
userInfo.add(serverField);
JLabel portLabel = new JLabel("Server Port: ");
JTextField portField = new JTextField(3);
userInfo.add(portLabel);
userInfo.add(portField);
//--- To: CC: and Subject Fields ---//
JPanel msgInfo = new JPanel();
JLabel toLabel = new JLabel("To: ");
JTextField toField = new JTextField(30);
msgInfo.add(toLabel);
msgInfo.add(toField);
JLabel subLabel = new JLabel("Subject: ");
JTextField subField = new JTextField(30);
msgInfo.add(subLabel);
msgInfo.add(subField);
//--- Body ---//
JLabel bodyLabel = new JLabel("Body");
bodyLabel.setFont(size30);
JTextArea bodyField = new JTextArea(30,70);
bodyField.setLineWrap(true);
bodyField.setWrapStyleWord(true);
JScrollPane bodyScroll = new JScrollPane(bodyField);
bodyScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
bodyScroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
pnl.add(userInfo);
pnl.add(msgInfo);
pnl.add(bodyLabel);
pnl.add(bodyScroll);
contentPane.add(pnl);
setVisible(true);
pack();

Related

I want my button not in the same row as my choose buttons in my gui? How will I do that?

How do I add a break to put my "Make pokemon" buttons and textarea not in the same row as my "Pokemon choice." I'm trying to put an empty JLabel, but I don't think it works.
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton(" Make Pokemon ");
private JButton bClear = new JButton(" Clear ");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel();
private JPanel bottomSubPanel = new JPanel();
private GUIListener listener = new GUIListener();
private Choice chSpe = new Choice();
private JLabel lEmp = new JLabel(" ");
private PokemonGUILizylf st;
private final int capacity = 10;
private PokemonGUILizylf[ ] stArr = new PokemonGUILizylf[capacity];
private int count = 0;
private String sOut = new String("");
private JTextArea textArea = new JTextArea(400, 500);
private JTextArea textArea2 = new JTextArea(400, 500);
private JScrollPane scroll = new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lEmp = new JLabel(" ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
chSpe.add("Choose");
chSpe.add("Bulbasaur");
chSpe.add("Venusaur");
chSpe.add("Ivysaur");
chSpe.add("Squirtle");
chSpe.add("Wartortle");
chSpe.add("Blastoise");
chSpe.add("Charmander");
chSpe.add("Charmeleon");
chSpe.add("Charizard");
centerSubPanel.add(lSpe);
centerSubPanel.add(chSpe);
centerSubPanel.add(lEmp);
centerSubPanel.add(bDone);
centerSubPanel.add(lNew);
textArea.setPreferredSize(new Dimension(500, 200));
textArea.setEditable(false);
textArea2.setPreferredSize(new Dimension(500, 200));
textArea2.setEditable(false);
textArea.setBackground(Color.white);
textArea.setEditable(false);
scroll.setBorder(null);
centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
bottomSubPanel.add(lMsg);
bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
This is what my GUI looks like:
enter image description here
But it should show like this:
enter image description here
Can someone explain to me how I can do that?
Use a different layout manager (other then default FlowLayout which JPanel uses)
See Laying Out Components Within a Container for more details.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new PokemonPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PokemonPanel extends JPanel {
private JLabel lTitle = new JLabel("Pokemon");
// private JLabel lMsg = new JLabel(" ");
private JButton bDone = new JButton("Make Pokemon ");
private JButton bClear = new JButton("Clear");
private JPanel topSubPanel = new JPanel();
private JPanel centerSubPanel = new JPanel(new GridBagLayout());
private JPanel bottomSubPanel = new JPanel();
// private GUIListener listener = new GUIListener();
private JComboBox<String> chSpe = new JComboBox<>();
private JLabel lEmp = new JLabel(" ");
// private PokemonGUILizylf st;
private final int capacity = 10;
// private PokemonGUILizylf[] stArr = new PokemonGUILizylf[capacity];
// private int count = 0;
// private String sOut = new String("");
// private JTextArea textArea = new JTextArea(400, 500);
// private JTextArea textArea2 = new JTextArea(400, 500);
//
// private JScrollPane scroll = new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
// JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
public PokemonPanel() {
this.setLayout(new BorderLayout());
// this.setPreferredSize(new Dimension(400, 500));
topSubPanel.setBackground(Color.cyan);
centerSubPanel.setBackground(Color.white);
bottomSubPanel.setBackground(Color.white);
topSubPanel.add(lTitle);
this.add("North", topSubPanel);
JLabel lSpe = new JLabel("Pokemon Available: ");
JLabel lNew = new JLabel("New Pokemon: ");
//add choices to the choice dropdown list
DefaultComboBoxModel<String> chSpeModel= new DefaultComboBoxModel<>();
chSpeModel.addElement("Choose");
chSpeModel.addElement("Bulbasaur");
chSpeModel.addElement("Venusaur");
chSpeModel.addElement("Ivysaur");
chSpeModel.addElement("Squirtle");
chSpeModel.addElement("Wartortle");
chSpeModel.addElement("Blastoise");
chSpeModel.addElement("Charmander");
chSpeModel.addElement("Charmeleon");
chSpeModel.addElement("Charizard");
chSpe.setModel(chSpeModel);
centerSubPanel.setBorder(new EmptyBorder(4, 4, 4, 4));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(4, 4, 4, 4);
gbc.anchor = GridBagConstraints.LINE_END;
centerSubPanel.add(lSpe, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridwidth = GridBagConstraints.REMAINDER;
centerSubPanel.add(chSpe);
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridwidth = 1;
gbc.gridx = 0;
gbc.gridy++;
centerSubPanel.add(bDone, gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.FIRST_LINE_END;
centerSubPanel.add(lNew, gbc);
gbc.gridx++;
gbc.gridheight = gbc.REMAINDER;
centerSubPanel.add(new JScrollPane(new JTextArea(10, 10)), gbc);
// textArea.setEditable(false);
// textArea2.setEditable(false);
//
// textArea.setBackground(Color.white);
// textArea.setEditable(false);
// scroll.setBorder(null);
// centerSubPanel.add(scroll); //add scrollPane to panel, textArea inside.
// scroll.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0));
add("Center", centerSubPanel);
// bottomSubPanel.add(lMsg);
// bDone.addActionListener(listener); //add listener to button
bottomSubPanel.add(bClear);
// bClear.addActionListener(listener); //add listener to button
//add bottomSubPanel sub-panel to South area of main panel
add("South", bottomSubPanel);
}
}
}
Also, avoid using setPreferredSize, let the layout managers do their job. In the example I'm used insets (from GridBagConstraints) and an EmptyBorder to add some additional space around the components
Also, be careful of using AWT components (ie Choice), they don't always play nicely with Swing. In this case, you should be using JComboBox

How to improve the margin and padding of JPanel?

When I initially run my Java Swing application, the padding and margining of the JLabel and JTextField components in a JPanel look good. But whenever I resize the application, the padding and margining for the labels and text fields increases so much that it does not look as good.
I understand a GridLayout has a set amount of vertical and horizontal spacing, but what can I do to make the spacing look better as the size of the application increases? I would also like the text in the text fields to resize as the text field increases but have been unable to figure it out.
I have been thinking to use a GridBagLayout but have not had much luck with that either. There is just way too much spacing as the size increases, which does not look good, and I have been unable to find or learn a good solution.
I would appreciate any advice.
Code:
package TestPackage;
import java.awt.GridLayout;
import javax.swing.*;
public class TestGridLayout {
public static void main(String[] args) {
JPanel testPanel = new JPanel();
GridLayout layoutManager = new GridLayout(5,2);
testPanel.setLayout(layoutManager);
JLabel platformEnumerationNameLabel = new JLabel();
JLabel logicalEnumerationNameFieldLabel = new JLabel();
JLabel valueTypeUnitNameFieldLabel = new JLabel();
JLabel measurementNameFieldLabel = new JLabel();
JLabel measurementAxisNameFieldLabel = new JLabel();
JTextField platformEnumerationNameField = new JTextField();
JTextField logicalEnumerationNameField = new JTextField();
JTextField valueTypeUnitNameField = new JTextField();
JTextField measurementNameField = new JTextField();
JTextField measurementAxisNameField = new JTextField();
platformEnumerationNameLabel.setText("Label 1");
testPanel.add(platformEnumerationNameLabel);
platformEnumerationNameField.setText("input some data");
testPanel.add(platformEnumerationNameField);
logicalEnumerationNameFieldLabel.setText("Label 2");
testPanel.add(logicalEnumerationNameFieldLabel);
logicalEnumerationNameField.setText("input some data");
testPanel.add(logicalEnumerationNameField);
valueTypeUnitNameFieldLabel.setText("Label 3");
testPanel.add(valueTypeUnitNameFieldLabel);
valueTypeUnitNameField.setText("input some data");
testPanel.add(valueTypeUnitNameField);
measurementNameFieldLabel.setText("Label 4");
testPanel.add(measurementNameFieldLabel);
measurementNameField.setText("input some data");
testPanel.add(measurementNameField);
measurementAxisNameFieldLabel.setText("Label 5");
testPanel.add(measurementAxisNameFieldLabel);
measurementAxisNameField.setText("input some data");
testPanel.add(measurementAxisNameField);
JDialog dialog = new JDialog();
dialog.add(testPanel);
dialog.setSize(700,200);
dialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
dialog.setVisible(true);
}
}
Use a different layout manager that doesn't resize all the components (unless you want them to)
See How to Use GridBagLayout for more details
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
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();
gbc.insets = new Insets(8, 8, 8, 8);
gbc.gridx = 0;
gbc.gridy = 0;
JLabel platformEnumerationNameLabel = new JLabel();
JLabel logicalEnumerationNameFieldLabel = new JLabel();
JLabel valueTypeUnitNameFieldLabel = new JLabel();
JLabel measurementNameFieldLabel = new JLabel();
JLabel measurementAxisNameFieldLabel = new JLabel();
JTextField platformEnumerationNameField = new JTextField(20);
JTextField logicalEnumerationNameField = new JTextField(20);
JTextField valueTypeUnitNameField = new JTextField(20);
JTextField measurementNameField = new JTextField(20);
JTextField measurementAxisNameField = new JTextField(20);
platformEnumerationNameLabel.setText("Label 1");
add(platformEnumerationNameLabel, gbc);
gbc.gridx++;
platformEnumerationNameField.setText("input some data");
add(platformEnumerationNameField, gbc);
gbc.gridy++;
gbc.gridx = 0;
logicalEnumerationNameFieldLabel.setText("Label 2");
add(logicalEnumerationNameFieldLabel, gbc);
gbc.gridx++;
logicalEnumerationNameField.setText("input some data");
add(logicalEnumerationNameField, gbc);
gbc.gridy++;
gbc.gridx = 0;
valueTypeUnitNameFieldLabel.setText("Label 3");
add(valueTypeUnitNameFieldLabel, gbc);
gbc.gridx++;
valueTypeUnitNameField.setText("input some data");
add(valueTypeUnitNameField, gbc);
gbc.gridy++;
gbc.gridx = 0;
measurementNameFieldLabel.setText("Label 4");
add(measurementNameFieldLabel, gbc);
gbc.gridx++;
measurementNameField.setText("input some data");
add(measurementNameField, gbc);
gbc.gridy++;
gbc.gridx = 0;
measurementAxisNameFieldLabel.setText("Label 5");
add(measurementAxisNameFieldLabel, gbc);
gbc.gridx++;
measurementAxisNameField.setText("input some data");
add(measurementAxisNameField, gbc);
}
}
}

How to use GridBagLayout to make a JLabel 1 column wide and then a JTextField 2 columns wide (for a total width 3 columns)

I've read the documentation for GridBagLayout and I can't make sense of it. I basically want to accomplish something like this:
I made some example code to help me figure this out. How can I modify this code to accomplish this?
import java.awt.*;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
JLabel label = new JLabel("label");
JTextField field = new JTextField();
JLabel label2 = new JLabel("label2");
JTextField field2 = new JTextField();
JPanel jp = new JPanel();
jp.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
//gbc.weightx = ??
jp.add(label, gbc);
gbc.gridx = 1;
gbc.gridwidth = 2;
//gbc.weightx = ??
jp.add(field, gbc);
JPanel jp2 = new JPanel();
jp2.setLayout(new GridBagLayout());
GridBagConstraints gbc2 = new GridBagConstraints();
gbc2.fill = GridBagConstraints.BOTH;
gbc2.gridx = 0;
gbc2.gridy = 0;
gbc2.gridwidth = 1;
//gbc2.weightx = ??
jp2.add(label2, gbc2);
gbc2.gridx = 1;
gbc2.gridwidth = 2;
//gbc2.weightx = ??
jp2.add(field2, gbc2);
JPanel jpContainer = new JPanel();
jpContainer.setLayout(new BoxLayout(jpContainer, BoxLayout.Y_AXIS));
jpContainer.add(jp);
jpContainer.add(jp2);
JFrame f = new JFrame();
f.setSize(300, 100);
f.setContentPane(jpContainer);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
EDIT: Changed JTextArea to JTextField
Using GridBagLayout columnWidths you can manually adjust the widths and then set the GridBagConstraints fill to GridBagConstraints.HORIZONTAL :
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import java.awt.GridBagConstraints;
import javax.swing.JTextField;
import java.awt.Insets;
public class Example extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField textField;
private JTextField textField_1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Example frame = new Example();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public Example() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] {100, 0};
gbl_contentPane.rowHeights = new int[]{0, 0, 0};
gbl_contentPane.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
gbl_contentPane.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
contentPane.setLayout(gbl_contentPane);
JLabel lblNewLabel = new JLabel("jlabel");
GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
gbc_lblNewLabel.anchor = GridBagConstraints.WEST;
gbc_lblNewLabel.gridx = 0;
gbc_lblNewLabel.gridy = 0;
contentPane.add(lblNewLabel, gbc_lblNewLabel);
textField = new JTextField();
GridBagConstraints gbc_textField = new GridBagConstraints();
gbc_textField.insets = new Insets(0, 0, 5, 0);
gbc_textField.fill = GridBagConstraints.HORIZONTAL;
gbc_textField.gridx = 1;
gbc_textField.gridy = 0;
contentPane.add(textField, gbc_textField);
textField.setColumns(10);
JLabel lblNewLabel_1 = new JLabel("jlabel2");
GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
gbc_lblNewLabel_1.anchor = GridBagConstraints.WEST;
gbc_lblNewLabel_1.insets = new Insets(0, 0, 0, 5);
gbc_lblNewLabel_1.gridx = 0;
gbc_lblNewLabel_1.gridy = 1;
contentPane.add(lblNewLabel_1, gbc_lblNewLabel_1);
textField_1 = new JTextField();
GridBagConstraints gbc_textField_1 = new GridBagConstraints();
gbc_textField_1.fill = GridBagConstraints.HORIZONTAL;
gbc_textField_1.gridx = 1;
gbc_textField_1.gridy = 1;
contentPane.add(textField_1, gbc_textField_1);
textField_1.setColumns(10);
}
}
Of course, if you want to maintain the 1/3 Label and 2/3 JTextField, you might consider using a MigLayout as such:
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import net.miginfocom.swing.MigLayout;
import javax.swing.JLabel;
import javax.swing.JTextField;
public class MigLayoutExample extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTextField textField;
private JTextField textField_1;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MigLayoutExample frame = new MigLayoutExample();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MigLayoutExample() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new MigLayout("", "[grow 33][grow 66]", "[][]"));
JLabel lblNewLabel = new JLabel("New label");
contentPane.add(lblNewLabel, "cell 0 0");
textField = new JTextField();
contentPane.add(textField, "cell 1 0,growx");
textField.setColumns(10);
JLabel lblNewLabel_1 = new JLabel("New label");
contentPane.add(lblNewLabel_1, "cell 0 1");
textField_1 = new JTextField();
contentPane.add(textField_1, "cell 1 1,growx");
textField_1.setColumns(10);
}
}
You only have two components on each row so you can only have two columns.
If you want the JTextArea to occupy more space then define the JTextArea like:
JTextArea textArea = new JTextArea(3, 30);
to control the size of the text area by specifying the row/columns of the text area.
I'm not sure why you are using a JTextArea. It seems like a JTextField would be more appropriate. You can also specify the columns when you create a JTextField. Check out the JTextField API.

GUI Layout with swing components JAVA

This is what i want to achieve
I used grid layout and this is what have
and my code goes (not full code can provide one if needed).
components.setLayout(new GridLayout(4,0));
components.setBorder(BorderFactory.createTitledBorder("Personal Data"));
//Lable to display
name.setText("Resident Name");
roomNo.setText("Room Number");
age.setText("Age");
gender.setText("Gender");
careLvl.setText("Care Level");
components.add(name);
components.add(textFieldForName);
components.add(roomNo);
components.add(textFieldForAge);
components.add(age);
components.add(coForAge);
components.add(gender);
components.add(coForGender);
components.add(careLvl);
components.add(coForCareLvl);
any heads up would be greatly appreciated.
GridLayout does just that, it layouts components out in a grid, where each cell is percentage of the available space based on the requirements (ie width / columns and height / rows).
Take a look at A Visual Guide to Layout Managers for examples of the basic layout managers and what they do.
I would recommend that you take a look at GridBagLayout instead. It is the most flexible (and most complex) layout manager available in the default libraries.
For Example
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JComboBox;
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 TestLayout31 {
public static void main(String[] args) {
new TestLayout31();
}
public TestLayout31() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JLabel lblRes = new JLabel("Resident Name");
JLabel lblRoomNo = new JLabel("RoomNo");
JLabel lblAge = new JLabel("Age");
JLabel lblGender = new JLabel("Gender");
JLabel lblCare = new JLabel("Care level");
JTextField fldRes = new JTextField("john smith", 20);
JTextField fldRoomNo = new JTextField(10);
JComboBox cmbAge = new JComboBox(new Object[]{51});
JComboBox cmbGener = new JComboBox(new Object[]{"M", "F"});
JComboBox cmbCare = new JComboBox(new Object[]{"Low"});
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(1, 1, 1, 1);
add(lblRes, gbc);
gbc.gridx++;
gbc.gridwidth = 4;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(fldRes, gbc);
gbc.gridx = 7;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
add(lblRoomNo, gbc);
gbc.gridx++;
add(fldRoomNo, gbc);
gbc.gridy++;
gbc.gridx = 1;
add(lblAge, gbc);
gbc.gridx++;
add(cmbAge, gbc);
gbc.gridx++;
add(lblGender, gbc);
gbc.gridx++;
add(cmbGener, gbc);
gbc.gridx++;
gbc.gridwidth = 2;
add(lblCare, gbc);
gbc.gridx += 2;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(cmbCare, gbc);
}
}
}
Compound Layout Example
Another option would be to use a compound layout. This is, you separate each section of your UI into separate containers, concentrating on their individual layout requirements.
For example, you have two rows of fields, each which don't really relate to each other, so rather than trying to figure out how to make the fields line up, you can focus on each row separately...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JComboBox;
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 TestLayout31 {
public static void main(String[] args) {
new TestLayout31();
}
public TestLayout31() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
JPanel topPane = new JPanel(new GridBagLayout());
JLabel lblRes = new JLabel("Resident Name");
JLabel lblRoomNo = new JLabel("RoomNo");
JLabel lblAge = new JLabel("Age");
JLabel lblGender = new JLabel("Gender");
JLabel lblCare = new JLabel("Care level");
JTextField fldRes = new JTextField("john smith", 20);
JTextField fldRoomNo = new JTextField(10);
JComboBox cmbAge = new JComboBox(new Object[]{51});
JComboBox cmbGener = new JComboBox(new Object[]{"M", "F"});
JComboBox cmbCare = new JComboBox(new Object[]{"Low"});
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
gbc.insets = new Insets(1, 1, 1, 1);
topPane.add(lblRes, gbc);
gbc.gridx++;
gbc.fill = GridBagConstraints.HORIZONTAL;
topPane.add(fldRes, gbc);
gbc.gridx++;
topPane.add(lblRoomNo, gbc);
gbc.gridx++;
topPane.add(fldRoomNo, gbc);
JPanel bottomPane = new JPanel(new GridBagLayout());
gbc.gridx = 0;
bottomPane.add(lblAge, gbc);
gbc.gridx++;
bottomPane.add(cmbAge, gbc);
gbc.gridx++;
bottomPane.add(lblGender, gbc);
gbc.gridx++;
bottomPane.add(cmbGener, gbc);
gbc.gridx++;
bottomPane.add(lblCare, gbc);
gbc.gridx++;
bottomPane.add(cmbCare, gbc);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
add(topPane, gbc);
gbc.gridy++;
add(bottomPane, gbc);
}
}
}
This will make it easier to modify the UI later should you have to...
JFrame frame = new JFrame();
JPanel contentPane = new JPanel();
JPanel northPane = new JPanel();
JPanel centerPane = new JPanel();
JPanel southPane = new JPanel();
contentPane.setLayout(new BorderLayout());
northPane.setLayout( new GridLayout(1, 6));
southPane.setLayout( new GridLayout(1, 7));
contentPane.add(northPane, BorderLayout.NORTH );
contentPane.add(centerPane, BorderLayout.CENTER);
contentPane.add(southPane, BorderLayout.SOUTH );
frame.setContentPane(contentPane);
JLabel residentNameLabel = new JLabel("Resident name ");
JTextField residentNameText = new JTextField();
JLabel roomNoLabel = new JLabel("RoomNo ");
JTextField roomNoText = new JTextField();
JLabel emptyLabel0 = new JLabel(" ");
JLabel emptyLabel1 = new JLabel(" ");
JLabel emptyLabel2 = new JLabel(" ");
JLabel emptyLabel3 = new JLabel(" ");
JLabel ageLabel = new JLabel("Age ");
JComboBox<String> ageComboBox = new JComboBox<String>();
ageComboBox.addItem("50");
ageComboBox.addItem("51");
ageComboBox.addItem("52");
ageComboBox.addItem("53");
ageComboBox.addItem("54");
ageComboBox.addItem("55");
JLabel genderLabel = new JLabel("Gender ");
JComboBox<String> genderComboBox = new JComboBox<String>();
genderComboBox.addItem("M");
genderComboBox.addItem("F");
JLabel careLevelLabel = new JLabel("Care Level ");
JComboBox<String> careLevelComboBox = new JComboBox<String>();
genderComboBox.addItem("low");;
genderComboBox.addItem("medium");
genderComboBox.addItem("high");
residentNameLabel.setHorizontalAlignment(JLabel.RIGHT);
roomNoLabel.setHorizontalAlignment(JLabel.RIGHT);
ageLabel.setHorizontalAlignment(JLabel.RIGHT);
genderLabel.setHorizontalAlignment(JLabel.RIGHT);
careLevelLabel.setHorizontalAlignment(JLabel.RIGHT);
northPane.add(emptyLabel0 );
northPane.add(residentNameLabel);
northPane.add(residentNameText );
northPane.add(roomNoLabel );
northPane.add(roomNoText );
northPane.add(emptyLabel1 );
centerPane.add(emptyLabel2 );
southPane.add(ageLabel );
southPane.add(ageComboBox );
southPane.add(genderLabel );
southPane.add(genderComboBox );
southPane.add(careLevelLabel );
southPane.add(careLevelComboBox);
southPane.add(emptyLabel3 );
contentPane.setBorder(BorderFactory.createTitledBorder("Personal Data"));
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent evt) {
System.exit(0);
}
});
frame.setVisible(true);
frame.pack();

GridBagConstraints for Java

Here is some Java Code that I have that works that uses GridBagConstraints:
public AuctionClient() {
JFrame guiFrame = new JFrame();
JPanel guiPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("UserName:");
JTextField userNameTextField = new JTextField(30);
JButton loginButton = new JButton("Login");
JButton registerButton = new JButton("Register");
JLabel passwordLabel = new JLabel("Password:");
JTextField passwordTextField = new JPasswordField(30);
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Auction Client");
guiFrame.setSize(500, 250);
guiFrame.setLocationRelativeTo(null);
GridBagConstraints labelGBC = new GridBagConstraints();
labelGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints fieldGBC = new GridBagConstraints();
fieldGBC.insets = new Insets(3, 3, 3, 3);
fieldGBC.gridwidth = GridBagConstraints.REMAINDER;
guiPanel.add(userNameLabel, labelGBC);
guiPanel.add(userNameTextField, fieldGBC);
guiPanel.add(passwordLabel, labelGBC);
guiPanel.add(passwordTextField, fieldGBC);
GridBagConstraints loginButtonGBC = new GridBagConstraints();
loginButtonGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints registerButtonGBC = new GridBagConstraints();
registerButtonGBC.insets = new Insets(3, 3, 3, 3);
registerButtonGBC.gridwidth = GridBagConstraints.REMAINDER;
guiPanel.add(loginButton, loginButtonGBC);
guiPanel.add(registerButton, registerButtonGBC);
guiFrame.add(guiPanel, BorderLayout.NORTH);
guiFrame.setVisible(true);
}
I have had a look online for some explanation of how the GridBagConstraints work in relation to placing controls on a panel. I could not understand exactly how it works so am asking a question here on this forum.
Here is a screenshot of the above code when running:
Can I please have some help to position the Login and Register buttons in the middle of the panel, side by side.
EDIT
Here is my current working code:
public AuctionClientLogon() {
JFrame guiFrame = new JFrame();
JPanel guiFieldsPanel = new JPanel(new GridBagLayout());
JPanel guiButtonsPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("UserName:");
JTextField userNameTextField = new JTextField(30);
JButton loginButton = new JButton("Login");
JButton registerButton = new JButton("Register");
JLabel passwordLabel = new JLabel("Password:");
JTextField passwordTextField = new JPasswordField(30);
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Auction Client");
guiFrame.setSize(500, 250);
guiFrame.setLocationRelativeTo(null);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
guiFieldsPanel.add(userNameLabel, gbc);
gbc.gridx++;
guiFieldsPanel.add(userNameTextField, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
guiFieldsPanel.add(passwordLabel, gbc);
gbc.gridx++;
guiFieldsPanel.add(passwordTextField, gbc);
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridx = 0;
gbc.gridy = 1;
guiButtonsPanel.add(loginButton, gbc);
gbc.gridx++;
guiButtonsPanel.add(registerButton, gbc);
guiFrame.add(guiFieldsPanel, BorderLayout.NORTH);
guiFrame.add(guiButtonsPanel, BorderLayout.CENTER);
guiFrame.setVisible(true);
}
Here is an image:
http://canning.co.nz/Java/Positioning_Image2.png
Is it possible to place the Labels and TextFields in the Center as well as the buttons, but not on top of each other? I would like everything in the Center if possible, but the buttons to be a little bit lower than the Labels and TextFields. Is this possible?
Start by taking a look at your forms requirements. You have two sections. The fields and the buttons. Each of these sections have a (slightly) different layout requirement.
Start by separating the layout to best meet these requirements.
Create a JPanel to hold the fields and a JPanel for the buttons. These panels could have different layouts if required, but the example I've included uses GridBagLayout for each.
Then layout your components accordingly (on there individual panels).
Then bring it all together...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class GridBagLayout01 {
public static void main(String[] args) {
new GridBagLayout01();
}
public GridBagLayout01() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame guiFrame = new JFrame();
JPanel guiPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("UserName:");
JTextField userNameTextField = new JTextField(30);
JButton loginButton = new JButton("Login");
JButton registerButton = new JButton("Register");
JLabel passwordLabel = new JLabel("Password:");
JTextField passwordTextField = new JPasswordField(30);
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Auction Client");
guiFrame.setSize(500, 250);
guiFrame.setLocationRelativeTo(null);
JPanel fields = new JPanel(new GridBagLayout());
GridBagConstraints labelGBC = new GridBagConstraints();
labelGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints fieldGBC = new GridBagConstraints();
fieldGBC.insets = new Insets(3, 3, 3, 3);
fieldGBC.gridwidth = GridBagConstraints.REMAINDER;
fields.add(userNameLabel, labelGBC);
fields.add(userNameTextField, fieldGBC);
fields.add(passwordLabel, labelGBC);
fields.add(passwordTextField, fieldGBC);
JPanel buttons = new JPanel(new GridBagLayout());
GridBagConstraints loginButtonGBC = new GridBagConstraints();
loginButtonGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints registerButtonGBC = new GridBagConstraints();
registerButtonGBC.insets = new Insets(3, 3, 3, 3);
registerButtonGBC.gridwidth = GridBagConstraints.REMAINDER;
buttons.add(loginButton, loginButtonGBC);
buttons.add(registerButton, registerButtonGBC);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
guiPanel.add(fields, gbc);
guiPanel.add(buttons, gbc);
guiFrame.add(guiPanel, BorderLayout.NORTH);
guiFrame.setVisible(true);
}
});
}
}
Use a FlowLayout to keep this kind of line of buttons.Then you can easily place the button position where ever you want inline.
Have a look at how to use flow layout

Categories