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

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

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

另外,请参阅坐标系统上的节点文档。

在器件像素级,整数坐标映射到角上,像素之间的裂缝和像素的中心出现在整数像素位置之间的中点处。 由于所有坐标值均使用浮点数指定,因此坐标可以精确指向这些角(当浮点值具有精确的整数值时)或指向像素上的任何位置。 例如,坐标(0.5,0.5)将指向舞台上左上角像素的中心。 类似地,尺寸为10×10的(0,0)处的矩形将从舞台上左上角像素的左上角跨越到第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(); } } 

线型样品