1. DO NOT use absolute positioning (null layout), it's harder to maintain, and can easily looked fucked up on different systems with different configurations.
2. DO NOT use GUI designers/builders, they produce bad code which is hard to maintain, and often is not the best way to build the GUI. You also cannot achieve more advanced things if you're using a builder. Another good reason to do it "by hand", is so that you actually know what you are doing, you will learn nothing from a GUI builder.
3. Look at https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html, by combining these layout managers in nested JPanels you can easily achieve your desired GUI
Here is an example using the GridBagLayout: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#gridbag
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import static java.awt.GridBagConstraints.HORIZONTAL;
import static java.awt.GridBagConstraints.NONE;
public class GUI {
private final JFrame jFrame;
public GUI() {
jFrame = new JFrame("Pigeon GUI");
JPanel mainPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
jFrame.setContentPane(mainPanel);
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
JLabel titleLabel = new JLabel("Pigeon GUI");
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 4;
gbc.insets = new Insets(0, 10, 20, 10);
mainPanel.add(titleLabel, gbc);
JLabel nameLabel = new JLabel("Name:");
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.insets = new Insets(0, 0, 0, 5);
mainPanel.add(nameLabel, gbc);
JTextField nameField = new JTextField(20);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.insets = new Insets(0, 0, 0, 0);
mainPanel.add(nameField, gbc);
JScrollPane whitelistScrollPane = new JScrollPane();
JList<String> whitelist = new JList<>();
whitelistScrollPane.add(whitelist);
gbc.gridx = 2;
gbc.gridy = 1;
gbc.ipadx = 200;
gbc.ipady = 200;
gbc.gridwidth = 2;
gbc.insets = new Insets(10, 10, 0, 10);
mainPanel.add(whitelistScrollPane, gbc);
JButton insertButton = new JButton("Insert");
gbc.gridx = 2;
gbc.gridy = 2;
gbc.fill = HORIZONTAL;
gbc.weightx = 0.5;
gbc.gridwidth = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.insets = new Insets(10, 10, 0, 10);
mainPanel.add(insertButton, gbc);
JButton deleteButton = new JButton("Delete");
gbc.gridx = 3;
gbc.gridy = 2;
gbc.fill = HORIZONTAL;
gbc.weightx = 0.5;
gbc.gridwidth = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.insets = new Insets(10, 10, 0, 10);
mainPanel.add(deleteButton, gbc);
JButton startButton = new JButton("Start");
gbc.gridwidth = 4;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.fill = NONE;
gbc.insets = new Insets(20, 10, 0, 10);
mainPanel.add(startButton, gbc);
jFrame.pack(); // resize the JFrame so that all the components are at or above their preferred sizes
jFrame.setLocationRelativeTo(null); // center the gui on screen
}
public void open() {
jFrame.setVisible(true);
}
public void close() {
jFrame.setVisible(false);
jFrame.dispose();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new GUI().open());
}
}
Here is another example purely using nested JPanels with BorderLayout and FlowLayouts.
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
public class GUI {
private final JFrame jFrame;
public GUI() {
jFrame = new JFrame("Pigeon GUI");
// We want to split the GUI into three sections, title at the top, inputs in the middle, start button at the bottom
// To do this we use a BorderLayout: https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#border
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.setPreferredSize(new Dimension(500, 400));
jFrame.setContentPane(mainPanel); // use this panel as the main content panel for the GUI
// Create a JPanel to contain the title. Here we use a FlowLayout https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#flow
// We set the alignment to FlowLayout.CENTER so the title appears in the middle.
JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
titlePanel.setBorder(new EmptyBorder(5, 5, 5, 5)); // We give the JPanel an empty border of 5px, so that there is some padding
JLabel titleLabel = new JLabel("Pigeon GUI");
titlePanel.add(titleLabel);
mainPanel.add(titlePanel, BorderLayout.NORTH); // Add the title to the North side of the main panel
// Create a JPanel to contain the main GUI inputs (textfield and whitelist)
JPanel inputsPanel = new JPanel(new BorderLayout());
// Create a JPanel to contain the name label and name input
JPanel namePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
namePanel.setBorder(new EmptyBorder(10, 10, 10, 10));
JLabel nameLabel = new JLabel("Name:");
namePanel.add(nameLabel);
JTextField nameField = new JTextField(20);
namePanel.add(nameField);
inputsPanel.add(namePanel, BorderLayout.WEST);
// Create a JPanel to contain the whitelist and buttons
JPanel whitelistPanel = new JPanel(new BorderLayout());
whitelistPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
inputsPanel.add(whitelistPanel, BorderLayout.EAST);
// Create a JScrollPane to contain the whitelist
// Add the JScrollPane to the whitelistpanel above
JScrollPane whitelistScrollPane = new JScrollPane();
JList<String> whitelist = new JList<>();
whitelistScrollPane.add(whitelist);
whitelistPanel.add(whitelistScrollPane, BorderLayout.CENTER);
// Create a JPanel to contain the whitelist buttons
JPanel whitelistButtons = new JPanel(new FlowLayout(FlowLayout.CENTER));
JButton insertButton = new JButton("Insert");
whitelistButtons.add(insertButton);
JButton deleteButton = new JButton("Delete");
whitelistButtons.add(deleteButton);
whitelistPanel.add(whitelistButtons, BorderLayout.SOUTH);
mainPanel.add(inputsPanel, BorderLayout.CENTER); // Add the inputs panel to the centre of the main panel
// Crete a JPanel to contain the start button
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
buttonPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
JButton startButton = new JButton("Start");
buttonPanel.add(startButton);
mainPanel.add(buttonPanel, BorderLayout.SOUTH); // Add the button panel to the south of the main panel
jFrame.pack(); // resize the JFrame so that all the components are at or above their preferred sizes
jFrame.setResizable(false);
jFrame.setLocationRelativeTo(null); // center the gui on screen
}
public void open() {
jFrame.setVisible(true);
}
public void close() {
jFrame.setVisible(false);
jFrame.dispose();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new GUI().open());
}
}