When I initially started out working with the Canvas API I noticed that the results of my rendering code were somewhat blurry and even worse, inconsistent. Some lines were blurry, others sharp. Coming from Swing it took me some time to realize that this was caused by the coordinate system of JavaFX, which allows for double precision rendering.
To solve this problem all that is needed is to use coordinates “in the middle”. So in my code you now find a lot of methods called snapXZY() (similar methods can be found in the JavaFX code itself), which first casts the given coordinate to an integer and then adds .5 to it. The following screenshot shows the difference when using this approach.

Bildschirmfoto 2014-04-10 um 11.59.49
The code below was used for this example:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
* Tip 2: How to render sharp lines in a canvas.
*/
public class Tip2DrawingSharpLinesInCanvas extends
Application {

class MyCanvas extends Canvas {

public MyCanvas(boolean drawSharpLines) {

setWidth(150);
setHeight(150);

double w = getWidth();
double h = getHeight();

GraphicsContext gc = getGraphicsContext2D();
gc.clearRect(0, 0, w, h);

gc.setStroke(Color.GRAY);
gc.strokeRect(0, 0, w, h);

for (double y = 20; y <= h - 20; y += 10) { if (drawSharpLines) { // Snap the y coordinate gc.strokeLine(10, snap(y), w - 10, snap(y)); } else { gc.strokeLine(10, y, w - 10, y); } } } private double snap(double y) { return ((int) y) + .5; } } @Override public void start(Stage stage) throws Exception { MyCanvas canvasBlurry = new MyCanvas(false); MyCanvas canvasSharp = new MyCanvas(true); Label labelBlurry = new Label("Blurry"); Label labelSharp = new Label("Sharp"); VBox.setMargin(canvasBlurry, new Insets(10)); VBox.setMargin(canvasSharp, new Insets(10)); VBox.setMargin(labelBlurry, new Insets(10, 10, 0, 10)); VBox.setMargin(labelSharp, new Insets(10, 10, 0, 10)); VBox box = new VBox(); box.getChildren().add(labelBlurry); box.getChildren().add(canvasBlurry); box.getChildren().add(labelSharp); box.getChildren().add(canvasSharp); stage.setScene(new Scene(box)); stage.setTitle("Tip 2: Sharp Lines in Canvas"); stage.show(); } public static void main(String[] args) { launch(args); } } [/code]