Drawing with JavaFX Canvas
Introduction to JavaFX Canvas
JavaFX Canvas
is a node for rendering custom graphics and animations. However, unlike other Node
subclasses, it has no graphical content by default. All graphics are rendered manually through a GraphicsContext
object, which you obtain from the Canvas
. The GraphicsContext
provides various methods
for drawing shapes, text, images, other graphical elements.
Setting Up the Canvas
Step 1: Create a Canvas Object
To use Canvas
in JavaFX, you first need to create a Canvas
object by specifying its width and height and add it to a layout, like a Pane
, StackPane
or Group
.
Here’s how to create a simple canvas:
// Canvas with width 400px and height 400pxCanvas canvas = new Canvas(400, 400);
Step 2: Access the GraphicsContext
Once the canvas is created, you can retrieve its GraphicsContext
object, which is the tool used for drawing. You access it via the getGraphicsContext2D()
method:
GraphicsContext gc = canvas.getGraphicsContext2D();
Step 3: Add Canvas to the Scene
Now that you have a Canvas
and a GraphicsContext
, add the canvas to a scene graph. Note that a Canvas
can be added to an FXML layout file (using Scene Builder).
Clearing and Redrawing the Canvas
To clear a part of the canvas or the entire canvas, use clearRect()
method of GraphicsContext
. For dynamic drawing, you can clear and redraw based on user input or animation.
// Clear the entire canvasgc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
// Redraw the shapes or update the contentdrawShapes(gc);
Handling Mouse Events
You can handle mouse events on the canvas, such as mouse clicks or movement. Below is an example where the user can click on the canvas, and a circle will be drawn at the clicked position.
canvas.setOnMouseClicked(e -> { gc.setFill(Color.BLACK); gc.fillOval(e.getX() - 20, e.getY() - 20, 40, 40); // Draw circle at mouse click});
Drawing Basic Shapes
Drawing a Line
To draw a line, you can use the strokeLine()
method of GraphicsContext
. It requires the starting and ending coordinates of the line:
gc.setStroke(Color.BLACK); // Set the line color to blackgc.setLineWidth(2); // Set the line widthgc.strokeLine(50, 50, 350, 350); // Draw a line from (50,50) to (350,350)
Drawing a Rectangle
To draw a rectangle, use the strokeRect()
or fillRect()
methods. The difference is that fillRect()
fills the rectangle with a color, while strokeRect()
only outlines it.
// Outline rectanglegc.setStroke(Color.RED);gc.setLineWidth(3);gc.strokeRect(50, 50, 100, 150); // (x, y, width, height)
// Filled rectanglegc.setFill(Color.GREEN);gc.fillRect(200, 50, 100, 150); // (x, y, width, height)
Drawing Rounded Rectangles
To draw a rectangle with rounded corners, use fillRoundRect
or strokeRoundRect
.
gc.setFill(Color.GREEN);gc.fillRoundRect(100, 100, 120, 80, 20, 20); // Round corners (arc width = 20, arc height = 20)
Drawing Circles and Ovals
To draw a circle, use the strokeOval()
or fillOval()
methods. The circle’s bounding box is defined by the top-left corner and its width and height (which will be equal for a perfect circle).
// Outline circlegc.setStroke(Color.BLUE);gc.setLineWidth(2);gc.strokeOval(50, 250, 100, 100); // (x, y, width, height)
// Filled circlegc.setFill(Color.YELLOW);gc.fillOval(200, 250, 100, 100); // (x, y, width, height)
Drawing an Arc
You can draw an arc (slice of a circle) using the strokeArc()
or fillArc()
methods. It requires the x and y coordinates for the bounding box, width, height, the starting angle, and the length of the arc.
gc.setStroke(Color.PURPLE);gc.setLineWidth(3);gc.strokeArc(50, 50, 100, 100, 0, 90, ArcType.OPEN); // Draws a quarter circle
// Draw a filled arc (from startAngle to arcExtent, in degrees)gc.setFill(javafx.scene.paint.Color.RED);gc.fillArc(50, 50, 100, 100, 0, 90, javafx.scene.shape.ArcType.ROUND);
gc.setFill(Color.ORANGE);gc.fillArc(200, 50, 100, 100, 45, 90, ArcType.CHORD); // Draws a filled chord
Drawing a Polygon and Polylines
To draw a polygon, you can use the strokePolygon()
or fillPolygon()
methods. These methods take an array of x-coordinates and y-coordinates to form the vertices of the polygon.
double[] xPoints = {150, 200, 250, 200};double[] yPoints = {350, 300, 350, 400};
gc.setStroke(Color.BROWN);gc.setLineWidth(3);gc.strokePolygon(xPoints, yPoints, 4); // Draws a polygon with 4 points
gc.setFill(Color.CYAN);gc.fillPolygon(xPoints, yPoints, 4); // Fills the polygon with cyan color
Polylines
A polyline is similar to a polygon but does not connect the last point to the first. Example:
double[] xPoints = {50, 150, 250, 350};double[] yPoints = {300, 200, 300, 200};gc.setStroke(Color.BROWN);gc.strokePolyline(xPoints, yPoints, 4); // Open polyline
Drawing Text
You can also draw text using the fillText()
and strokeText()
methods.
gc.setFill(Color.BLACK);gc.setFont(new Font("Arial", 24));gc.fillText("Hello, JavaFX!", 100, 100); // Text with filling
gc.setStroke(Color.RED);gc.setLineWidth(2);gc.strokeText("Stroke Text", 50, 100); // Text with stroke outline
Using Gradients
JavaFX also supports gradients for fills. You can use LinearGradient
or RadialGradient
for more complex fill effects.
// Linear GradientLinearGradient linearGradient = new LinearGradient(0, 0, 1, 1, true, CycleMethod.REFLECT, new Stop(0, Color.RED), new Stop(1, Color.BLUE));gc.setFill(linearGradient);gc.fillRect(50, 50, 300, 100); // Apply gradient to the rectangle
// Radial GradientRadialGradient radialGradient = new RadialGradient(0, 0, 0.5, 0.5, 0.5, true, CycleMethod.REFLECT, new Stop(0, Color.YELLOW), new Stop(1, Color.GREEN));gc.setFill(radialGradient);gc.fillOval(50, 200, 200, 200); // Apply radial gradient to the circle