Chapter: Java The Complete Reference - Introducing GUI Programming with JavaFX - Introducing JavaFX GUI Programming

Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail

Drawing Directly on a Canvas

As mentioned early on, JavaFX handles rendering tasks for you automatically, rather than you handling them manually.

Drawing Directly on a Canvas

 

As mentioned early on, JavaFX handles rendering tasks for you automatically, rather than you handling them manually. This is one of the most important ways that JavaFX improves on Swing. As you may know, in Swing or the AWT, you must call the repaint( ) method to cause a window to be repainted. Furthermore, your application needs to store the window contents, redrawing them when painting is requested. JavaFX eliminates this tedious mechanism because it keeps track of what you display in a scene and redisplays that scene as needed. This is called retained mode. With this approach, there is no need to call a method like repaint( ). Rendering is automatic.

 

One place that JavaFX’s approach to rendering is especially helpful is when displaying graphics objects, such as lines, circles, and rectangles. JavaFX’s graphics methods are found in the GraphicsContext class, which is part of java.scene.canvas. These methods can be used to draw directly on the surface of a canvas, which is encapsulated by the Canvas class in java.scene.canvas. When you draw something, such as a line, on a canvas, JavaFX automatically renders it whenever it needs to be redisplayed.

Before you can draw on a canvas, you must perform two steps. First, you must create a Canvas instance. Second, you must obtain a GraphicsContext object that refers to that canvas. You can then use the GraphicsContext to draw output on the canvas.

 

The Canvas class is derived from Node; thus it can be used as a node in a scene graph. Canvas defines two constructors. One is the default constructor, and the other is the one shown here:

 

Canvas(double width, double height)

 

Here, width and height specify the dimensions of the canvas.

To obtain a GraphicsContext that refers to a canvas, call getGraphicsContext2D( ). Here is its general form:

 

GraphicsContext getGraphicsContext2D( )

 

The graphics context for the canvas is returned.

 

GraphicsContext defines a large number of methods that draw shapes, text, and images, and support effects and transforms. If sophisticated graphics programming is in your future, you will definitely want to study its capabilities closely. For our purposes, we will use only a few of its methods, but they will give you a sense of its power. They are described here.

You can draw a line using strokeLine( ), shown here:

 

void strokeLine(double startX, double startY, double endX, double endY)

 

It draws a line from startX,startY to endX,endY, using the current stroke, which can be a solid color or some more complex style.

 

To draw a rectangle, use either strokeRect( ) or fillRect( ), shown here: void strokeRect(double topX, double topY, double width, double height) void fillRect(double topX, double topY, double width, double height)

The upper-left corner of the rectangle is at topX,topY. The width and height parameters specify its width and height. The strokeRect( ) method draws the outline of a rectangle using the current stroke, and fillRect( ) fills the rectangle with the current fill. The current fill can be as simple as a solid color or something more complex.

 

To draw an ellipse, use either strokeOval( ) or fillOval( ), shown next: void strokeOval(double topX, double topY, double width, double height) void fillOval(double topX, double topY, double width, double height)

The upper-left corner of the rectangle that bounds the ellipse is at topX,topY. The width and height parameters specify its width and height. The strokeOval( ) method draws the outline of an ellipse using the current stroke, and fillOval( ) fills the oval with the current fill. To draw a circle, pass the same value for width and height.

 

You can draw text on a canvas by using the strokeText( ) and fillText( ) methods. We will use this version of fillText( ):

 

void fillText(String str, double topX, double topY)

 

It displays str starting at the location specified by topX,topY, filling the text with the current fill. You can set the font and font size of the text being displayed by using setFont( ). You can

 

obtain the font used by the canvas by calling getFont( ). By default, the system font is used. You can create a new font by constructing a Font object. Font is packaged in javafx.scene.-text. For example, you can create a default font of a specified size by using this constructor:

 

Font(double fontSize)

 

Here, fontSize specifies the size of the font.

 

You can specify the fill and stroke using these two methods defined by Canvas: void setFill(Paint newFill)

void setStroke(Paint newStroke)

