如何在javafx中绘制一条直线,当用户移动鼠标时它会自动更新?

时间:2017-02-15 19:32:21

标签: java user-interface javafx

所以,我知道如何做自由手线,但我想要一条直线,所以当用户点击一个点到用户释放鼠标的点时,当用户拖动鼠标时,终点应该用鼠标移动即类似于在绘画应用程序中绘制直线。

目前正在使用此代码:

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);

    }

}

如何修改鼠标拖动事件以绘制直线而不是自由手?

2 个答案:

答案 0 :(得分:2)

一般来说,我同意评论 - 使用Line更容易做到这一点。 但是使用canvas可以达到同样的目的:

public class JavaFX_DrawOnCanvas extends Application {

    private Pair<Double, Double> initialTouch;
    private Canvas layer = new Canvas();

    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();

        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) {
                        Canvas newLayer = new Canvas(400, 400);
                        GraphicsContext context = newLayer.getGraphicsContext2D();
                        initDraw(context);

                        layer = newLayer;
                        root.getChildren().add(0, newLayer);
                        initialTouch = new Pair<>(event.getSceneX(), event.getSceneY());
                    }
                });

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

                    @Override
                    public void handle(MouseEvent event) {
                        GraphicsContext context = layer.getGraphicsContext2D();
                        context.clearRect(0, 0, layer.getWidth(), layer.getHeight());
                        context.strokeLine(initialTouch.getKey(), initialTouch.getValue(), event.getSceneX(), event.getSceneY());
                    }
                });

        root.getChildren().add(canvas);
        Scene scene = new Scene(root, 400, 400);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    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);

    }

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

}

因此,基本上您需要为每个新行创建单独的图层并使用strokeLine method。请注意,必须在0索引处将新添加的层添加到根子项,因为否则主画布的事件处理程序将停止进程事件。

答案 1 :(得分:0)

每次拖动鼠标时都必须添加新行。你可以尝试这个演示,

public class JavaFX_DrawOnCanvas extends Application {

    private double from_x = 0;
    private double from_y = 0;
    private double to_x = 0;
    private double to_y = 0;
    private int line_no = 1;

    @Override
    public void start(Stage primaryStage) {

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

        canvas.setOnMousePressed((event) -> this.setFromPos(event));
        canvas.setOnMouseDragged((event) -> {
            root.getChildren().remove(0);
            final Canvas temp_canvas = new Canvas(400, 400);
            final GraphicsContext gc = temp_canvas.getGraphicsContext2D();
            this.setToPos(event);
            this.drawLine(gc);
            root.getChildren().add(0,temp_canvas);
        });         
        canvas.setOnMouseReleased((event) -> {
            final Canvas new_line = new Canvas(400, 400);
            final GraphicsContext gc = new_line.getGraphicsContext2D();
            this.setToPos(event);
            this.drawLine(gc);
            //final new stright line
            root.getChildren().add(line_no++,new_line);             
        });

        root.getChildren().addAll( new Canvas(), 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 drawLine(GraphicsContext gc) {
        gc.setFill(Color.RED);
        gc.setStroke(Color.BLUE);
        gc.setLineWidth(1);
        gc.strokeLine(from_x, from_y, to_x, to_y);      
    }

    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
    }

    private void setFromPos(MouseEvent event) {
        this.from_x = event.getSceneX();
        this.from_y = event.getSceneY();
    }

    private void setToPos(MouseEvent event) {
        this.to_x = event.getSceneX();
        this.to_y = event.getSceneY();
    }   
}