javaswinguser-interfacelayout-managerboxlayout

This GUI is displaying nothing after setting BoxLayout


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GUI_Borrower extends JFrame implements ActionListener {

    JPanel panel = new JPanel();

    JLabel lblName = new JLabel("Name:");
    JLabel lblProg = new JLabel("Program:");
    JLabel lblId = new JLabel("Library ID: ");
    JLabel lblTitle = new JLabel("Add Borrower");
    JTextField txtName = new JTextField(10);
    JTextField txtProg = new JTextField(10);
    JTextField txtId = new JTextField(10);
    static int counter = 19000;
    JButton btnSubmit = new JButton("Submit");

    public GUI_Borrower() {
        super("Add Borrower");
        makeFrame();
        showFrame();
    }

    public void makeFrame() {
        lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
        lblTitle.setForeground(Color.BLUE);
        add(lblTitle);
        add(lblName);
        add(txtName);
        add(lblProg);
        add(txtProg);
        add(lblId);
        add(txtId);

        panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
        panel.add(btnSubmit);
        btnSubmit.addActionListener(this);
    }

    public void showFrame() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 200);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public void actionPerformed(ActionEvent ae) {
        Object source = ae.getSource();

        if (ae.getActionCommand().equals("Confirm")) {
            txtName.setText("");
            txtProg.setText("");
            btnSubmit.setText("Submit");
        } else if (source == btnSubmit) {
            if (txtName.getText().equals("") && txtProg.getText().equals("")) {
                txtId.setText("No entry of both");
            } else if (txtName.getText().equals("")) {
                txtId.setText("No entry of Name");
            } else if (txtProg.getText().equals("")) {
                txtId.setText("No entry of Program");
            } else {
                counter++;
                txtId.setText("" + counter);

                btnSubmit.setText("Confirm");
            }
        }
    }

    public static void main(String[] args) {
        new GUI_Borrower();
    }
}

I tried adding BoxLayout because all the text fields and labels are on one line. So I tried box Layout and failed.

Can anyone show me how to make it like the title one line, label Different line, button different line?

Like this:

enter image description here


Solution

  • As camickr says in his comment, you generally use a GridBagLayout to create a form.

    I reworked your code because I hope to show a better way to code a GUI panel.

    Here's the GUI.

    Add Borrower GUI

    The major changes I made include:

    1. All Swing applications must start with a call to the SwingUtilities invokeLater method. This method ensures that all Swing components are created and executed on the Event Dispatch Thread.

    2. I organized the GUI code into three methods so I could focus on one part of the GUI at a time. The JFrame is created in the run method. The title JPanel is created in the createTitlePanel method. The form JPanel is created in the createFormPanel method. The code for the JFrame will rarely change from Swing application to Swing application.

    3. I use Swing components. I don't extend Swing components, or any Java class, unless I intend to override one of the class methods.

    4. The createFormPanel class uses the GridBagLayout to organize the labels and text fields in columns. You can think of the GridBagLayout as a flexible grid. The cells of the grid don't have to be the same size. The Oracle tutorial, How to Use GridBagLayout, has another example.

    5. I put the ActionListener in a separate class. I made it an inner class in this example so I could paste the code as one file. Generally, you should put separate classes in separate files. It makes each class shorter and easier to understand.

    Here's the runnable, example code.

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.BorderFactory;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    import javax.swing.SwingUtilities;
    
    public class BorrowerGUI implements Runnable {
    
        private static int ID_COUNTER = 19000;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new BorrowerGUI());
        }
    
        private JButton btnSubmit;
    
        private JTextField txtName;
        private JTextField txtProg;
        private JTextField txtId;
    
        @Override
        public void run() {
            JFrame frame = new JFrame("Add Borrower");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            frame.add(createTitlePanel(), BorderLayout.BEFORE_FIRST_LINE);
            frame.add(createFormPanel(), BorderLayout.CENTER);
    
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    
        private JPanel createTitlePanel() {
            JPanel panel = new JPanel(new FlowLayout());
    
            JLabel lblTitle = new JLabel("Add Borrower");
            lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
            lblTitle.setForeground(Color.BLUE);
            panel.add(lblTitle);
    
            return panel;
        }
    
        private JPanel createFormPanel() {
            JPanel panel = new JPanel(new GridBagLayout());
            panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.LINE_START;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            gbc.insets = new Insets(5, 5, 5, 5);
            gbc.gridx = 0;
            gbc.gridy = 0;
    
            JLabel lblName = new JLabel("Name:");
            panel.add(lblName, gbc);
    
            gbc.gridx++;
            txtName = new JTextField(20);
            panel.add(txtName, gbc);
    
            gbc.gridx = 0;
            gbc.gridy++;
            JLabel lblProg = new JLabel("Program:");
            panel.add(lblProg, gbc);
    
            gbc.gridx++;
            txtProg = new JTextField(20);
            panel.add(txtProg, gbc);
    
            gbc.gridx = 0;
            gbc.gridy++;
            JLabel lblId = new JLabel("Library ID:");
            panel.add(lblId, gbc);
    
            gbc.gridx++;
            txtId = new JTextField(20);
            txtId.setEditable(false);
            panel.add(txtId, gbc);
    
            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = 2;
            btnSubmit = new JButton("Submit");
            btnSubmit.addActionListener(new SubmitListener());
            panel.add(btnSubmit, gbc);
    
            return panel;
        }
    
        public class SubmitListener implements ActionListener {
    
            @Override
            public void actionPerformed(ActionEvent ae) {
                Object source = ae.getSource();
    
                if (ae.getActionCommand().equals("Confirm")) {
                    txtName.setText("");
                    txtName.requestFocus();
                    txtProg.setText("");
                    txtId.setText("");
                    btnSubmit.setText("Submit");
                } else if (source == btnSubmit) {
                    if (txtName.getText().equals("") &&
                            txtProg.getText().equals("")) {
                        txtId.setText("No entry of both");
                    } else if (txtName.getText().equals("")) {
                        txtId.setText("No entry of Name");
                    } else if (txtProg.getText().equals("")) {
                        txtId.setText("No entry of Program");
                    } else {
                        ID_COUNTER++;
                        txtId.setText("" + ID_COUNTER);
                        btnSubmit.setText("Confirm");
                    }
                }
    
            }
        }
    }
    

    Edited to add: If you want the title JLabel to be right-justified, you'll have to switch to a BorderLayout. I added an empty border so the text wouldn't be on the right edge of the JFrame.

    Here's the changed method.

    private JPanel createTitlePanel(String title) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
    
        JLabel lblTitle = new JLabel(title);
        lblTitle.setFont(new Font("Forte", Font.PLAIN, 40));
        lblTitle.setForeground(Color.BLUE);
        panel.add(lblTitle, BorderLayout.AFTER_LINE_ENDS);
    
        return panel;
    }