The source file has grown by some 53 lines so what have we gained:
- A more colourful palette, the values of which are pre-computed for each possible iteration value:
palette = new int[MAX_ITER]; for (int i = 0; i<palette.length; i++) palette[i] = java.awt.Color.HSBtoRGB(i/256f, 1, i/(i+8f));
- The ability to zoom in and out of the set based on mouse location:
imageView.addEventHandler(MouseEvent.MOUSE_CLICKED, (mouseEvent) -> { if(mouseEvent.getButton() == javafx.scene.input.MouseButton.PRIMARY) { ZOOM = ZOOM * 0.5; } if(mouseEvent.getButton() == javafx.scene.input.MouseButton.SECONDARY) { ZOOM = ZOOM / 0.5; } offsetX = offsetX+ ZOOM *(mouseEvent.getX()-(width/2)); offsetY = offsetY+ ZOOM *(mouseEvent.getY()-(height/2)); System.out.printf("offset (x/y): (%f / %f)", offsetX, offsetY); calculate(); });
- The method which computes the Mandelbrot set is run in a separate thread to the application. The result of which is then displayed in the imageView:
private void calculate() { if (!calculationInProgress.getAndSet(true)) { System.out.println("calculate spawned"); Task calculate = createWorker(); new Thread(calculate).start(); } else { System.out.println("someone beat us to it!"); } } private Task createWorker() { return new Task() { @Override protected Object call() throws Exception { Platform.runLater(() -> { currentImageView.setImage(createMandelbrotImage()); calculationInProgress.set(false); }); return true; } }; }
What’s left to do?
- Refine the colour palette used, produce one with more subtle variation.
- Implement a panning function with the mouse
- Improve the speed of rendering by using additional threads to produce an inter-laced image.
- Sort out the ugly pixelation encountered after several zooms

Full source code available here
Leave a Reply