Drawing and animation
IA tooling, not an exam topic. These are JavaFX patterns for drawing tools, simulations, and small games. Most form-and-table IAs will not need them. Nothing here is examinable, and your IA must be your own work.
A Canvas is a blank rectangle you draw on directly with shapes, lines, text, and images. This page covers drawing on it, reacting to the mouse, and running a smooth animation loop. Reach for these only if your IA is a drawing tool, a simulation, or a game-style app.
Draw shapes and lines on a canvas
What this does: draws shapes, lines, and text onto a Canvas using its GraphicsContext, the object that holds the drawing commands.
When you would use it in your IA: a board for a game, a simple diagram, a chart you want full control over, or any free-form drawing surface.
The pattern:
Imports:
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
Controller:
@FXML private Canvas canvas;
@FXML
public void initialize() {
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.CORNFLOWERBLUE);
gc.fillRect(20, 20, 100, 60); // x, y, width, height
gc.setStroke(Color.DARKRED);
gc.strokeLine(20, 100, 200, 100); // from (x1, y1) to (x2, y2)
gc.fillOval(140, 20, 50, 50); // x, y, width, height of the bounding box
gc.strokeText("Hello", 20, 150); // text at (x, y)
}
FXML:
<Canvas fx:id="canvas" width="300" height="200" />
Make it your own:
- Change the colours, coordinates, and sizes for your own drawing.
setFillthen afill...method draws a solid shape;setStrokethen astroke...method draws an outline.
Watch out for:
- Coordinates start at
(0, 0)in the top-left corner, andyincreases downward, not upward. This trips up most people once. - A canvas is “paint and forget”: you are drawing pixels, not objects. Once a shape is drawn it has no identity, so to move or remove it you clear the area and draw again. The animation recipe below relies on this.
Mix with: Draw where the user clicks or drags, Run a smooth animation or game loop.
Draw where the user clicks or drags
What this does: reads the mouse position on the canvas and draws there, so the user can click or drag to make marks.
When you would use it in your IA: a paint or sketch tool, placing pieces on a board, or letting the user mark points on a diagram.
The pattern:
Imports:
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
Controller (one handler covers both a click and a drag):
@FXML private Canvas canvas;
@FXML
private void handleDraw(MouseEvent event) {
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.BLACK);
// event.getX() and event.getY() are the mouse position on the canvas.
gc.fillOval(event.getX() - 5, event.getY() - 5, 10, 10);
}
FXML (send both press and drag to the same handler):
<Canvas fx:id="canvas" width="300" height="200"
onMousePressed="#handleDraw" onMouseDragged="#handleDraw" />
Make it your own:
- Change what you draw at the mouse position: a dot, a line from the last point, a game piece.
onMousePressedfires once per click;onMouseDraggedfires repeatedly as the mouse moves with the button down. Using both gives a continuous brush.- Subtracting
5(half the10-wide oval) centres the mark on the cursor.
Watch out for:
event.getX()andevent.getY()are measured from the canvas’s top-left corner, which is what you want when drawing on it.- For a separate “released” action (for example finishing a line), add
onMouseReleasedpointing at another method.
Mix with: Draw shapes and lines on a canvas, React to the Enter key.
Run a smooth animation or game loop
What this does: runs a piece of code on every frame (about 60 times a second) using an AnimationTimer, which is what gives smooth motion.
When you would use it in your IA: moving a sprite, a physics or particle simulation, or any game loop that updates and redraws continuously.
The pattern:
Imports:
import javafx.animation.AnimationTimer;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;
Controller:
@FXML private Canvas canvas;
private double ballX = 0;
@FXML
public void initialize() {
GraphicsContext gc = canvas.getGraphicsContext2D();
AnimationTimer loop = new AnimationTimer() {
@Override
public void handle(long now) {
// 1. wipe the canvas so the last frame does not leave a trail
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
// 2. draw this frame
gc.setFill(Color.TOMATO);
gc.fillOval(ballX, 80, 30, 30);
// 3. update the state for next frame
ballX += 2;
if (ballX > canvas.getWidth()) {
ballX = 0; // wrap back to the left
}
}
};
loop.start();
}
Make it your own:
- Put your own per-frame logic in
handle: move things, check collisions, redraw. - Keep the moving values (positions, speeds) as fields so they carry over between frames.
- Call
loop.stop()to pause the animation, andloop.start()to resume.
Watch out for:
- Clear the canvas at the start of each frame, or every drawing stays and you get smears instead of motion.
handleruns around 60 times a second, so keep the work inside it light. Heavy work there makes the whole app stutter.AnimationTimeris the heavier cousin ofTimeline. UseTimelinefor a fixed beat like a one-second countdown, andAnimationTimerwhen you need smooth, every-frame motion.- The
new AnimationTimer() { ... }form is an anonymous class with an overriddenhandlemethod. The override is ordinary OOP; the inline class is a convenience for giving the timer its one method.
Mix with: Do something on a repeating beat, Play a sound.