import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.scene.Group; import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.WritableImage; import javafx.scene.image.WritablePixelFormat; import javafx.stage.Stage; public class CanvasErrors extends Application { public static void main(String[] args) throws Exception { launch(args); } public void start(final Stage stage) throws Exception { // create a simple surface wrapper around a canvas. final Canvas canvas = new Canvas(1800, 600); final Surface surface = new Surface(canvas); // layout the scene. Scene scene = new Scene(new Group(canvas)); stage.setResizable(false); stage.setScene(scene); stage.show(); // update the surface every pulse. AnimationTimer timer = new AnimationTimer() { int t = 0; @Override public void handle(long now) { t++; System.out.print((t % 60 == 0) ? "." : ""); surface.clear(0x27, 0x2b, 0x38); surface.update(); } }; timer.start(); } class Surface { private int width; private int height; private GraphicsContext context; private byte[] buffer; private WritablePixelFormat format = WritablePixelFormat.getByteBgraPreInstance(); private WritableImage imageBuffer; Surface(Canvas canvas) { width = (int) canvas.getWidth(); height = (int) canvas.getHeight(); context = canvas.getGraphicsContext2D(); buffer = new byte[width * 4 * height]; imageBuffer = new WritableImage(width, height); } void clear(int red, int green, int blue) { int idx = 0; for (int y = 0; y < height; y++) { for(int x = 0; x < width; x++) { buffer[idx++] = (byte) blue; buffer[idx++] = (byte) green; buffer[idx++] = (byte) red; buffer[idx++] = (byte) 0xFF; } } } void update() { // should work but you get java.lang.NullPointerException at com.sun.prism.impl.BaseGraphics.drawTextureVO(BaseGraphics.java:418) when using -server VM. context.getPixelWriter().setPixels(0, 0, width, height, format, buffer, 0, width * 4); } // void update() { // workaround - this works for some reason I don't really understand. // imageBuffer.getPixelWriter().setPixels(0, 0, width, height, format, buffer, 0, width * 4); // context.drawImage(imageBuffer, 0, 0); // } } }