【问题标题】:How to draw a crisp, opaque hairline in JavaFX 2.2?如何在 JavaFX 2.2 中绘制清晰、不透明的细线?
【发布时间】:2012-08-06 20:16:21
【问题描述】:

在 JavaFX 2.2 中绘制清晰、不透明的细线的最佳方法是什么?

文档说,strokeWidth0.0d 将是一条细线,但它根本不可见。值> 0.0d and <1.0d 显示的线条非常好,但也没有表现出不透明的行为。当一条线切割另一条线时,相交点比线的其余部分轻(我希望这种行为来自具有一定透明度的线)。最后,1.0d 绘制了一条宽度为几个像素的白线。

这是我的测试代码:

LineBuilder.create().startX(i*gridSize).startY(0).endX(i*gridSize).endY(height).smooth(false).stroke(Color.WHITE).strokeWidth(0.5d).fill(Color.WHITE).build();           

【问题讨论】:

    标签: java javafx javafx-2


    【解决方案1】:

    您可以使用Region 子类,例如将Pane 用于您的Parent,并将snapToPixel 设置为true。

    另外,请参阅坐标系上的Node 文档。

    在设备像素级别,整数坐标映射到角落 像素和像素中心之间出现裂缝 整数像素位置之间的中点。因为所有坐标 值用浮点数指定,坐标可以 精确指向这些角(当浮点值有 精确的整数值)或像素上的任何位置。例如,一个 (0.5, 0.5) 的坐标将指向左上角的中心 舞台上的像素。类似地,一个位于 (0, 0) 的矩形,其尺寸为 10 x 10 将跨越左上角的左上角 舞台上的像素到舞台上第 10 个像素的右下角 第 10 条扫描线。里面最后一个像素的像素中心 矩形将位于坐标 (9.5, 9.5)。

    另请参阅Shape 文档:

    大多数节点往往只应用整数转换,并且 它们通常也使用整数坐标定义。为了 在这种常见情况下,具有直线边缘的形状填充往往是 清晰,因为它们与落在像素之间的裂缝对齐 整数设备坐标,因此往往自然覆盖整个 像素。另一方面,抚摸这些相同的形状通常会导致 到模糊的轮廓,因为默认的描边属性同时指定了 默认笔画宽度是 1.0 坐标,通常映射到 正好 1 个设备像素,并且笔划应该跨越 形状的边界,在边界的两侧下降一半。自从 许多常见形状的边框往往直接落在整数上 坐标和那些整数坐标通常精确映射到 整数设备位置,边界往往会导致 50% 的覆盖率 在边界两侧的像素行和列上 形状而不是 100% 覆盖一个或另一个。因此,填充可能 通常是清脆的,但笔画通常是模糊的。

    避免这些模糊轮廓的两种常见解决方案是使用更宽的 完全覆盖更多像素的笔画 - 通常是笔画宽度 如果没有有效的比例变换,2.0 的 2.0 将实现这一点 - 或指定 StrokeType.INSIDE 或 StrokeType.OUTSIDE 笔划样式 - 将默认的单个单位笔划偏向 内部或外部的完整像素行或列之一 形状的边框。

    因此,如果您将节点留在没有 snapToPixel 的组或区域中,您可以按照 Shape 文档中的上述说明进行操作。

    这里是一些示例代码:

    import javafx.application.Application;
    import javafx.scene.*;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Line;
    import javafx.scene.shape.LineBuilder;
    import javafx.scene.shape.StrokeType;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    
    /** http://stackoverflow.com/questions/11886230/how-to-draw-a-crisp-opaque-hairline-in-javafx-2-2 */
    public class LineWidths extends Application {
      public static void main(String[] args) { launch(args); }
    
      @Override public void start(Stage stage) {
        Line fuzzyline = LineBuilder.create()
            .startX(5).startY(50)
            .endX(90).endY(50)
            .stroke(Color.BLACK).strokeWidth(1)
          .build();
        Line hairline = LineBuilder.create()
            .startX(4.5).startY(99.5)
            .endX(89.5).endY(99.5)
            .stroke(Color.BLACK).strokeWidth(1)
          .build();
        Line fatline = LineBuilder.create()
            .startX(5).startY(150)
            .endX(90).endY(150)
            .stroke(Color.BLACK).strokeWidth(1).strokeType(StrokeType.OUTSIDE)
          .build();
        Pane snappedPane = new Pane();
        Line insideline = LineBuilder.create()
            .startX(5).startY(25)
            .endX(90).endY(25)
            .stroke(Color.BLACK).strokeWidth(1)
          .build();
        snappedPane.setSnapToPixel(true);
        snappedPane.getChildren().add(insideline);
        snappedPane.setPrefSize(100, 50);
        snappedPane.relocate(-0.5, 174.5);
    
        stage.setScene(
          new Scene(
            new Group(
              fuzzyline, hairline, fatline, snappedPane,
              new Text(10, 40, "fuzzyline"),  
              new Text(10, 90, "hairline"),  
              new Text(10, 140, "fatline"),  
              new Text(10, 190, "snappedPane")
            ), 100, 250
          )
        );
        stage.show();
      }
    }
    

    【讨论】:

    猜你喜欢
    • 2015-12-12
    • 1970-01-01
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    相关资源
    最近更新 更多