【问题标题】:how to draw a straight line in javafx that updates itself when the user moves the mouse?如何在用户移动鼠标时在javafx中绘制一条更新自身的直线?
【发布时间】:2017-07-04 15:36:19
【问题描述】:

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

目前正在使用此代码:

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

    }

}

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

【问题讨论】:

  • 为什么要使用画布?使用场景图上的线条通常更容易实现此类事情。
  • 只是一个问题,你别无选择,只能使用Canvas ?

标签: java user-interface javafx


【解决方案1】:

一般来说,我同意 cmets - 使用Line 更容易做到这一点。 但是使用画布,您可以像这样实现相同的效果:

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 索引处,否则主画布的事件处理程序将停止处理事件。

【讨论】:

  • 没有 Canvas 的 Line 更容易使用?我想看看这样的例子。使用 Group 而不是 Canvas,只需添加 Line。
  • 只是想补充,没有批评的意思。我很想看看没有 Canvas 的情况。
猜你喜欢
  • 1970-01-01
  • 2016-10-26
  • 2012-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-11
相关资源
最近更新 更多