Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to draw a continuous line with mouse on JavaFX canvas?

The code below results in a JavaFX Canvas that can be drawn on with the mouse pointer but skips some points, i.e., leaves gaps if one tries to draw a continuous line. The gapping intensifies as pointer speed increases.

What causes this behaviour and what can be done to achieve a well-connected line? (N.B., I'm looking for an answer that explicitly toggles each single pixel the pointer passes over to black, not operations such as smoothing or connecting dots, etc.)

public class DrawingSample extends Application {
    public void start(Stage stage) {
        FlowPane flowPane = new FlowPane();
        Canvas canvas = new Canvas(300, 300);
        flowPane.getChildren().add(canvas);
        GraphicsContext graphicsContext = canvas.getGraphicsContext2D();

        graphicsContext.setFill(Color.WHITE);
        graphicsContext.fillRect(0, 0, 300, 300);

        canvas.setOnMouseDragged((event) -> {
            graphicsContext.setFill(Color.BLACK);
            graphicsContext.fillRect(event.getX(), event.getY(), 1, 1);
        });

        stage.setScene(new Scene(flowPane));
        stage.show();
    }

    public static void main(String[] args) {
        launch(DrawingSample.class);
    }
}

The following figure demonstrates three lines drawn from left to right at increasing speeds as we go down.

enter image description here

like image 407
basse Avatar asked Apr 15 '17 17:04

basse


People also ask

Is canvas a control in JavaFX?

Canvas class is a part of JavaFX. Canvas class basically creates an image that can be drawn on using a set of graphics commands provided by a GraphicsContext. Canvas has a specified height and width and all the drawing operations are clipped to the bounds of the canvas.


1 Answers

This code from here.

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 * @web http://java-buddy.blogspot.com/
 */
public class JavaFX_DrawOnCanvas extends Application {

    @Override
    public void start(Stage primaryStage) {

        Canvas canvas = new Canvas(400, 400);
        final GraphicsContext graphicsContext = canvas.getGraphicsContext2D();
        initDraw(graphicsContext);

        canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, 
                new EventHandler<MouseEvent>(){

            @Override
            public void handle(MouseEvent event) {
                graphicsContext.beginPath();
                graphicsContext.moveTo(event.getX(), event.getY());
                graphicsContext.stroke();
            }
        });

        canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, 
                new EventHandler<MouseEvent>(){

            @Override
            public void handle(MouseEvent event) {
                graphicsContext.lineTo(event.getX(), event.getY());
                graphicsContext.stroke();
            }
        });

        canvas.addEventHandler(MouseEvent.MOUSE_RELEASED, 
                new EventHandler<MouseEvent>(){

            @Override
            public void handle(MouseEvent event) {

            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(canvas);
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setTitle("java-buddy.blogspot.com");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

    private void initDraw(GraphicsContext gc){
        double canvasWidth = gc.getCanvas().getWidth();
        double canvasHeight = gc.getCanvas().getHeight();

        gc.setFill(Color.LIGHTGRAY);
        gc.setStroke(Color.BLACK);
        gc.setLineWidth(5);

        gc.fill();
        gc.strokeRect(
                0,              //x of the upper left corner
                0,              //y of the upper left corner
                canvasWidth,    //width of the rectangle
                canvasHeight);  //height of the rectangle

        gc.setFill(Color.RED);
        gc.setStroke(Color.BLUE);
        gc.setLineWidth(1);

    }

}
like image 147
Sedrick Avatar answered Oct 01 '22 05:10

Sedrick