【问题标题】:JavaFx custom grid painting issueJavaFx 自定义网格绘制问题
【发布时间】:2014-11-18 12:30:03
【问题描述】:

我正在使用下面的代码在 JavaFX 画布上绘制垂直线。不知何故,最后一行(最后 10%)的不透明度较低。我没有更改任何选项(对 gc 的转换/影响)。我附上截图供参考,有什么想法吗?

public class ChartPane extends StackPane {

    Canvas canvas;

    public ChartPane() {

        setStyle("-fx-background-color: white;");
        canvas = new Canvas(getWidth(), getHeight()); 
        getChildren().add(canvas);

        widthProperty().addListener(new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                canvas.setWidth(newValue.intValue());
            }
        });

        heightProperty().addListener(new ChangeListener<Number>() {

            @Override
            public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                canvas.setHeight(newValue.intValue());
            }
        });
    }

    @Override
    protected void layoutChildren() {
        super.layoutChildren(); 

        GraphicsContext gc = canvas.getGraphicsContext2D(); 
        gc.save();
        gc.clearRect(0, 0, getWidth(), getHeight());

        System.out.println(getWidth() + ", " + getHeight());

        // vertical lines
        gc.setStroke(Color.BLUE);
        gc.setLineWidth(0.1);
        gc.beginPath();
        for(int i = 0 ; i < getWidth() ; i+=30){
            gc.moveTo(i, 0);
            gc.lineTo(i, getHeight() - (getHeight()%30));            
            gc.stroke();
        }        

        // horizontal lines
        gc.beginPath();
        gc.setStroke(Color.RED);
        for(int i = 30 ; i < getHeight() ; i+=30){
            gc.moveTo(30, i);
            gc.lineTo(getWidth(), i);              
            gc.stroke();   
        }        
        //gc.restore();
    }    
}

【问题讨论】:

  • 查看将 Canvas 添加为子元素的位置会很有帮助。 Canvas 的任何父元素都可以引入我们在屏幕截图中看到的效果..
  • 已编辑问题,请检查。也可以将 gc.stroke() 放在笔画之外,这样我就可以准备路径并只调用一次 stroke() 吗?现在它确实绘制但不是在 setStroke() 方法中指定的颜色。

标签: javafx javafx-8 graphicscontext


【解决方案1】:

我已将代码重写为strokeLine,它似乎可以工作:

@Override
    protected void layoutChildren() {
        super.layoutChildren(); 

        GraphicsContext gc = canvas.getGraphicsContext2D(); 
        gc.clearRect(0, 0, getWidth(), getHeight());

        // vertical lines
        gc.setStroke(Color.BLUE);
        for(int i = 0 ; i < getWidth() ; i+=30){
            gc.strokeLine(i, 0, i, getHeight() - (getHeight()%30));
        }        

        // horizontal lines
        gc.setStroke(Color.RED);
        for(int i = 30 ; i < getHeight() ; i+=30){
            gc.strokeLine(30, i, getWidth(), i);
        }        
    }

仅供参考,我使用 Canvas 编写了一个可调整大小的网格:https://gist.github.com/eckig/176b7c2a10048bb71f43


更新 我从链接的示例中复制以使用锐线进行绘制并显示在何处编辑线宽:

@Override
protected void layoutChildren() {
    super.layoutChildren();

    final int top = (int) snappedTopInset();
    final int right = (int) snappedRightInset();
    final int bottom = (int) snappedBottomInset();
    final int left = (int) snappedLeftInset();
    final int width = (int) getWidth() - left - right;
    final int height = (int) getHeight() - top - bottom;
    final double spacing = 30;

    GraphicsContext gc = canvas.getGraphicsContext2D();
    gc.clearRect(0, 0, getWidth(), getHeight());
    gc.setLineWidth(1); // change the line width

    final int hLineCount = (int) Math.floor((height + 1) / spacing);
    final int vLineCount = (int) Math.floor((width + 1) / spacing);

    gc.setStroke(Color.RED);
    for (int i = 0; i < hLineCount; i++) {
        gc.strokeLine(0, snap((i + 1) * spacing), width, snap((i + 1) * spacing));
    }

    gc.setStroke(Color.BLUE);
    for (int i = 0; i < vLineCount; i++) {
        gc.strokeLine(snap((i + 1) * spacing), 0, snap((i + 1) * spacing), height);
    }
}

private double snap(double y) {
    return ((int) y) + 0.5;
}

【讨论】:

  • 嘿,这画线好了...谢谢。但我似乎无法设置线宽,我的意思是如果我在 strokeLine 之前添加 gc.setLineWidth() 那么它不会绘制颜色!你也可以帮忙吗?
  • 好吧,既然你用strokeLine(x1,y1,x2,y2)画一条直线,那么线的宽度是由坐标的差异组成的(x2-x1 = 水平线宽,y2-y1 = 垂直线宽)
  • 线宽指的是strokeWidth,如何用strokeLike方法画出细线?有什么线索吗?
  • 在这里找到了线条锐度的解决方案:dlemmermann.wordpress.com/2014/04/10/…
  • 这条线实际上是 1px 细,但看起来很模糊。答案仍然与我之前的评论相同。但为了澄清这一点,我将编辑我的答案..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2021-03-04
  • 2020-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
相关资源
最近更新 更多