Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Rendering a canvas on a background thread is very slow when updateing the scene graph.

FXitJun 28 2015 — edited Sep 8 2015

Hi *,

I have a lot of data to draw onto a canvas. Thefore I would like to do this on a background thread. In my example I create two canvas objects and while the first one is rendered I replace it with the other one.

Anyway, while the painting seems to be fast, when reattaching the canvas to the scene graph the UI seems to freeze and is getting slow.

Does anyone have an idea how to improve this?

Many thanks in advance.

import javafx.application.Application;

import javafx.concurrent.Task;

import javafx.concurrent.WorkerStateEvent;

import javafx.event.ActionEvent;

import javafx.event.EventHandler;

import javafx.scene.Scene;

import javafx.scene.canvas.Canvas;

import javafx.scene.canvas.GraphicsContext;

import javafx.scene.control.Button;

import javafx.scene.layout.StackPane;

import javafx.scene.layout.VBox;

import javafx.scene.paint.Color;

import javafx.stage.Stage;

public class DrawInBackground extends Application {

  Canvas cv = new Canvas(1000, 1000);

  GraphicsContext gc;

  Canvas dummer = new Canvas(1000, 1000);

  @Override

  public void start(Stage stage) throws Exception {

  gc = cv.getGraphicsContext2D();

  VBox v = new VBox();

  Button b = new Button("draw");

  StackPane stackPane = new StackPane();

  stackPane.getChildren().add(cv);

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

  @Override

  public void handle(ActionEvent event) {

  stackPane.getChildren().clear();

  stackPane.getChildren().add(dummer);

  CanvasPainter cvp = new CanvasPainter(gc);

  cvp.setOnSucceeded(new EventHandler<WorkerStateEvent>() {

  @Override

  public void handle(WorkerStateEvent event) {

  stackPane.getChildren().clear();

  stackPane.getChildren().add(cv);

  System.out.println(System.currentTimeMillis() + " transfer done\n");

  }

  });

  Thread t = new Thread(cvp);

  t.setDaemon(true);

  t.start();

  }

  });

  v.getChildren().addAll(b, stackPane);

  stage.setScene(new Scene(v));

  stage.setTitle("Draw on background thread.");

  stage.show();

  }

  public static void main(String[] args) {

  launch(args);

  }

  public class CanvasPainter extends Task<Canvas> {

  GraphicsContext gc;

  public CanvasPainter(GraphicsContext gc) {

  this.gc = gc;

  }

  @Override

  protected Canvas call() throws Exception {

  System.out.println(System.currentTimeMillis() + " Painting");

  gc.clearRect(0, 0, 1000, 1000);

  gc.setStroke(Color.RED);

  for (int i = 0; i < 2000000; i++) {

  gc.strokeLine(Math.random() * 1000, Math.random() * 1000, Math.random() * 1000, Math.random() * 1000);

  }

  System.out.println(System.currentTimeMillis() + " done");

  return null;

  }

  }

}

Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Oct 6 2015
Added on Jun 28 2015
1 comment
918 views