JavaFX Canvas Example
This is a JavaFX Canvas Example. Through thejavafx.scene.canvas package, JavaFX provides the Canvas API that offers a drawing surface to draw shapes, images, and text using drawing commands. The API also gives pixel-level access to the drawing surface where you can write any pixels on the surface. The API consists of only two classes:
- Canvas
- GraphicsContext
A canvas is a bitmap image, which is used as a drawing surface. An instance of theCanvas class represents a canvas. It inherits from theNode class. Therefore, aCanvas is aNode.
It can be added to aScene Graph, and effects and transformations can be applied to it. ACanvas has a graphics context associated with it that is used to issue drawing commands to theCanvas. An instance of theGraphicsContext class represents a graphics context.
The following table shows an overview of the whole article:
Table Of Contents
The following examples uses Java SE 8 and JavaFX 2.2.
1. Creating a Canvas
1.1 The Code
FxCanvasExample1.java
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.layout.Pane;import javafx.stage.Stage;public class FxCanvasExample1 extends Application{public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) { // Create the CanvasCanvas canvas = new Canvas(400, 200);// Set the width of the Canvascanvas.setWidth(400);// Set the height of the Canvascanvas.setHeight(200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Draw a Textgc.strokeText("Hello Canvas", 150, 100);// Create the PanePane root = new Pane();// Set the Style-properties of the Paneroot.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: blue;");// Add the Canvas to the Paneroot.getChildren().add(canvas);// Create the SceneScene scene = new Scene(root);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("Creation of a Canvas");// Display the Stagestage.show();}}TheCanvas class has two constructors. The no-args constructor creates an empty canvas. Later, you can set the size of the canvas using its width and height properties. The other constructor takes the width and height of the canvas as parameters:
// Create a Canvas of zero width and heightCanvas canvas = new Canvas();// Create a 400X200 canvasCanvas canvas = new Canvas(400, 200);
1.2 The GUI
The following image shows the result of the above example:

2. Drawing on the Canvas
2.1 Introduction
Once you create a canvas, you need to get its graphics context using thegetGraphicsContext2D() method, as in the following snippet of code:
// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();
All drawing commands are provided in theGraphicsContext class as methods. Drawings that fall outside the bounds of theCanvas are clipped. The canvas uses a buffer. The drawing commands push necessary parameters to the buffer. It is important to note that you should use the graphics context from any one thread before adding theCanvas to the Scene Graph.
Once theCanvas is added to the Scene Graph, the graphics context should be used only on the JavaFX Application Thread. TheGraphicsContext class contains methods to draw the following types of objects:
- Basic shapes
- Text
- Paths
- Images
- Pixels
2.2 Drawing Basic Shapes
2.2.1 The Code
FxCanvasExample2.java
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.layout.Pane;import javafx.scene.paint.Color;import javafx.scene.shape.ArcType;import javafx.stage.Stage;public class FxCanvasExample2 extends Application{public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {// Create the Canvas with a width of 400 px and a height of 200 px.Canvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Set line widthgc.setLineWidth(2.0);// Set fill colorgc.setFill(Color.RED);// Draw a rounded Rectanglegc.strokeRoundRect(10, 10, 50, 50, 10, 10);// Draw a filled rounded Rectanglegc.fillRoundRect(100, 10, 50, 50, 10, 10);// Change the fill colorgc.setFill(Color.BLUE);// Draw an Ovalgc.strokeOval(10, 70, 50, 30);// Draw a filled Ovalgc.fillOval(100, 70, 50, 30);// Draw a Linegc.strokeLine(200, 50, 300, 50);// Draw an Arcgc.strokeArc(320, 10, 50, 50, 40, 80, ArcType.ROUND);// Draw a filled Arcgc.fillArc(320, 70, 50, 50, 00, 120, ArcType.OPEN);// Create the PanePane root = new Pane();// Set the Style-properties of the Paneroot.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: blue;");// Add the Canvas to the Paneroot.getChildren().add(canvas);// Create the SceneScene scene = new Scene(root);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("Drawing Basic Shapes on a Canvas");// Display the Stagestage.show();}}TheGraphicsContext class provides two types of methods to draw the basic shapes. The methodfillXxx() draws a shapeXxx and fills it with the current fill paint. The methodstrokeXxx() draws a shapeXxx with the current stroke. Use the following methods for drawing shapes:
- fillArc()
- fillOval()
- fillPolygon()
- fillRect()
- fillRoundRect()
- strokeArc()
- strokeLine()
- strokeOval()
- strokePolygon()
- strokePolyline()
- strokeRect()
- strokeRoundRect()
The following snippet of code draws a rounded rectangle. The stroke color is red and the stroke width is 2px. The upper-left corner of the rectangle is at (10, 10). The rectangle is 50px wide and 50px high. ThearcWidth and thearcHeight are 10 px.
// Create the Canvas with a width of 400 px and a height of 200 px.Canvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Set line widthgc.setLineWidth(2.0);// Set fill colorgc.setFill(Color.RED);// Draw a rounded Rectanglegc.strokeRoundRect(10, 10, 50, 50, 10, 10);
2.2.2 The GUI
The following image shows a canvas with a few basic shapes (rectangular, oval, etc.):

2.3 Drawing Text
2.3.1 The Code
FxCanvasExample3.java
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.layout.Pane;import javafx.scene.paint.Color;import javafx.stage.Stage;public class FxCanvasExample3 extends Application{public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {// Create the CanvasCanvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Set line widthgc.setLineWidth(1.0);// Set fill colorgc.setFill(Color.BLUE);// Draw a Textgc.strokeText("This is a stroked Text", 10, 50);gc.strokeText("This is a stroked Text with Max Width 300 px", 10, 100, 300);// Draw a filled Textgc.fillText("This is a filled Text", 10, 150);gc.fillText("This is a filled Text with Max Width 400 px", 10, 200, 400);// Create the PanePane root = new Pane();// Set the Style-properties of the Paneroot.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: blue;");// Add the Canvas to the Paneroot.getChildren().add(canvas);// Create the SceneScene scene = new Scene(root);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("Drawing a Text on a Canvas");// Display the Stagestage.show();}}You can draw text using thefillText() andstrokeText() methods of theGraphicsContext using the following snippets of code:
- void strokeText(String text, double x, double y)
- void strokeText(String text, double x, double y, double maxWidth)
- void fillText(String text, double x, double y)
- void fillText(String text, double x, double y, double maxWidth)
Both methods are overloaded. One version lets you specify the text and its position. The other version lets you specify the maximum width of the text as well. If the actual text width exceeds the specified maximum width, the text is resized to fit the specified the maximum width.
The following snippet of code draws a blue filledText.
// Create the CanvasCanvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Set line widthgc.setLineWidth(1.0);// Set fill colorgc.setFill(Color.BLUE);// Draw a filled Textgc.fillText("This is a filled Text", 10, 150);2.3.2 The GUI
The following GUI shows a few examples of stroked and filled texts:

2.4 Drawing Paths
2.4.1 The Code
FxCanvasExample4.java
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.layout.Pane;import javafx.scene.paint.Color;import javafx.stage.Stage;public class FxCanvasExample4 extends Application{public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {// Create the CanvasCanvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Set line widthgc.setLineWidth(2.0);// Set the Colorgc.setStroke(Color.GREEN);// Set fill colorgc.setFill(Color.LIGHTCYAN);// Start the Pathgc.beginPath();// Make different Pathsgc.moveTo(50, 50);gc.quadraticCurveTo(30, 150, 300, 200);gc.fill();// End the Pathgc.closePath();// Draw the Pathgc.stroke();// Create the PanePane root = new Pane();// Set the Style-properties of the Paneroot.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: blue;");// Add the Canvas to the Paneroot.getChildren().add(canvas);// Create the SceneScene scene = new Scene(root);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("Drawing Paths on a Canvas");// Display the Stagestage.show();}}Use can use path commands and SVG path strings to create aShape of your choice. A path consists of multiple subpaths. The following methods are used to draw paths:
- beginPath()
- lineTo(double x1, double y1)
- moveTo(double x0, double y0)
- quadraticCurveTo(double xc, double yc, double x1, double y1)
- appendSVGPath(String svgpath)
- arc(double centerX, double centerY, double radiusX, double radiusY, double startAngle, double length)
- arcTo(double x1, double y1, double x2, double y2, double radius)
- bezierCurveTo(double xc1, double yc1, double xc2, double yc2, double x1, double y1)
- closePath()
- stroke()
- fill()
ThebeginPath() andclosePath() methods start and close a path, respectively. Methods such asarcTo() andlineTo() are the path commands to draw a specific type of subpath. Do not forget to call thestroke() orfill() method at the end, which will draw an outline or fill the path.
The following snippet of code draws a quadratic curve. The color of the curve is green and the fill color is lightcyan.
// Start the Pathgc.beginPath();// Make different Pathsgc.moveTo(50, 50);gc.quadraticCurveTo(30, 150, 300, 200);gc.fill();// End the Pathgc.closePath();
2.4.2 The GUI
The following image shows a simple example how to draw a path on a canvas:

2.5 Drawing Images
2.5.1 The Code
FxCanvasExample5.java
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.image.Image;import javafx.scene.layout.Pane;import javafx.stage.Stage;public class FxCanvasExample5 extends Application{public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {// Create the CanvasCanvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Load the ImageString imagePath = "file:\\Path-To-Your-Image\\java-logo.gif";Image image = new Image(imagePath);// Draw the Imagegc.drawImage(image, 10, 10, 200, 200);gc.drawImage(image, 220, 50, 100, 70);// Create the PanePane root = new Pane();// Set the Style-properties of the Paneroot.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: blue;");// Add the Canvas to the Paneroot.getChildren().add(canvas);// Create the SceneScene scene = new Scene(root);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("Drawing an Image on a Canvas");// Display the Stagestage.show();}}You can draw anImage on theCanvas using thedrawImage() method. The method has three versions:

Thank you!
We will contact you soon.
- void drawImage(Image img, double x, double y)
- void drawImage(Image img, double x, double y, double w, double h)
- void drawImage(Image img, double sx, double sy, double sw, double sh, double dx, double dy, double dw, double dh)
You can draw the whole or part of theImage. The drawn image can be stretched or shortened on the canvas.
The following snippet of code draws the first whole image with a size of 200 px x 200 px on the canvas at (10, 10). The second image will be drawn at (220, 50). The width is 100 px and the height is 70 px.
// Create the CanvasCanvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Load the ImageString imagePath = "file:\\Path-To-Your-Image\\java-logo.gif";Image image = new Image(imagePath);// Draw the Imagegc.drawImage(image, 10, 10, 200, 200);gc.drawImage(image, 220, 50, 100, 70);
2.5.2 The GUI
The following GUI shows a canvas, which contains two images:

2.6 Writing Pixels
2.6.1 The Code
FxCanvasExample6.java
import java.nio.ByteBuffer;import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.image.PixelFormat;import javafx.scene.image.PixelWriter;import javafx.scene.layout.Pane;import javafx.stage.Stage;public class FxCanvasExample6 extends Application{private static final int RECT_WIDTH = 25;private static final int RECT_HEIGHT = 25;public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {Canvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Set line widthgc.setLineWidth(2.0);// Write custom pixels to create a patternwritePixels(gc);// Create the PanePane root = new Pane();// Set the Style-properties of the Paneroot.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: blue;");// Add the Canvas to the Paneroot.getChildren().add(canvas);// Create the SceneScene scene = new Scene(root);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("Writing Pixels on a Canvas");// Display the Stagestage.show();}private void writePixels(GraphicsContext gc) {// Define properties of the Imageint spacing = 5;int imageWidth = 300;int imageHeight = 100;int rows = imageHeight/(RECT_HEIGHT + spacing);int columns = imageWidth/(RECT_WIDTH + spacing);// Get the Pixelsbyte[] pixels = this.getPixelsData();// Create the PixelWriterPixelWriter pixelWriter = gc.getPixelWriter();// Define the PixelFormatPixelFormat<ByteBuffer> pixelFormat = PixelFormat.getByteRgbInstance();// Write the pixels to the canvasfor (int y = 0; y < rows; y++) {for (int x = 0; x < columns; x++) {int xPos = 50 + x * (RECT_WIDTH + spacing);int yPos = 50 + y * (RECT_HEIGHT + spacing);pixelWriter.setPixels(xPos, yPos, RECT_WIDTH, RECT_HEIGHT,pixelFormat, pixels, 0, RECT_WIDTH * 3);}}}private byte[] getPixelsData() {// Create the Arraybyte[] pixels = new byte[RECT_WIDTH * RECT_HEIGHT * 3];// Set the rationdouble ratio = 1.0 * RECT_HEIGHT/RECT_WIDTH;// Generate pixel datafor (int y = 0; y < RECT_HEIGHT; y++) {for (int x = 0; x < RECT_WIDTH; x++) {int i = y * RECT_WIDTH * 3 + x * 3;if (x <= y/ratio) {pixels[i] = -1;pixels[i+1] = 1;pixels[i+2] = 0;} else {pixels[i] = 1;pixels[i+1] = 1;pixels[i+2] = 0;}}}// Return the Pixelsreturn pixels;}}You can also directly modify pixels on theCanvas. ThegetPixelWriter() method of theGraphicsContext object returns aPixelWriter that can be used to write pixels to the associated canvas:
Canvas canvas = new Canvas(200, 100);GraphicsContext gc = canvas.getGraphicsContext2D();PixelWriter pw = gc.getPixelWriter();
Once you get aPixelWriter, you can write pixels to the canvas.
The following method creates an array of pixels with the corresponding with, height and RGB-Code:
private byte[] getPixelsData() {// Create the Arraybyte[] pixels = new byte[RECT_WIDTH * RECT_HEIGHT * 3];// Set the rationdouble ratio = 1.0 * RECT_HEIGHT/RECT_WIDTH;// Generate pixel datafor (int y = 0; y < RECT_HEIGHT; y++) {for (int x = 0; x < RECT_WIDTH; x++) {int i = y * RECT_WIDTH * 3 + x * 3;if (x <= y/ratio) {pixels[i] = -1;pixels[i+1] = 1;pixels[i+2] = 0;} else {pixels[i] = 1;pixels[i+1] = 1;pixels[i+2] = 0;}}}// Return the Pixelsreturn pixels;}The following method draws the pixels on the canvas.
private void writePixels(GraphicsContext gc) {// Define properties of the Imageint spacing = 5;int imageWidth = 300;int imageHeight = 100;int rows = imageHeight/(RECT_HEIGHT + spacing);int columns = imageWidth/(RECT_WIDTH + spacing);// Get the Pixelsbyte[] pixels = this.getPixelsData();// Create the PixelWriterPixelWriter pixelWriter = gc.getPixelWriter();// Define the PixelFormatPixelFormat<ByteBuffer> pixelFormat = PixelFormat.getByteRgbInstance();// Write the pixels to the canvasfor (int y = 0; y < rows; y++) {for (int x = 0; x < columns; x++) {int xPos = 50 + x * (RECT_WIDTH + spacing);int yPos = 50 + y * (RECT_HEIGHT + spacing);pixelWriter.setPixels(xPos, yPos, RECT_WIDTH, RECT_HEIGHT,pixelFormat, pixels, 0, RECT_WIDTH * 3);}}}2.6.2 The GUI
The following GUI shows the result of the written pixels on the canvas:

3. Clearing the Canvas Area
3.1 The Code
FxCanvasExample7.java
import javafx.application.Application;import javafx.scene.Scene;import javafx.scene.canvas.Canvas;import javafx.scene.canvas.GraphicsContext;import javafx.scene.layout.Pane;import javafx.scene.paint.Color;import javafx.stage.Stage;public class FxCanvasExample7 extends Application{public static void main(String[] args) {Application.launch(args);}@Overridepublic void start(Stage stage) {// Create the CanvasCanvas canvas = new Canvas(400, 200);// Get the graphics context of the canvasGraphicsContext gc = canvas.getGraphicsContext2D();// Set line widthgc.setLineWidth(2.0);// Set fill colorgc.setFill(Color.GREEN);// Draw a rounded Rectanglegc.fillRoundRect(50, 50, 300, 100, 10, 10);// Clear the rectangular area from the canvasgc.clearRect(80, 80, 130, 50);// Create the PanePane root = new Pane();// Set the Style-properties of the Paneroot.setStyle("-fx-padding: 10;" +"-fx-border-style: solid inside;" +"-fx-border-width: 2;" +"-fx-border-insets: 5;" +"-fx-border-radius: 5;" +"-fx-border-color: blue;");// Add the Canvas to the Paneroot.getChildren().add(canvas);// Create the SceneScene scene = new Scene(root);// Add the Scene to the Stagestage.setScene(scene);// Set the Title of the Stagestage.setTitle("Clearing the Area of a Canvas");// Display the Stagestage.show();}}TheCanvas is a transparent area. Pixels will have colors and opacity depending on what is drawn at those pixels. Sometimes you may want to clear the whole or part of the canvas so the pixels are transparent again.
TheclearRect() method of theGraphicsContext lets you clears a specified area on theCanvas:
The following code snippet clears a rectangular area inside of the drawn rectangular:
// Clear the rectangular area from the canvasgc.clearRect(80, 80, 130, 50);
3.2 The GUI
The following GUI shows a simple example how you can delete a given area of a canvas:

4. Download Java Source Code
This was an example ofjavafx.scene.canvas
You can download the full source code of this example here:JavaFxCanvasExample.zip

Thank you!
We will contact you soon.




