Drawing Squares and Circles in JavaFX

JavaFX Shapes
Drawing shapes in JavaFX is easy.

JavaFX is all about graphics and drawing. Sure JavaFX can do great layouts, but if you need to visualize results, add images to layouts, or display data, JavaFX has all the tools you’ll need. Even games are written using JavaFX.

If you don’t know where to start learning JavaFX graphics capabilities, start with this tutorial. This tutorial explains how to draw JavaFX circles and squares after laying out your JavaFX UI using Scene Builder. It may not be glamorous, but it is a beginning.

Note: If you have never created a JavaFX application before, I suggest you look at this detailed JavaFX tutorial first, or my overview of JavaFX, just to get a feel for how to create JavaFX projects in Eclipse and how to create FXML using Scene Builder.

Another Note: If you want to see what this example looks like without FXML, check out my other JavaFX Squares and Circles Tutorial.

To start out, create a standard JavaFX project in Eclipse. You should have already installed the e(fx)clipse plugin. I called my project circles-and-squares, and used the package name com.whatisjavafx.

JavafX Circles and Squares
Here’s the basic JavaFX 8 project.

Your JavaFX project should look like the above image in Eclipse’s Package Explorer.

Next, open up Scene Builder. You’ll want a Group for your root object—meaning, drag a Group to the center first. Groups are a bit tricky to find. The JavaFX Group is under “Miscellaneous” on the left. The group takes on the size of the nodes it contains, so it is small for now.

Add a Canvas to your group. Canvas is also found in the Miscellaneous section on the left. You might find it challenging to drag a JavaFX Canvas node onto that tiny Group in the central preview window. Instead, drag it onto the Group in the Hierarchy on the bottom left. You’ll find that drop-target to be a bit easier to hit.

Your Hierarchy in Scene Builder should now look like the following.

SceneBuilder Hierarchy
Sometimes dragging nodes to the Hierarchy is easier than dragging them to the preview.

Sometimes, it is just easier to drag nodes to their proper location in the Hierarchy when you can’t seem to drag them to the right place in the central preview window.

Select your Canvas in the Hierarchy and then in the Layout on the right-hand side, set the width to 600 and the height to 400.

SceneBuilder Inspector Layout
Set the Canvas width to 600 and the height to 400.

At this point, you might be tempted to grab the JavaFX Circle and JavaFX Rectangle from the shapes library on the left and drag them onto the preview window. However, if you check the Hierarchy, you’ll find that you are placing nodes directly on the Group, and not in the Canvas. Our goal is to draw the circle and square programmatically on the Canvas, so dragging those shapes to your group would not accomplish our goal.

Now your Hierarchy consists of a JavaFX Group and a JavaFX Canvas. I specifically mention JavaFX, because back in olden days AWT had a Canvas, too. But, this is not your father’s Canvas. (Sorry. Couldn’t resist.)

Next, we need to configure our Scene Builder project for the Controller to use.

Select your Canvas, and give it a fx:id of mycanvas. You enter the fx:id under the code section on the right-hand side of Scene Builder.

Next, under Controller on the left, enter com.whatisjavafx.ShapeController for your Controller class name. Remember, you need to use fully qualified names that include the Java package of the controller class name or you’ll have a headache trying to figure out why your JavaFX application can’t load your controller.

JavaFX Controller Class
Set your Controller class name using the full package name of the Controller.

You are ready to save your FXML and create your Controller.

Save your Scene Builder creation in the same directory as your Main.java file. I saved mine as circle-and-square.fxml, but you can call yours whatever you like. Just remember the name when you write your root loader code! Remember to refresh your JavaFX project view in Eclipse, so the FXML file is visible.

Your FXML file should look something like the following.

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.Group?>
<?import javafx.scene.canvas.Canvas?>


<Group 
xmlns="http://javafx.com/javafx/8.0.65" 
xmlns:fx="http://javafx.com/fxml/1" 
fx:controller="com.whatisjavafx.ShapeController">
  <children>
    <Canvas 
    fx:id="mycanvas" 
    height="400.0" 
    width="600.0" />
  </children>
</Group>

 

Now let’s create a Controller for your JavaFX project. I always like to start by copying a skeletal Controller from Scene Builder. You can see that by selecting View->Show Sample Controller Skeleton. It’s just a nice place to start when creating a new JavaFX Controller class.

In the same package as your Main class and your FXML file, create a class named ShapeController.

Give the Controller the following code.

/**
 * Sample Skeleton for 
 * 'circle-and-square.fxml' 
 * Controller Class
 */

package com.whatisjavafx;

import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.paint.Color;

public class ShapeController {

  // Value injected by FXMLLoader
    @FXML // fx:id="mycanvas"
    private Canvas mycanvas;

    // This method is called by the 
    // FXMLLoader when initialization 
    // is complete
    @FXML
    void initialize() {
      GraphicsContext gc = 
          mycanvas.getGraphicsContext2D();
      draw( gc );
    }
    
    /**
     * Drawing the shapes
     */
    private void draw(GraphicsContext gc) {
      gc.setFill(Color.GREEN);
      gc.fillOval(50, 100, 200, 200);
      gc.setFill(Color.RED);
      gc.fillRect(300, 100, 200, 200);
    }
}

 

JavaFX takes care of the dependency injection required to hook the @FXML annotated items up to objects in your UI. In this case, a reference to the JavaFX Canvas object named mycanvas is injected into the controller. Also, the initialize() method is hooked up to allow you to do additional configuration and customization programmatically to your UI before the user sees it.

All 2D drawing in JavaFX is done using a GraphicsContext. To draw on a Canvas, you need to get its GraphicsContext, and then use the GraphicsContext to draw on the Canvas. In the example above, we pass the Canvas‘s GraphicsContext to a method named draw() to do the actual drawing.

In the draw() method, we set the fill color to green. Fill means just that. Fill is the color the shape will be filled with.

Once the fill color is set, we draw the oval shape. Remember that circles are just nicely proportioned circles, so we can make an oval look that is a circle. The first two numbers passed in to the fillOval() method are the coordinates to place the oval (or in our case, circle) at.

All coordinates in the JavaFX GraphicsContext start at the upper left hand corner. So, (0,0) is the top left corner of your Canvas.

The third and forth parameters of the fillOval() call are the width and the height of the drawn object. So all together it is …

gc.fillOval( x, y, width, height);

Not too surprisingly, the fillRect() method works exactly like the fillOval() method, except that it produces a rectangle or square depending on the parameters you’ve entered.

Now modify your Main class to read as follows.

package com.whatisjavafx;
	
import java.net.URL;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {
	@Override
	public void start(Stage stage) {
	  try {
      URL url = 
          getClass()
          .getResource("circle-and-square.fxml");
      Group root = FXMLLoader.load(url);

      Scene scene = new Scene(root);
      stage.setScene(scene);
      stage
      .setTitle("JavaFX Circle and Square");
      stage.show();
    } catch(Exception e) {
      e.printStackTrace();
    }
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

 

 

Nothing too fancy happens in the Main class. You load your FXML file and assign it to a Group. You add the Group object to a Scene, and the Scene ends up added the primary Stage.

Suggested JavaFX Drawing Practice

Try these tasks to get a better understanding of drawing shapes in JavaFX. You might find the javadoc for GraphicsContext helpful.

  1. Draw your initials using squares and circles.
  2. Draw a simple picture of your favorite Minecraft MOB.
  3. Draw a self portrait.

Leave a Reply

Your email address will not be published. Required fields are marked *