如何在 JavaFX 2.2 中绘制清晰、不透明的细线?
Posted
技术标签:
【中文标题】如何在 JavaFX 2.2 中绘制清晰、不透明的细线?【英文标题】:How to draw a crisp, opaque hairline in JavaFX 2.2? 【发布时间】:2012-08-06 20:16:21 【问题描述】:在 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】:您可以使用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://***.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();
【讨论】:
另见相关问题:What are a line's exact dimensions in JavaFX 2?以上是关于如何在 JavaFX 2.2 中绘制清晰、不透明的细线?的主要内容,如果未能解决你的问题,请参考以下文章