Unit 2: GUI and Event Handling

CSE406 — Advanced Java Programming 9 min read

I. Orientation

Java Swing is a GUI toolkit introduced with the Java Foundation Classes in Java 1.2 (1998). It provides platform-independent windows, controls, layout systems, drawing facilities, and an event-driven programming model in which user actions determine program flow.

  • Core principle: A Swing program creates a hierarchy of components, displays them inside top-level containers, and responds to events through registered listeners.
  • Main packages:
    • javax.swing: Swing components such as JFrame, JPanel, and JButton.
    • java.awt: layouts, colors, fonts, graphics, and basic event infrastructure.
    • java.awt.event: event classes, listener interfaces, and adapter classes.
  • Lightweight components: Most Swing controls are drawn by Java rather than by native operating-system peers.
  • Event-driven execution: The program normally waits for events such as button clicks, mouse movement, or key presses.
  • Event Dispatch Thread (EDT): Swing component creation and modification should occur on the EDT, commonly through SwingUtilities.invokeLater.
  • Component hierarchy: Controls are placed in containers, while layout managers determine their sizes and positions.

II. Swing Foundations — Windows, Containers, and Controls

A. Introduction to Swing

Swing is Java’s platform-independent library for building desktop graphical user interfaces.

  • Pluggable look and feel: Swing can change component appearance without changing application logic; examples include system and cross-platform look-and-feel implementations.
  • Rich component set: It supplies buttons, labels, lists, tables, trees, menus, dialogs, and text controls.
  • Naming convention: Swing component names usually begin with J, as in JLabel, JButton, and JTable.
  • MVC influence: Many Swing components separate their data model from visual presentation; for example, JList uses a ListModel.
  • Threading rule: GUI startup should be scheduled safely:
JAVA
SwingUtilities.invokeLater(() -> {
    JFrame frame = new JFrame("Application");
    frame.setVisible(true);
});

B. JFrame and JPanel

JFrame represents a top-level window, whereas JPanel is a lightweight container used to organize components or perform custom drawing.

  1. JFrame:

    • Purpose: Provides a title bar, border, content area, and window controls.
    • Configuration: Common methods include setSize, setTitle, setLocationRelativeTo, and setDefaultCloseOperation.
    • Closing behavior: JFrame.EXIT_ON_CLOSE terminates the application when the frame closes.
  2. JPanel:

    • Purpose: Groups related controls inside a frame and supports nested layouts.
    • Default layout: A new JPanel normally uses FlowLayout.
    • Custom painting: Drawing is performed by overriding paintComponent(Graphics g).
JAVA
JFrame frame = new JFrame("Demo");
JPanel panel = new JPanel();
panel.add(new JButton("Save"));
frame.add(panel);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

C. Swing components

Swing components are reusable GUI objects that display information, receive input, or organize other components.

  • Display controls: JLabel shows text or icons; JProgressBar visually represents progress.
  • Command controls: JButton initiates an action, while JMenuItem represents a menu command.
  • Text controls: JTextField accepts one line, JTextArea accepts multiple lines, and JPasswordField masks input.
  • Selection controls: JCheckBox permits independent choices; JRadioButton supports exclusive choices when placed in a ButtonGroup.
  • Data controls: JList, JTable, and JTree present collections or structured information.
  • Scrolling: Large components such as JTextArea are commonly placed in JScrollPane.

III. Interface Arrangement and Rendering

A. Layout managers

Layout managers automatically calculate component position and size, making interfaces more portable than fixed coordinates.

  • FlowLayout: Arranges components left to right and moves them to a new row when space is insufficient.
  • BorderLayout: Divides a container into NORTH, SOUTH, EAST, WEST, and CENTER; a frame’s content pane uses it by default.
  • GridLayout: Places components in equal-sized cells arranged as rows and columns.
  • BoxLayout: Arranges components along either the horizontal X_AXIS or vertical Y_AXIS.
  • GridBagLayout: Uses GridBagConstraints for flexible grids with components of different sizes.
  • Manual positioning: A null layout requires setBounds(x, y, width, height) and is generally avoided because it adapts poorly to fonts and screen sizes.
JAVA
panel.setLayout(new GridLayout(2, 2, 5, 5));
// 2 rows, 2 columns, 5-pixel horizontal and vertical gaps

B. Color class

The java.awt.Color class represents colors used for component backgrounds, foregrounds, borders, and custom graphics.

  • RGB model: new Color(r, g, b) accepts red, green, and blue values from 0 to 255.
  • Alpha channel: new Color(r, g, b, a) adds transparency, where 0 is transparent and 255 is opaque.
  • Constants: Named values include Color.RED, Color.BLUE, Color.WHITE, and Color.BLACK.
  • Component use: setBackground(Color.YELLOW) changes a background, while setForeground(Color.BLUE) changes text or foreground drawing.
  • Concrete example: new Color(255, 128, 0) produces orange because red is maximum, green is half intensity, and blue is absent.

C. Font class

The java.awt.Font class describes the family, style, and point size used to render text.

  • Construction: The form is new Font(name, style, size).
    • name: Font family such as "Serif" or "Monospaced".
    • style: Font.PLAIN, Font.BOLD, Font.ITALIC, or a combined style.
    • size: Text size measured in points.
  • Application: Components accept fonts through setFont.
  • Combined style: Bitwise OR combines constants, as in Font.BOLD | Font.ITALIC.
  • Example:
JAVA
Font heading = new Font("SansSerif", Font.BOLD, 20);
label.setFont(heading);

D. Graphics class

