Free degree-level programming lessons for careful independent study.

Degree Level Programmes · Programming 2 · Lesson 13

Event-Driven Programming

Build a small event-driven Java program where user actions trigger program behaviour.

Lesson Overview

Build a small event-driven Java program where user actions trigger program behaviour.

Portfolio focus: Create a button-click counter or equivalent event task.

ConceptEvents
Run fileEventDrivenProgrammingDemo.java
BaselineButton clicked
Evidence3 tasks

Starter: think before typing

Before running this events example, find the line where the main idea becomes active. Write a prediction: what must already be true for that line to work, and what should be different after it runs? The checked run ends with `Button clicked`; predict how the focus line helps produce that evidence.

Learning Objectives

  • Explain event, listener and handler.
  • Describe control flow in an event-driven program.
  • Keep interface code separate from model logic.
  • Test event responses.

Learning Outcomes

  • By the end of the lesson, you can explain event, listener and handler.
  • By the end of the lesson, you can describe control flow in an event-driven program.
  • By the end of the lesson, you can keep interface code separate from model logic.
  • By the end of the lesson, you can test event responses.

Why this idea exists

Event-driven programming became central as interactive systems replaced purely batch-style programs. Instead of one fixed sequence from start to finish, the program waits for user actions, messages or system events.

Graphical interfaces, games, web applications and many networked systems all rely on this model. It changes how programmers think about control flow because the next action may come from outside the program.

Good event-driven design keeps event handlers small. The handler should translate the event and delegate real work to model or service code that can be tested independently.

Deep dive

Mechanism in this example

The important mechanism is visible around `button.onClick(() -> System.out.println("Button clicked"));`. Read it as a concrete move in the program, not as decorative syntax: identify what value, object, branch, call or boundary is being created at that point.

Design pressure

Good event-driven design keeps event handlers small. The handler should translate the event and delegate real work to model or service code that can be tested independently.

Failure mode to watch

For Event-Driven Programming, deliberately disturb the assumption behind `button.onClick(() -> System.out.println("Button clicked"));`: use an awkward value, missing input, wrong order of calls or boundary case. The useful question is how that disturbance exposes a weakness in the events design.

Extension step

Extend the example by doing this: Draw the event flow. The point is to make one small change that forces you to revisit the concept, rather than adding unrelated features.

Portfolio standard

The portfolio note should not repeat the lesson wording. It should show the edited code, the run result, and your own explanation of this evidence: move business logic out of the handler.

Lesson visual

Photo-real laptop with a Java UI button, event arrows, listener card and state-change notes.
Photo-real laptop with a Java UI button, event arrows, listener card and state-change notes.Download visual

Type this and run it

Create EventDrivenProgrammingDemo.java, type the program, and run it before changing anything. This section is about reproducing the checked baseline.

import java.util.ArrayList;
import java.util.List;

public class EventDrivenProgrammingDemo {
  public static void main(String[] args) {
    Button button = new Button();
    button.onClick(() -> System.out.println("Button clicked"));
    button.click();
  }
}

class Button {
  private final List<Runnable> listeners = new ArrayList<>();

  void onClick(Runnable listener) {
    listeners.add(listener);
  }

  void click() {
    for (Runnable listener : listeners) listener.run();
  }
}

Build and run it with:

javac EventDrivenProgrammingDemo.java && java EventDrivenProgrammingDemo

Expected baseline: Button clicked

Run the code in your browser

Use the editor as an experiment surface. First run the checked version, then make one small change to the part of the program that demonstrates events and compare the new behaviour with the reference output.

Line-by-line explanation

Read the code as a sequence of responsibilities. The focus line for this lesson is button.onClick(() -> System.out.println("Button clicked"));; the surrounding lines prepare it, use its result or make the behaviour observable.

import java.util.ArrayList;

In Event-Driven Programming, this imports ArrayList: a resizable list implementation for changing collections.

