Javafx canvas draw only moving object without redraw the background


I am drawing inside JavaFx Canvas the program draw many different shapes and one of them represent a position marker(Oval) in some situation its position must be updated every 1 second and this is OK to remove several traces of marker I have to redraw again and this slow the program the question how can I redraw only the current marker removing its traces without drawing all shapes?? much like swing repaint() .

import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;

public class  DrawChart    { 

private Timeline timelinePosition;
private Canvas canvas;
private GraphicsContex graphicsContex;

public void start()  {

  canvas = new Canvas();
  graphicsContex = canvas.getGraphicsContext2D();


public void drawManyShapes()  {

     draw many shapes .......

public void drawPositionMarker()  {

        EventHandler eventHandler = new EventHandler<ActionEvent>() {
            public void handle(ActionEvent t) {

                graphicsContex.strokeOval(posi_x , posi_y,  width , hight );    


        Duration duration = Duration.millis(1000);

        timelinePosition = new Timeline();
        KeyFrame keyPosition = new KeyFrame(duration, drawPosition , null, null);


public void someStateMonitor()  {

  if(state == true);
  if(state == false) timelinePosition.stop();


7/20/2014 1:27:28 PM

Accepted Answer

You can add layers of canvases. Or you can save a rectangle under your shape and redraw that after.

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.text.Font;
import javafx.stage.Stage;

public class LayeredCanvas extends Application {

    public void start(Stage primaryStage) {
        Canvas layer1 = new Canvas(700, 300);
        Canvas layer2 = new Canvas(700, 300);
        GraphicsContext gc1 = layer1.getGraphicsContext2D();
        GraphicsContext gc2 = layer2.getGraphicsContext2D();

        gc1.setFont(new Font("Comic sans MS", 100));
        gc1.fillText("BACKGROUND", 0, 100);
        gc1.fillText("LAYER", 0, 200);
        gc1.setFont(new Font(30));
        gc1.fillText("Hold a key", 0, 270);

        Pane root = new Pane(layer1, layer2);
        Scene scene = new Scene(root);


        scene.setOnKeyPressed((evt) -> {
            gc2.clearRect(0, 0, layer2.getWidth(), layer2.getHeight());
            gc2.fillOval(Math.random() * layer2.getWidth(), Math.random() * layer2.getHeight(), 20, 30);

    public static void main(String[] args) {

7/20/2014 10:34:29 PM

I have encountered this issue as well (for me rectangle) and I made a rectangle class, you could to the same but with ovals. The example is just to give you a idea

class Rectangle {
//x position
int x;
//y position
int y;
//size for width
int xSize;
//size for height
int ySize;
//to draw on the canvas
GraphicsContext graphics;

//used to create a rectangle object
public Rectangle(GraphicsContext graphics, int x, int y, int xSize, int ySize) {
    //sets fields used for the rectangle
    this.x = x;
    this.y = y;
    this.xSize = xSize;
    this.ySize = ySize; = graphics;

        graphics.fillRect(x, y, xSize, ySize);

    //used to get rid of rectangles
public void delete(Rectangle rectangle) {
    //erase the rectangle
    (, rectangle.y, rectangle.xSize, rectangle.ySize);

    //erase its fields
    rectangle.x = -1;
    rectangle.y = -1;
    rectangle.xSize = -1;
    rectangle.ySize = -1;

//will redraw the rectangle
public void reDraw(Rectangle rectangle) {
    (, rectangle.y, rectangle.xSize, rectangle.ySize);

//will move the rectangle
public void move(Rectangle rectangle, int x, int y) {
    (, rectangle.y, rectangle.xSize+1, rectangle.ySize+1);

        (, y, rectangle.xSize, rectangle.ySize);
    //redifine the fields
    this.x = x;
    this.y = y; } }

You could add other fields as well.

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow