I've been tasked with designing a basic UI in Java using Swing but I'm stuck with laying it out. I want to create something similar to this but my attempts at using GridBagLayout have resulted in something very messy. Can anyone offer some tips on how I can lay out my GUI like this?
I have a JTabbedPane to which I add two tabs, and to each of those two tabs I add a JPanel containing my controls.
I would recommend that
the overall GUI use BorderLayout,
the JTable be in a JScrollPane and this should be placed BorderLayout.CENTER.
The top JPanel holding labels, fields, and buttons be placed BorderLayout.PAGE_START.
The top JPanel also can use BorderLayout and can hold the buttons in the BorderLayout.PAGE_END position.
The buttons would be held by a GridLayout(1, 0, x, 0) using JPanel where x is the gap between buttons
The labels and JTextFields be in a JPanel that uses GridBagLayout and that is placed in the top JPanel in the BorderLayout.CENTER position.
that you not follow these recommendations blindly but instead that you experiment with and play with different combinations of nested JPanels, each using its own layout.
that you also check out this link
Here's what I would recommend:
Use a JPanel pTextBox with GridLayout(3, 2) to hold all of your labels + textboxes
Use a JPanel pButtons with GridLayout(1, 3) or BoxLayout(horizontal) hold all of your buttons
Use a JPanel pAll with BoxLayout(vertical) to hold pTextBox, pButtons and the Table.
Use struts, glues, and min/max/prefererd sizes to adjust spacing / resizing behaviour.
Also check out: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html to compare exactly what you are looking for.
There is a component, the JTable, that wants to occupy all the available space in the window. That means that a BorderLayout will be needed, with a JScrollPane that contains the JTable in the BorderLayout.CENTER of that BorderLayout. The other components will be inside another JPanel in the BorderLayout.PAGE_START
In this new JPanel, there is no component that needs to adjust its size vertically, so i don't see the necessity of a BorderLayout. I would compose it with a vertical BoxLayout. Insert in this panel two more, one GridBagLayout for the labels and text fields, and below one FlowLayout for the buttons, with center alignment and some horizontal gap. I prefer FlowLayout insetad of GridLayout for the buttons because if you resize the main panel, with a FlowLayout the buttons will keep the same distance between them.
Here's some code...I couldn't get the JTextFields to display correctly so you'll have to fix that.
Main:
import javax.swing.SwingUtilities;
public class Main {
public static void main(String [] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Panel panel = new Panel();
}
});
}
}
Panel:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JTextField;
public class Panel extends JPanel{
private JFrame frame;
private JLabel label1;
private JLabel label2;
private JLabel label3;
private JTextField textField1;
private JTextField textField2;
private JTextField textField3;
private JButton button1;
private JButton button2;
private JButton button3;
private JTable table;
public Panel() {
label1 = new JLabel("label1");
label2 = new JLabel("label2");
label3 = new JLabel("label3");
textField1 = new JTextField("textField1", 20);
textField2 = new JTextField("textField2", 20);
textField3 = new JTextField("textField3", 100);
button1 = new JButton("Hello");
button2 = new JButton("Goodbye");
button3 = new JButton("Love");
table = new JTable(20,20);
frame = new JFrame("My application");
frame.setSize(1000, 1000);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
this.setOpaque(true);
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.weightx = 1;
gc.weighty =1;
gc.fill = GridBagConstraints.NONE;
gc.gridx = 0;
gc.gridy = 0;
// gc.anchor = GridBagConstraints.WEST;
add(label1, gc);
gc.gridx = 2;
gc.gridy = 0;
//gc.anchor = GridBagConstraints.EAST;
add(textField1, gc);
gc.gridx = 0;
gc.gridy = 1;
//gc.anchor = GridBagConstraints.WEST;
add(label2, gc);
gc.gridx = 2;
gc.gridy = 1;
//gc.anchor = GridBagConstraints.EAST;
add(textField2, gc);
gc.gridx = 0;
gc.gridy = 2;
//gc.anchor = GridBagConstraints.WEST;
add(label3, gc);
gc.gridx = 2;
gc.gridy = 2;
//gc.anchor = GridBagConstraints.EAST;
add(textField3, gc);
gc.gridx = 0;
gc.gridy = 3;
//gc.anchor = GridBagConstraints.WEST;
add(button1, gc);
gc.gridx = 1;
gc.gridy = 3;
gc.anchor = GridBagConstraints.CENTER;
add(button2, gc);
gc.gridx = 2;
gc.gridy = 3;
// gc.anchor = GridBagConstraints.EAST;
add(button3, gc);
gc.gridx = 1;
gc.gridy = 4;
gc.anchor = GridBagConstraints.CENTER;
add(table, gc);
frame.add(this);
}
}
Related
My partner and I are writing this program for a game. He used GridBagLayout for our grid and I'm trying to troubleshoot some problems with the grid.
Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
#SuppressWarnings("serial")
public class NewGame extends JFrame{
private int width = 500, height = 500, xSquares = 4, ySquares = 4;
Font buttonFont = new Font("Times New Roman", Font.PLAIN, 15);
endGame end = new endGame();
public NewGame() {
super("OnO");
// gridbaglayout is flexible but kinda complicated
GridBagLayout Griddy = new GridBagLayout();
this.setLayout(Griddy);
JPanel p = new JPanel();
p.setLayout(Griddy);
this.add(p);
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.weightx = 1;
c.weighty = 1;
c.gridwidth = 4;
c.gridheight = 4;
NewBoard board = new NewBoard(xSquares, ySquares);
// board at top left
c.gridx = 0;
c.gridy = 0;
this.add(board, c);
// find a way to make buttons smaller
JButton EndGame = new JButton("End");
EndGame.setBackground(Color.black);
EndGame.setForeground(Color.white);
EndGame.setFont(buttonFont);
EndGame.addActionListener(end);
JButton Undo = new JButton("Undo");
Undo.setBackground(Color.black);
Undo.setForeground(Color.white);
Undo.setFont(buttonFont);
JButton NewGame = new JButton("New Game");
NewGame.setBackground(Color.black);
NewGame.setForeground(Color.white);
NewGame.setFont(buttonFont);
// fit 3
c.gridwidth = 1;
c.gridheight = 1;
c.gridy = 3;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(EndGame, c);
c.gridx = 2;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(Undo, c);
c.gridx = 3;
c.fill = GridBagConstraints.HORIZONTAL;
p.add(NewGame, c);
this.setPreferredSize(new Dimension(width, height));
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
this.setLocation(450, 30);
this.setVisible(true);
}
public class endGame implements ActionListener {
public void actionPerformed(ActionEvent event) {
System.exit(0);
}
}
public class newGame implements ActionListener {
public void actionPerformed(ActionEvent event) {
}
}
}
When this code is run with the other classes in our program, the endGame, Undo, and NewGame buttons overlap with the board:
I want to find a way to display the 3 buttons either above or below the board in its individual space, but I've tinkered with the code for a long time and can't find the solution yet. I'm not sure what I should be doing here.
First of all, variable names should NOT start with an upper case character. Learn and follow Java naming conventions.
I want to find a way to display the 3 buttons either above or below the board
Simplest solution is to not use a GridBagLayout for the frame.
Just use the default BorderLayout of the frame. Then you can use a JPanel with the FlowLayout for your buttons, and a GridLayout for your board panel.
The basic logic would be:
JPanel buttons = new JPanel();
buttons.add(endGame);
buttons.add(undo);
buttons.add(newGame);
this.add(button, BorderLayout.PAGE_START);
NewBoard board = new NewBoard(xSquares, ySquares);
this.add(board, BorderLayout.CENTER);
By default a JPanel uses a FlowLayout so the buttons will be displayed on a single row.
Read the Swing tutorial on Layout Managers for more information and working examples to better understand how this suggestion works.
The element won't center vertically, and I don't know why. I've tried "center center", but it's not working.
MigLayout
private JPanel panel = new JPanel(new MigLayout("center center, filly"));
Components
panel.add(header, "span");
panel.add(input, "split 4");
panel.add(unit1);
panel.add(to);
panel.add(unit2, "wrap");
panel.add(convert, "span");
panel.add(output, "span");
I want to center the components, but not using absolute positioning (because I know how to center using this method)
TL;DR
Shame on you but
center center is not center, center
center, center, filly - filly mitigates the vertical center
To align individual components, you need align center - For example, panel.add(new JLabel("Header"), "span, align center");
Assuming you are asking how to horizontally align the components, you need to specify that per component. However, first it is best to look at what the following line of code actually does.
private JPanel panel = new JPanel(new MigLayout("center center, filly"));
Or more specifically, what the following extract means.
new MigLayout("center center, filly")
center center - This horizontally aligns the packed components on the JPanel.
Assuming you were trying to get the components centered vertically as well as horizontally, you would actually need center, center. Notice the , between the two center keywords.
filly - Well to quote the white paper, "Claims all available space in the container for the columns and/or rows".
This pretty much mitigates the effect of "center, center" and all you really need is center, filly.
Now to horizontally align components across multiple columns, you need to add the keywords align center to each component you want to do this on. For example
panel.add(new JLabel("Header"), "span, align center");
An example of this with your components would be
String[] dummyList = new String[] {
"Val 1",
"Val 2"
};
JPanel migPanel = new JPanel(new MigLayout("center, filly")); //Maybe you wanted center, center. I'm not sure
migPanel.add(new JLabel("Header"), "span, align center");
migPanel.add(new JTextField("Input"), "split 4");
migPanel.add(new JComboBox<String>(dummyList));
migPanel.add(new JLabel("To"), "span");
migPanel.add(new JComboBox<String>(dummyList), "wrap");
migPanel.add(new JButton("Convert"), "span, align center");
migPanel.add(new JTextField("Output"), "span, align center");
As MadProgrammer mentioned there are other layouts that can be used to achieve a very similar look to what you had; GridBagLayout being the easiest.
Using a mixture of GridBagConstraints you can achieve a very similar layout.
For example,
String[] dummyList = new String[] {
"Val 1",
"Val 2"
};
JPanel gridBagPanel = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.weighty = 1; //Delete this line if you are after an equivalent of `center, center` from the MigLayout
gc.gridwidth = 4;
gridBagPanel.add(new JLabel("Header"), gc);
gc.gridy = 1;
gc.gridwidth = 1;
gridBagPanel.add(new JTextField("Input"), gc);
gc.gridx = 1;
gridBagPanel.add(new JComboBox<String>(dummyList), gc);
gc.gridx = 2;
gridBagPanel.add(new JLabel("To"), gc);
gc.gridx = 3;
gridBagPanel.add(new JComboBox<String>(dummyList), gc);
gc.gridy = 2;
gc.gridx = 0;
gc.gridwidth = 4;
gridBagPanel.add(new JButton("Convert"), gc);
gc.gridy = 3;
gridBagPanel.add(new JTextField("Output"), gc);
Runnable Example - LayoutExample.java
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
#SuppressWarnings("serial")
public class LayoutExample extends JFrame {
private JTabbedPane tabs;
private JPanel migPanel;
private JPanel gridBagPanel;
private JPanel migPanelCC;
private JPanel gridBagPanelCC;
private String[] dummyList = new String[] {
"Val 1",
"Val 2"
};
private LayoutExample() {
super("Layout Example");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setUpTabs();
add(tabs);
setSize(800, 500);
setVisible(true);
}
private void setUpTabs() {
tabs = new JTabbedPane();
setUpMig();
tabs.add(migPanel, "Mig Panel");
setUpMigCC();
tabs.add(migPanelCC, "Mig Panel Center Center");
setUpGridBag();
tabs.add(gridBagPanel, "Grid Bag Panel");
setUpGridBagCC();
tabs.add(gridBagPanelCC, "Grid Bag Panel Center Center");
}
private void setUpMig() {
migPanel = new JPanel(new MigLayout("center, filly"));
addToMigPanel(migPanel);
}
private void setUpMigCC() {
migPanelCC = new JPanel(new MigLayout("center, center"));
addToMigPanel(migPanelCC);
}
private void addToMigPanel(JPanel mPanel) {
mPanel.add(new JLabel("Header"), "span, align center");
mPanel.add(new JTextField("Input"), "split 4");
mPanel.add(new JComboBox<String>(dummyList));
mPanel.add(new JLabel("To"), "span");
mPanel.add(new JComboBox<String>(dummyList), "wrap");
mPanel.add(new JButton("Convert"), "span, align center");
mPanel.add(new JTextField("Output"), "span, align center");
}
private void setUpGridBag() {
gridBagPanel = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.weighty = 1;
addToGridBagPanel(gridBagPanel, gc);
}
private void setUpGridBagCC() {
gridBagPanelCC = new JPanel(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
addToGridBagPanel(gridBagPanelCC, gc);
}
private void addToGridBagPanel(JPanel gblPanel, GridBagConstraints gc) {
gc.gridwidth = 4;
gblPanel.add(new JLabel("Header"), gc);
gc.gridy = 1;
gc.gridwidth = 1;
gblPanel.add(new JTextField("Input"), gc);
gc.gridx = 1;
gblPanel.add(new JComboBox<String>(dummyList), gc);
gc.gridx = 2;
gblPanel.add(new JLabel("To"), gc);
gc.gridx = 3;
gblPanel.add(new JComboBox<String>(dummyList), gc);
gc.gridy = 2;
gc.gridx = 0;
gc.gridwidth = 4;
gblPanel.add(new JButton("Convert"), gc);
gc.gridy = 3;
gblPanel.add(new JTextField("Output"), gc);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new LayoutExample());
}
}
Finally, it is a bad idea to use absolute positioning. This is because when the container changes size, the components within the container will not automatically adjust. This will not work well for most things as you could lose important UI components pretty fast or you could have loads of extra white space.
The IDE I use is Intellij.
Here I created a small program of converting currency.
I used BorderLayout as the root panel and flowLayout for the bottom buttons. For west and east panel I used GridLayout(Intellij).
When I run the program, it can display normally like this:
After changing its size, the gap between elements begin to expand like this:
How do I make them adjust the distance automatically?
Here are my codes:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Created by Bob on 2017/5/11.
*/
public class layout {
private JPanel converterRootPanel;
private JPanel westPanel;
private JLabel selectNationPanel;
private JLabel currencyToConvett;
private JLabel currencyConverted;
private JComboBox currencyType;
private JTextField input;
private JTextField output;
private JPanel eastPanel;
private JPanel southPanel;
private JButton convertButton;
private JButton clearButton;
private JLabel convertToLabel;
private JComboBox convertType;
private JPanel northPanel;
public int selection1;
public int selection2;
public Double toConvert;
public double[][] rate1={{0,0.1335,0.1449,16.5172,163.4922},{7.4927,0,1.0857,123.7900,
1225.0380},{6.9029,0.9382,0,114.01,1129.19},{0.06053,0.00808,0.008771,0,9.9043},{0.006112,
0.0008158,0.0008856,0.101,0}};
public layout() {
currencyType.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
selection1 = currencyType.getSelectedIndex();
}
});
convertType.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
selection2 = convertType.getSelectedIndex();
}
});
convertButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(selection1==selection2){
JOptionPane.showConfirmDialog(null, "You have to choose different currency types!", "Error Alert", JOptionPane.CANCEL_OPTION);
}
output.setText("");
toConvert = Double.parseDouble(input.getText().toString());
Double convertResult = toConvert*rate1[selection1][selection2];
output.setText(convertResult.toString());
}
});
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
output.setText("");
input.setText("");
convertType.setSelectedIndex(0);
currencyType.setSelectedIndex(0);
}
});
}
public static void main(String[] args) {
JFrame frame = new JFrame("layout");
frame.setContentPane(new layout().converterRootPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
//layout lay = new layout();
}
private void createUIComponents() {
// TODO: place custom component creation code here
}
}
What you want to do is done through a layout manager. There are several of these for Java that are part of the standard library and there are also other custom ones such as MigLayout.
The Java tutorials have a whole section on layout managers here
A basic example of the GridBagLayout would be the following.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Basic {
JFrame frame;
JPanel panel;
JLabel label;
JButton button;
public void createAndRun() {
frame = new JFrame("Basic Example");
setUp();
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void setUp() {
panel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
label = new JLabel("I am a JLabel");
c.gridx = 0;
c.gridy = 0;
c.fill = GridBagConstraints.BOTH;
c.weightx = 0.5;
c.weighty = 0;
panel.add(label, c);
button = new JButton("I am a JButton");
c.gridx = 0;
c.gridy = 1;
c.weighty = 0.5;
panel.add(button, c);
}
public static void main(String[] args) {
Basic b = new Basic();
b.createAndRun();
}
}
However, as the tutorials put it.
"GridBagLayout is one of the most flexible — and complex — layout managers the Java platform provides."
So if you are having problems with GridBagLayout it may be worth looking at other layout managers beforehand.
Finally, I would like to suggest some ways that you might look at improving your code.
The part that caught my eye the most was this line.
frame.setContentPane(new layout().converterRootPanel);
I would recommend not creating the JFrame and initialising you Layout class in the main method. Instead, it would be worth initialising the class first and then calling a method to create the frame.
Layout l = new Layout();
l.createFrame();
This is shown in the example code above.
A GridBagLayout uses the weightx and weighty properties of GridBagConstraints to determine how extra space is distributed. GridBagLayout uses the largest weightx of all cells in a column to determine the column’s actual horizontal weight for all cells in that column, and similarly, the largest weighty of all cells in a row determines that row’s vertical weight. If all columns have a zero weightx, they are all centered horizontally. If all rows have a zero weighty, they are all centered vertically.
Usually a good design is to have the input fields stretch horizontally, while the labels remain the same size at all times. You probably want the rows to have same vertical spacing at all times, and have all extra space appear above or below the entire set of rows.
To make all cells of a particular column stretch, you only need to set the weightx of one cell in that column:
JPanel buttonPanel = new JPanel();
buttonPanel.add(convertButton);
buttonPanel.add(clearButton);
converterRootPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_END;
// First row
converterRootPanel.add(selectNationPanel, gbc);
gbc.weightx = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
converterRootPanel.add(currencyType, gbc);
gbc.weightx = 0;
gbc.insets.top = 3;
// Second row
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
converterRootPanel.add(convertToLabel, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
converterRootPanel.add(convertType, gbc);
// Third row
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
converterRootPanel.add(currencyToConvett, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
converterRootPanel.add(input, gbc);
// Fourth row
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
converterRootPanel.add(currencyConverted, gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
converterRootPanel.add(output, gbc);
// Button row
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.CENTER;
converterRootPanel.add(buttonPanel, gbc);
I'm working on a small GUI project that builds a book manger to mange a book. In my layout, I want a textArea to display information about my book, a text JLabel underneath my textArea and a JTextArea for me to input information same column of JLabel and 1 row next to Label. However when I run my program, textArea and Label is completely cover over my textArea.
How can I fix this problem. Thanks!!
import java.awt.*;
import javax.swing.*;
public class Design extends JFrame {
JButton button1;
JTextArea outputArea;
JLabel stockLabel, bookPriceLabel;
JTextField stockTextField, priceTextField;
JPanel panel;
GridBagConstraints gc;
public Design(){
super("Book Info");
gc = new GridBagConstraints ();
panel = new JPanel();
outputArea = new JTextArea(20, 50);
stockLabel = new JLabel ("Books In Stock");
bookPriceLabel = new JLabel("Book Price");
stockTextField = new JTextField(10);
button1 = new JButton ("button1");
panel.setLayout(new GridBagLayout());
panel.setSize(600, 600);
gc.anchor = GridBagConstraints.NORTHWEST;
gc.weightx = 1;
gc.weighty = 1;
panel.add(outputArea, gc);
gc.gridx = 2;
gc.gridy = 2;
panel.add(stockLabel, gc);
gc.gridx = 3;
gc.gridy = 2;
panel.add(stockTextField, gc);
this.getContentPane().add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600,600);
setVisible(true);
setLocationRelativeTo(null);
}
public static void main (String args[]){
Design frame = new Design();
}
}
You could apply a gridWidth constraint to the JTextArea which would allow it to span multiple columns.
Remember, GridBagLayout is still based around the concept of a grid (rows and columns), but which provides a lot of flexibility to customise how components fill and span through out that grid
Maybe something like...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
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;
public class Design extends JFrame {
JButton button1;
JTextArea outputArea;
JLabel stockLabel, bookPriceLabel;
JTextField stockTextField, priceTextField;
JPanel panel;
GridBagConstraints gc;
public Design() {
super("Book Info");
gc = new GridBagConstraints();
panel = new JPanel();
outputArea = new JTextArea(20, 50);
stockLabel = new JLabel("Books In Stock");
bookPriceLabel = new JLabel("Book Price");
stockTextField = new JTextField(10);
button1 = new JButton("button1");
panel.setLayout(new GridBagLayout());
gc.anchor = GridBagConstraints.NORTHWEST;
gc.gridx = 0;
gc.gridy = 0;
gc.weightx = 1;
gc.weighty = 1;
gc.gridwidth = GridBagConstraints.REMAINDER;
panel.add(new JScrollPane(outputArea), gc);
gc.weightx = 0;
gc.weighty = 0;
gc.anchor = GridBagConstraints.WEST;
gc.gridwidth = 1;
gc.gridx = 0;
gc.gridy = 2;
panel.add(stockLabel, gc);
gc.gridx++;
gc.gridy = 2;
panel.add(stockTextField, gc);
this.getContentPane().add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
setLocationRelativeTo(null);
}
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) {
ex.printStackTrace();
}
Design frame = new Design();
}
});
}
}
See How to Use GridBagLayout for more details
Some general feedback:
There's no point in calling setSize on a component which will be added to a container which using a layout manager, the action will simply be ignored and the layout manager will call setSize with what it wants to use
JTextArea really should be contained within a JScrollPane, you'll get some weird results if you don't (it will want to grow as the text occupies more space)
Prefer JFrame#pack over JFrame#setSize, this will take into account the frame borders, wrapping the frame around the contents
You really should avoid extending directly from top level containers like JFrame, apart from locking you into a single use case, you're really not adding any new functionality to the frame. Instead, start with something like a JPanel, build you core UI ontop of that and then, when you need to, add that to what ever container you want
I have 3 JPanels and I want to place them all in one JPanel. I used the GridBagLayout for the main panel. But only one panel is getting added. Why might this be?
gblayout=new GridBagLayout();
gbc=new GridBagConstraints();
panel1Customizer();
panel2customizer();
panel3Customizer();
setLayout(gblayout);
gbc.fill=GridBagConstraints.HORIZONTAL;
gbc.anchor=GridBagConstraints.NORTHWEST;
gbc.weightx=1;
gbc.weighty=1;
gbc.gridheight=GridBagConstraints.REMAINDER;
add(panel1, gbc);
add(panel2, gbc);
gbc.gridwidth=GridBagConstraints.REMAINDER;
add(panel3, gbc);
The customizer methods are ones which add items into these panels.
I am not sure but I think you need to add a GridBagConstraints to your GridBagLayout. Try look at this site to get the idea on how to work with GridBagLayout:
link
Or maybe just use another Layout for your JFrame, maybe BorderLayout or GridLayout to arrange your Panels correctly
You should change gbc.gridx and/or gbc.gridy to be different for each panel
you have to read How to Use GridBagLayout, examples for that here and GridBagConstraints, change your gbc.fill=GridBagConstraints.HORIZONTAL;, if you have problem(s) with JComponent's Size then add setPreferedSize(); for example
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.*;
public class GBLFillBoth extends JFrame {
private static final long serialVersionUID = 1L;
public GBLFillBoth() {
JPanel panel = new JPanel();
GridBagLayout gbag = new GridBagLayout();
panel.setLayout(gbag);
GridBagConstraints c = new GridBagConstraints();
JButton btn1 = new JButton("One");
c.fill = GridBagConstraints.BOTH;
//c.fill = GridBagConstraints.HORIZONTAL;
c.anchor=GridBagConstraints.NORTHWEST;
c.gridx = 0;
c.gridy = 0;
c.weightx = 0.5;
c.weighty = 0.5;
panel.add(btn1, c);
JButton btn2 = new JButton("Two");
c.gridx++;
panel.add(btn2, c);
//c.fill = GridBagConstraints.BOTH;
JButton btn3 = new JButton("Three");
c.gridx = 0;
c.gridy++;
c.gridwidth = 2;
panel.add(btn3, c);
add(panel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
GBLFillBoth gBLFillBoth = new GBLFillBoth();
}
}
You might consider using a MigLayout instead, the code is much simpler:
panel1Customizer();
panel2customizer();
panel3Customizer();
setLayout(new MigLayout("fill, wrap 3"));
add(panel1, "grow");
add(panel2, "grow");
add(panel3, "grow");