import java.util.List;

In Event-Driven Programming, this imports List: the ordered collection type used to hold several values.

public class EventDrivenProgrammingDemo {

This names the runnable class for the Event-Driven Programming example, giving the compiler and JVM one clear unit to build.

public static void main(String[] args) {

This is the program entry point. In Event-Driven Programming, it keeps the demonstration of events in one traceable starting script.

Button button = new Button();

This constructs an object for the Event-Driven Programming example, asking Java for a value with a specific type and behaviour.

button.onClick(() -> System.out.println("Button clicked"));

This registers a listener. Nothing has been clicked yet; the program is storing behaviour to run later when the event occurs.

button.click();

This simulates the event. It is the moment stored listeners should be called.

}

This closes the innermost Event-Driven Programming block, so the immediately preceding method, branch or loop has finished.

}

This closes the outer Event-Driven Programming structure, returning the reader to the surrounding class or file.

class Button {

This starts a supporting class so Event-Driven Programming can separate the lesson idea into its own named responsibility.

private final List<Runnable> listeners = new ArrayList<>();

This stores the button's registered listeners. The list is private so outside code uses methods instead of changing the collection directly.

void onClick(Runnable listener) {

This starts onClick, a named Event-Driven Programming operation. Its parameters describe what information comes in; its body decides what work is done.

listeners.add(listener);

This stores the listener in the button, separating registration from later execution.

}

This closing brace number 3 completes another layer of the Event-Driven Programming source structure Java has been checking.

void click() {

This starts click, a named Event-Driven Programming operation. Its parameters describe what information comes in; its body decides what work is done.

for (Runnable listener : listeners) listener.run();

This executes a stored listener, turning the event into observable program behaviour.

Worked example

From code to explanation

Problem: Use Event-Driven Programming to complete a small portfolio-quality step: Create a button-click counter or equivalent event task.

Method: Locate the line `button.onClick(() -> System.out.println("Button clicked"));`, explain the exact role it plays, then decide what you would change to extend the example without changing the whole program.

Reveal worked answer

The checked run should produce `Button clicked`. A strong answer links the result back to events: what was created, selected, stored, called or protected, and why that matters for the portfolio task.

Trace the program

Before: Before the key operation, identify the relevant value, object, branch or resource that the events concept depends on.

During: Trace `button.onClick(() -> System.out.println("Button clicked"));` as the Event-Driven Programming example executes. Say whether that operation creates data, checks a condition, calls behaviour, stores information or crosses a boundary.

After: Compare the run with the expected evidence: `Button clicked`.

Change: Now draw the event flow, run again, and explain the smallest reason the behaviour changed.

Common misconception

A common mistake in event-driven programming is treating the example as a finished answer. For events, the important question is narrower: which operation carries the idea, what does it make possible, and what would break if you changed it carelessly?

Quick checks

1. In this Event-Driven Programming example, what is the best reason to focus on `button.onClick(() -> System.out.println("Button clicked"));`?

2. Which evidence is strongest after you edit and rerun this example?

How to study this lesson

For Event-Driven Programming, predict how events changes the run before you press Run.

Use the first portfolio task as your main edit: Create a button-click counter or equivalent event task.

Use the second task as your variation: Draw the event flow.

Finish with evidence, not a diary entry: Move business logic out of the handler.

Portfolio Practice

  1. Create a button-click counter or equivalent event task.
  2. Draw the event flow.
  3. Move business logic out of the handler.

Final self-check

Can you explain the key operation?

Explain the line identified in the quick check in one or two sentences. Your answer should say what it does before the output Button clicked appears.

Can you justify the portfolio evidence?

Your evidence should include the original run, one edited run, and a short note explaining how the edit affected events.

Study route

Practise events by predicting the Java example, typing it, running it in the browser, tracing the result and saving portfolio evidence.

Next, move into Operator-Style API Design and carry forward one improvement from this lesson into the next program.