您可以使用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();
}
}