VisualStudioTutor.com Java Tutorial All Lessons

Lesson 22 of 25

Java Swing GUI Development

Build desktop interfaces with windows, labels, text fields, buttons, layouts, tables, and event handlers.

Learning objectives

  • Explain the role of JFrame, JPanel, and Swing components.
  • Arrange components with layout managers.
  • Respond to button clicks using action listeners.
  • Read values from text fields and display validation messages.
  • Populate a JTable with tabular data.
  • Build a small student-entry desktop application.

1. How Swing applications are structured

Swing is Java's traditional desktop GUI toolkit. A typical application uses a JFrame as the main window, one or more JPanel containers, and controls such as JLabel, JTextField, JButton, and JTable.

Example: first Swing window

import javax.swing.*;

public class FirstWindow {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("My First Swing App");

            frame.setDefaultCloseOperation(
                JFrame.EXIT_ON_CLOSE
            );

            frame.setSize(420, 200);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

SwingUtilities.invokeLater starts the interface on Swing's Event Dispatch Thread (EDT), which is the correct thread for creating and updating Swing components.

2. Adding components with a layout manager

A layout manager controls component positioning. BorderLayout, FlowLayout, and GridLayout are useful beginner layouts.

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

public class StudentForm {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Student Form");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            JPanel form = new JPanel(new GridLayout(3, 2, 8, 8));

            JTextField txtName = new JTextField();
            JTextField txtMark = new JTextField();
            JButton btnCheck = new JButton("Check Result");

            form.add(new JLabel("Student Name:"));
            form.add(txtName);
            form.add(new JLabel("Mark:"));
            form.add(txtMark);
            form.add(new JLabel());
            form.add(btnCheck);

            frame.add(form);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

3. Handling button clicks

Swing is event-driven. The program waits for an event—such as a button click—and then invokes the registered listener.

Example: validate and calculate

btnCheck.addActionListener(event -> {
    String name = txtName.getText().trim();

    try {
        int mark = Integer.parseInt(
            txtMark.getText().trim()
        );

        if (name.isBlank()) {
            JOptionPane.showMessageDialog(
                frame,
                "Please enter the student's name."
            );
            return;
        }

        if (mark < 0 || mark > 100) {
            JOptionPane.showMessageDialog(
                frame,
                "Mark must be from 0 to 100."
            );
            return;
        }

        String result = mark >= 50 ? "Pass" : "Fail";

        JOptionPane.showMessageDialog(
            frame,
            name + " - " + result
        );

    } catch (NumberFormatException ex) {
        JOptionPane.showMessageDialog(
            frame,
            "Mark must be a whole number."
        );
    }
});

4. Displaying tabular data with JTable

JTable displays rows and columns. For dynamic data, DefaultTableModel is convenient for beginner applications.

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

String[] columns = {"Student ID", "Name", "Mark"};

DefaultTableModel model =
    new DefaultTableModel(columns, 0);

model.addRow(new Object[]{"S001", "Amina", 82});
model.addRow(new Object[]{"S002", "Daniel", 74});

JTable table = new JTable(model);
JScrollPane scrollPane = new JScrollPane(table);

Mini project: Student Result GUI

The following example combines fields, validation, a button event, and a table.

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;

public class StudentResultApp extends JFrame {

    private final JTextField txtId = new JTextField();
    private final JTextField txtName = new JTextField();
    private final JTextField txtMark = new JTextField();

    private final DefaultTableModel model =
        new DefaultTableModel(
            new String[]{"ID", "Name", "Mark", "Result"},
            0
        );

    public StudentResultApp() {
        setTitle("Student Result App");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        JPanel form = new JPanel(new GridLayout(4, 2, 8, 8));

        form.add(new JLabel("Student ID:"));
        form.add(txtId);

        form.add(new JLabel("Name:"));
        form.add(txtName);

        form.add(new JLabel("Mark:"));
        form.add(txtMark);

        JButton btnAdd = new JButton("Add Student");
        form.add(new JLabel());
        form.add(btnAdd);

        JTable table = new JTable(model);

        btnAdd.addActionListener(event -> addStudent());

        add(form, BorderLayout.NORTH);
        add(new JScrollPane(table), BorderLayout.CENTER);

        setSize(600, 350);
        setLocationRelativeTo(null);
    }

    private void addStudent() {
        String id = txtId.getText().trim();
        String name = txtName.getText().trim();

        try {
            int mark = Integer.parseInt(
                txtMark.getText().trim()
            );

            if (id.isBlank() || name.isBlank()) {
                throw new IllegalArgumentException(
                    "ID and name are required."
                );
            }

            if (mark < 0 || mark > 100) {
                throw new IllegalArgumentException(
                    "Mark must be from 0 to 100."
                );
            }

            String result = mark >= 50 ? "Pass" : "Fail";

            model.addRow(
                new Object[]{id, name, mark, result}
            );

            txtId.setText("");
            txtName.setText("");
            txtMark.setText("");

        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(
                this,
                "Mark must be a whole number."
            );
        } catch (IllegalArgumentException ex) {
            JOptionPane.showMessageDialog(
                this,
                ex.getMessage()
            );
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new StudentResultApp().setVisible(true);
        });
    }
}

Common mistakes

ProblemWhy it happensFix
GUI freezes during a long taskLong work is running on the Event Dispatch Thread.Move long-running work to a background worker such as SwingWorker.
Components overlap or resize badlyAbsolute positioning or an unsuitable layout was used.Use layout managers instead of hard-coded coordinates.
Input crashes the event handlerText is converted without validation.Validate fields and catch NumberFormatException.

Summary

You can now construct a Swing interface, react to user events, validate input, and display data in a table. Lesson 23 connects Java to SQLite through JDBC so application data can persist after the program closes.