Java - Week 12

Graphical User Interfaces: A Bird's Eye View of Java Swing

Introduction to Java Swing

Up until now, all of our Java programs have interacted with the user through the console (printing text and reading keyboard input). While powerful, modern applications rely on Graphical User Interfaces (GUIs) featuring windows, buttons, text fields, and images.

Java Swing is a built-in toolkit that allows you to create rich, interactive GUI applications. It sits on top of an older toolkit called AWT (Abstract Window Toolkit) but provides more modern, flexible, and "lightweight" components that look consistent across different operating systems.

The javax.swing Package

To use Swing, you will heavily import classes from the javax.swing package. A convention in Swing is that almost all component class names start with the letter 'J' (e.g., JButton, JLabel, JFrame).


Creating a Window (JFrame)

The foundation of any Swing application is the window itself. In Swing, the primary window is represented by the JFrame class. A JFrame provides the title bar, minimize/maximize/close buttons, and a blank canvas to hold other components.

Your First GUI Program

Let's look at the absolute minimum code required to display a window on the screen.

Java
import javax.swing.JFrame;

public class MyFirstWindow {
    public static void main(String[] args) {
        // 1. Create the frame and set the title
        JFrame frame = new JFrame("Hello Swing!");

        // 2. Set the dimensions of the window (width, height in pixels)
        frame.setSize(400, 300);

        // 3. Define what happens when the user clicks the 'X' button.
        // Without this, the window closes but the program keeps running in the background!
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 4. Center the window on the screen (optional but nice)
        frame.setLocationRelativeTo(null); 

        // 5. Make the window visible. (Always do this last!)
        frame.setVisible(true); 
    }
}

Adding Basic Components

An empty window isn't very useful. We need to add "Controls" or "Components" to it. Here are three of the most common components you will use:

  • JLabel: Used to display text or an image. The user cannot edit it.
  • JTextField: A single-line input box where the user can type text.
  • JButton: A clickable button.

Using a JPanel

While you can add components directly to a JFrame, it is best practice to group them inside a JPanel. Think of a JPanel as an invisible container or grouping board. You put your buttons and text fields onto the panel, and then you put the panel into the frame.

Java
import javax.swing.*;

public class ComponentExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Login Screen");
        frame.setSize(300, 150);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Create a Panel to hold our components
        JPanel panel = new JPanel();

        // Create the components
        JLabel userLabel = new JLabel("Username:");
        JTextField userText = new JTextField(15); // 15 columns wide
        JButton loginButton = new JButton("Login");

        // Add components to the panel
        panel.add(userLabel);
        panel.add(userText);
        panel.add(loginButton);

        // Add the panel to the frame
        frame.add(panel);

        frame.setVisible(true);
    }
}

Layout Managers

If you run the previous example, you might notice the components just flow next to each other. What if you want the button at the bottom, or in a grid?

In Java Swing, you generally don't set exact X and Y coordinates for buttons (though you can). Instead, you use Layout Managers. These are algorithms that automatically arrange your components, handling window resizing gracefully.

Common Layout Managers

  1. FlowLayout: The default for JPanels. It places components in a row, left to right. If it runs out of space, it wraps to the next line.
  2. BorderLayout: The default for JFrames. It divides the screen into five regions: North, South, East, West, and Center.
  3. GridLayout: Arranges components in a grid of evenly sized rows and columns (like a spreadsheet or a calculator).
Java
import javax.swing.*;
import java.awt.*; // Layout Managers are in the java.awt package

public class LayoutExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("BorderLayout Example");
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // Set the layout manager of the frame
        frame.setLayout(new BorderLayout());

        // Add components to specific regions
        frame.add(new JButton("Top (North)"), BorderLayout.NORTH);
        frame.add(new JButton("Bottom (South)"), BorderLayout.SOUTH);
        frame.add(new JButton("Left (West)"), BorderLayout.WEST);
        frame.add(new JButton("Right (East)"), BorderLayout.EAST);
        
        // The Center region stretches to fill remaining space
        JTextArea textArea = new JTextArea("Main working area (Center)");
        frame.add(textArea, BorderLayout.CENTER);

        frame.setVisible(true);
    }
}

Event Handling: Making Things Interactive

A button that you can click is useless if it doesn't actually do anything. In GUI programming, user actions (clicking a button, typing a key, moving the mouse) generate Events. To respond to an event, you must attach an Event Listener to the component.

The ActionListener Interface

For button clicks, we use the ActionListener interface. When the button is clicked, Java calls the actionPerformed() method inside the listener.

Because ActionListener is a functional interface (it has only one method), the modern, elegant way to write this in Java is by using a Lambda Expression.

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

public class EventExample {
    public static void main(String[] args) {
        JFrame frame = new JFrame("Interactive App");
        frame.setSize(300, 200);
        frame.setLayout(new FlowLayout());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JTextField textField = new JTextField(15);
        JButton greetButton = new JButton("Say Hello");
        JLabel resultLabel = new JLabel("...");

        // --- EVENT HANDLING ---
        // We add an ActionListener to the button using a Lambda expression
        greetButton.addActionListener(event -> {
            // This code runs ONLY when the button is clicked
            String name = textField.getText();
            
            if (name.isEmpty()) {
                resultLabel.setText("Please enter a name first!");
            } else {
                resultLabel.setText("Hello, " + name + "!");
                // Clear the text field for the next entry
                textField.setText(""); 
            }
        });

        frame.add(new JLabel("Name: "));
        frame.add(textField);
        frame.add(greetButton);
        frame.add(resultLabel);

        frame.setVisible(true);
    }
}
Pop-up Dialogs

Sometimes instead of updating a label, you want to show a quick pop-up message to the user. Swing provides a very easy way to do this using JOptionPane.

JOptionPane.showMessageDialog(frame, "Operation Successful!");