提问者:小点点

在javafx中将填充应用于画布


我必须在javafx画布中一个点一个点地画一条窦曲线,并将它们连接起来。但是,当您可以更改线条的宽度时,有时会因为线条靠近边框而被切割宽度。那么是否有可能像做一个填充或边框来避免这种情况呢?有可能像操纵坐标一样,但我不想这样做,因为我认为应该有更好的解决方案。画布图片

编辑:

这是在javafx项目中重现它的代码示例

public class HelloApplication extends Application {

    @Override
    public void start(Stage stage) throws IOException {
        Canvas c = new Canvas(715,495);
        GraphicsContext gc = c.getGraphicsContext2D();
        VBox v = new VBox();
        Pane p = new Pane();
        p.getChildren().add(c);


        Button b1 = new Button("Draw Sinus at Canvas");
        b1.setOnAction(e -> drawSinus(c, gc));

        v.getChildren().addAll(b1, p);
        Scene sc = new Scene(v);
        stage.setScene(sc);
        stage.setTitle("Drawing Lines - Dynamically at Runtime");
        stage.show();
    }


    private void drawSinus(Canvas c, GraphicsContext gc) {
        double height = c.getHeight();
        double width = c.getWidth();
        double multiplier = (2 * Math.PI)/width;
        double x1 = 0;
        double y1 = height/2;
        double x2 = 1;
        double y2 = 0;
        int i = 0;
        gc.setStroke(Color.BLACK);
        gc.setLineWidth(10);

        while(i < width) {
            y2 = (height/2) - ((height/2) * Math.sin(x2 * multiplier));
            gc.strokeLine(x1,y1,x2,y2);
            x1 = x2;
            y1 = y2;
            x2++;
            i++;
        }
    }

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

共2个答案

匿名用户

在您正在绘制的区域周围添加一些填充的一种方法是在不更改您使用的坐标的情况下,向图形上下文添加转换。基本上,您首先缩放绘图区域以使其按比例(wed-2*填充)/wide(hethy-2*填充)/高变小(因此实际绘图区域在每个维度上减少一个大小2*填充)。然后在每个维度上通过填充进行翻译。这看起来像:

public class HelloApplication extends Application {

    @Override
    public void start(Stage stage) throws IOException {
        Canvas c = new Canvas(715,495);
        GraphicsContext gc = c.getGraphicsContext2D();
        VBox v = new VBox();
        Pane p = new Pane();
        p.getChildren().add(c);


        Button b1 = new Button("Draw Sinus at Canvas");
        b1.setOnAction(e -> drawSinus(c, gc, 10));

        v.getChildren().addAll(b1, p);
        Scene sc = new Scene(v);
        stage.setScene(sc);
        stage.setTitle("Drawing Lines - Dynamically at Runtime");
        stage.show();
    }


    private void drawSinus(Canvas c, GraphicsContext gc, double padding) {


        double height = c.getHeight();
        double width = c.getWidth();

        Affine transform = new Affine(Transform.scale((width-2*padding)/width, (height-2*padding)/height));
        transform.appendTranslation(padding, padding);
        gc.setTransform(transform);

        double multiplier = (2 * Math.PI)/width;
        double x1 = 0;
        double y1 = height/2;
        double x2 = 1;
        double y2 = 0;
        int i = 0;
        gc.setStroke(Color.BLACK);
        gc.setLineWidth(10);

        while(i < width) {
            y2 = (height/2) - ((height/2) * Math.sin(x2 * multiplier));
            gc.strokeLine(x1,y1,x2,y2);
            x1 = x2;
            y1 = y2;
            x2++;
            i++;
        }

        // reset transform; may not be necessary depending on actual use case
        gc.setTransform(new Affine());
    }

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

如果要(例如)清除整个画布(包括填充区域),则需要重置转换。

匿名用户

将画布放置为StackPane并在StackPane上设置填充。

Canvas canvas = new Canvas(715,495);
StackPane stackPane = new StackPane(canvas);
stackPane.setPadding(new Insets(5));

根据需要调整画布和填充大小。