在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}}
答案 0 :(得分:3)
您可以为父级使用Region子类,例如Pane,snapToPixel设置为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();
}
}