Notice that the parameter of both methods is of type Paint. This is an abstract class packaged in javafx.scene.paint. Its subclasses define fills and strokes. The one we will use is Color, which simply describes a solid color. Color defines several static fields that specify a wide array of colors, such as Color.BLUE, Color.RED, Color.GREEN, and so on.

 

The following program uses the aforementioned methods to demonstrate drawing on a canvas. It first displays a few graphic objects on the canvas. Then, each time the Change Color button is pressed, the color of three of the objects changes color. If you run the program, you will see that the shapes whose color is not changed are unaffected by the change in color of the other objects. Furthermore, if you try covering and then uncovering the window, you will see that the canvas is automatically repainted, without any other actions on the part of your program. Sample output is shown here:


// Demonstrate drawing.

 

import javafx.application.*; import javafx.scene.*; import javafx.stage.*; import javafx.scene.layout.*; import javafx.scene.control.*; import javafx.event.*;

import javafx.geometry.*; import javafx.scene.shape.*; import javafx.scene.canvas.*; import javafx.scene.paint.*; import javafx.scene.text.*;

 

public class DirectDrawDemo extends Application {

 

GraphicsContext gc;

Color[] colors = { Color.RED, Color.BLUE, Color.GREEN, Color.BLACK }; int colorIdx = 0;

 

public static void main(String[] args) {

 

// Start the JavaFX application by calling launch().

launch(args);

 

}

 

// Override the start() method.

public void start(Stage myStage) {

 

     //Give the stage a title.

     myStage.setTitle("Draw Directly to a Canvas.");

 

     //Use a FlowPane for the root node.

 

FlowPane rootNode = new FlowPane();

 

     //Center the nodes in the scene.

     rootNode.setAlignment(Pos.CENTER);

 

     //Create a scene.

 

Scene myScene = new Scene(rootNode, 450, 450);

 

     //Set the scene on the stage.

     myStage.setScene(myScene);

 

     //Create a canvas.

 

Canvas myCanvas = new Canvas(400, 400);

 

     //Get the graphics context for the canvas.

     gc = myCanvas.getGraphicsContext2D();

 

     //Create a push button.

 

Button btnChangeColor = new Button("Change Color");

 

// Handle the action events for the Change Color button.

btnChangeColor.setOnAction(new EventHandler<ActionEvent>() {

public void handle(ActionEvent ae) {

 

     //Set the stroke and fill color.

     gc.setStroke(colors[colorIdx]); gc.setFill(colors[colorIdx]);

 

     //Redraw the line, text, and filled rectangle in the

 

     //new color. This leaves the color of the other nodes

 

     //unchanged.

 

gc.strokeLine(0, 0, 200, 200);

 

gc.fillText("This is drawn on the canvas.", 60, 50);

gc.fillRect(100, 320, 300, 40);

// Change the color.

colorIdx++;

 

if(colorIdx == colors.length) colorIdx= 0;

 

}

 

});

     Draw initial output on the canvas. gc.strokeLine(0, 0, 200, 200); gc.strokeOval(100, 100, 200, 200); gc.strokeRect(0, 200, 50, 200); gc.fillOval(0, 0, 20, 20); gc.fillRect(100, 320, 300, 40);

 

     //Set the font size to 20 and draw text.

 

     gc.setFont(new Font(20));

 

gc.fillText("This is drawn on the canvas.", 60, 50);

 

     //Add the canvas and button to the scene graph.

     rootNode.getChildren().addAll(myCanvas, btnChangeColor);

 

     //Show the stage and its scene.

 

myStage.show();

 

}

 

}

 

It is important to emphasize that GraphicsContext supports many more operations than those demonstrated by the preceding program. For example, you can apply various transforms, rotations, and effects. Despite its power, its various features are easy to master and use. One other point: A canvas is transparent. Therefore, if you stack canvases, the contents of both will show. This may be useful in some situations.


Study Material, Lecturing Notes, Assignment, Reference, Wiki description explanation, brief detail


Copyright © 2018-2020 BrainKart.com; All Rights Reserved. Developed by Therithal info, Chennai.