The abstract java.awt.Graphics class provides methods for drawing text, lines, shapes, and images on components.

  • Coordinate system: The origin (0, 0) is the component’s upper-left corner; x increases rightward and y downward.
  • Drawing methods: Common operations include drawLine, drawRect, fillRect, drawOval, fillOval, and drawString.
  • Painting method: Custom Swing drawing belongs in paintComponent, not in arbitrary application code.
  • Superclass call: super.paintComponent(g) clears the previous display and paints the panel correctly.
  • Graphics state: setColor and setFont affect subsequent drawing operations.
JAVA
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLUE);
    g.fillOval(20, 20, 80, 80);
    g.drawString("Circle", 35, 120);
}

IV. GUI Construction

A. Programs to create Graphical User Interface

A Swing GUI program normally creates a frame, selects a layout, adds components, registers listeners, and finally displays the frame.

  • Construction sequence:
    1. Create components such as JLabel, JTextField, and JButton.
    2. Add them to a panel or frame under a layout manager.
    3. attach listeners to interactive components.
    4. Call pack() or setSize, then setVisible(true).
  • pack() method: Sizes the window according to the preferred sizes of its contained components.
  • Example program:
JAVA
import javax.swing.*;

public class GreetingGUI {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame("Greeting");
            JTextField name = new JTextField(12);
            JButton button = new JButton("Greet");
            JLabel result = new JLabel(" ");

            JPanel p = new JPanel();
            p.add(name);
            p.add(button);
            p.add(result);

            button.addActionListener(e ->
                result.setText("Hello, " + name.getText()));

            f.add(p);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}

V. Java Event Architecture

A. Event delegation model

The event delegation model separates event generation from event processing by delegating each event to registered listener objects.

  • Three participants:
    • Source: The component that generates the event, such as a JButton.
    • Event object: An object containing event details, such as ActionEvent.
    • Listener: An object whose callback method processes the event.
  • Advantage: A source need not contain the response logic; different listeners can handle different actions.
  • Dispatch process: User action → source creates event object → registered callback executes on the EDT.

B. Event and event source

An event represents a change in component state, while an event source is the object on which that change occurs.

  • Event hierarchy: GUI event classes ultimately derive from java.util.EventObject; many AWT events extend AWTEvent.
  • Examples: Clicking a button produces ActionEvent, pressing a key produces KeyEvent, and moving a mouse produces MouseEvent.
  • Source retrieval: event.getSource() returns the originating object.
  • Event information: A MouseEvent supplies coordinates through getX() and getY(), while a KeyEvent supplies a key code through getKeyCode().

C. Event listener interfaces

Listener interfaces declare callback methods that Java invokes when corresponding events occur.

  • ActionListener: Declares actionPerformed(ActionEvent e) for buttons, menu items, and text-field actions.
  • MouseListener: Declares methods including mouseClicked, mousePressed, and mouseReleased.
  • MouseMotionListener: Handles mouseMoved and mouseDragged.
  • KeyListener: Declares keyPressed, keyReleased, and keyTyped.
  • WindowListener: Responds to window opening, closing, activation, and related state changes.

D. Registration and handling events

Registration connects a source to a listener so that the listener receives matching events.

  • Registration methods: Sources provide methods such as addActionListener, addMouseListener, and addKeyListener.
  • Handling method: The listener implements the callback required by its interface.
  • Removal: Methods such as removeActionListener detach listeners when they are no longer required.
  • Example:
JAVA
button.addActionListener(e -> label.setText("Button clicked"));
  • Threading consequence: Lengthy work inside a callback freezes repainting and input; background work should use mechanisms such as SwingWorker.

VI. User-Input Events

A. Mouse events

Mouse events report clicking, pressing, releasing, entering, exiting, moving, and dragging within a component.

  • Event interfaces: MouseListener handles button and boundary events; MouseMotionListener handles movement and dragging.
  • Event data: getX() and getY() return component-relative coordinates; getButton() identifies the pressed button.
  • Click count: getClickCount() distinguishes single and multiple clicks.
  • Registration:
JAVA
panel.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        System.out.println(e.getX() + ", " + e.getY());
    }
});

B. Key events

Key events describe keyboard activity received by the component that currently owns keyboard focus.

  • Event types: keyPressed reports physical key depression, keyReleased reports release, and keyTyped reports a Unicode character.
  • Key information: getKeyCode() identifies keys such as KeyEvent.VK_ENTER; getKeyChar() returns the typed character.
  • Focus requirement: A component generally must be focusable and own focus before its KeyListener receives events.
  • Swing alternative: Key bindings using InputMap and ActionMap are often preferable because they manage focus conditions more reliably.

VII. Listener Implementation Techniques

A. Anonymous class listeners

An anonymous class creates and registers a one-use listener without defining a separately named class.

  • Purpose: Keeps short event-handling code close to the component registration statement.
  • Syntax: The interface or class name is followed by an inline body that overrides callback methods.
  • Example:
JAVA
button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        label.setText("Saved");
    }
});
  • Lambda comparison: Functional interfaces such as ActionListener may use lambdas, but multi-method interfaces such as MouseListener cannot be represented directly by one lambda.

B. Listener interface adapter

A listener interface adapter is an abstract convenience class that supplies empty implementations of every method in a multi-method listener interface.

  • Purpose: A subclass overrides only the callbacks it needs instead of implementing every interface method.
  • Common adapters: MouseAdapter, KeyAdapter, WindowAdapter, and FocusAdapter.
  • Contrast:
    1. Implementing MouseListener requires all five callback methods.
    2. Extending MouseAdapter permits overriding only mouseClicked, for example.
  • Limitation: Because Java supports single class inheritance, a class already extending another class may use an anonymous adapter object rather than extending the adapter itself.