如何在JavaFX 2.2中绘制清晰,不透明的细线?

时间:2012-08-09 14:57:13

标签: java javafx javafx-2

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

文档说,strokeWidth 0.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(); 绘制一条宽度为几个像素的白线。

这是我的测试代码:

{{1}}

1 个答案:

答案 0 :(得分:3)

您可以为父级使用Region子类,例如PanesnapToPixel设置为true。

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

  

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

另请参阅Shape文档:

  

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

     

避免这些模糊轮廓的两种常见解决方案是使用更广泛的   完全覆盖更多像素的笔划 - 通常是笔划宽度   如果没有有效的比例变换,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();
  }
}

Line Type Sample