Event-driven programming

Events

  • User actions (button clicks, keyboard and mouse input)
  • Events from other applications or the system (download has finished, smartwatch warning)

We have done some of this when coding button actions on JavaFX

Event-driven Programming

  • Wait (listen) for events
  • React to events as they occur
  • Use appropriate event-handling methods

Event handling in JavaFX

  • For each GUI component, define an event handler

Starter code

package com.paint;

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

import java.io.IOException;

/**
 * JavaFX App
 */
public class App extends Application {

    private static Scene scene;

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

    public void drawDot(int x, int y, Group group) {
        Circle circle = new Circle();
        circle.setCenterX(x);
        circle.setCenterY(y);
        circle.setRadius(5);
        group.getChildren().add(circle);
    }

    @Override
    public void start(Stage stage) throws IOException {
        stage.setTitle("My Window");

        // set up the canvas
        Group root = new Group();
        drawDot(10, 10, root);

        scene = new Scene(root, 640, 480);
        stage.setScene(scene);
        stage.show();
    }
   
}

Mouse events in Scene

The class Scence has a .addEventFilter() method. The MouseEvent class has a few events. Let’s use MOUSE_CLICKED.

scene.addEventFilter(MouseEvent.MOUSE_CLICKED,
                     new EventHandler<MouseEvent>() {});

The second argument in the addEventFilter is new EventHandler<MouseEvent>() {}, an anonymous inner class.

Inner anonymous class

EventHandler class documentation

scene.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
  public void handle(MouseEvent mouseEvent) {
    int x = (int) mouseEvent.getX();
    int y = (int) mouseEvent.getY();
    System.out.println(x + " " + y);
    drawDot(x, y, root);
  }
});

Lambda Function

Anonymous method with a concise syntax: (e) -> {}

scene.addEventFilter(MouseEvent.MOUSE_CLICKED, (mouseEvent) -> {
  int x = (int) mouseEvent.getX();
  int y = (int) mouseEvent.getY();
  System.out.println(x + " " + y);
  drawDot(x, y, root); 
});

Add a MOUSE_DRAGGED event handler

Create a clear button

Implement clearGroup(Group)

Button clearButton = new Button("Clear");
root.getChildren().add(clearButton);

clearButton.setOnAction((actionEvent) -> {
  // TODO 
});

Solution

clearButton.setOnAction((actionEvent) -> {
  root.getChildren().clear();
  root.getChildren().add(clearButton);
});

Implement brush color and size

Do not set global variables. Create a Brush class instead with instance variables for color and size.