如何在JavaFX中禁用TextFlow中Line节点的平滑?

问题描述 投票:0回答:1

我有两个 TextFlow,我需要一条垂直线穿过它们(感谢 James_D,他帮助我完成了它。但是,我需要一条宽度为

1px
的线,但看起来该线已平滑,因此渲染的线宽度是
2px
这是我的代码:

public class Test extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {
        var textFlow1 = createTextFlow();
        textFlow1.setStyle("-fx-background-color: cyan");
        var textFlow2 = createTextFlow();
        textFlow2.setStyle("-fx-background-color: yellow");

        VBox vbox = new VBox(textFlow1, textFlow2);
        Scene scene = new Scene(vbox, 300, 100);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private TextFlow createTextFlow() {
        Text textA = new Text("ABC ");
        textA.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");
        Line line = new Line();
        line.setManaged(false);
        line.setSmooth(false);
        Text textB = new Text(" DEF");
        textB.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");
        TextFlow textFlow = new TextFlow(textA, line, textB) {
            @Override
            protected void layoutChildren() {
                super.layoutChildren();
                double x = textB.getBoundsInParent().getMinX();
                line.setStartX(x);
                line.setEndX(x);
                line.setEndY(getHeight());
            }
        };
        return textFlow;
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这就是结果:

enter image description here

有人能告诉我如何禁用线条的平滑吗?

javafx
1个回答
0
投票

要获得清晰的线条,请将端点坐标舍入并修改为笔画宽度的一半。 由于您的笔划为 1 像素,因此调整 0.5。

例如:

double x = Math.round(textB.getBoundsInParent().getMinX()) - 0.5;
line.setStartX(x);
line.setEndX(x);

示例输出的快照和放大版本:

snapshot

可执行样本

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.shape.Line;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.Stage;

import java.io.IOException;

public class Test extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {
        var textFlow1 = createTextFlow();
        textFlow1.setStyle("-fx-background-color: cyan");
        var textFlow2 = createTextFlow();
        textFlow2.setStyle("-fx-background-color: yellow");

        VBox vbox = new VBox(textFlow1, textFlow2);
        vbox.setPadding(new Insets(5));
        Scene scene = new Scene(vbox);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private TextFlow createTextFlow() {
        Text textA = new Text("ABC ");
        textA.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");
        Line line = new Line();
        line.setManaged(false);
        Text textB = new Text(" DEF");
        textB.setStyle("-fx-font-family: 'monospace'; -fx-font-size: 14;");

        return new TextFlow(textA, line, textB) {
            @Override
            protected void layoutChildren() {
                super.layoutChildren();
                double x = Math.round(textB.getBoundsInParent().getMinX()) - 0.5;
                line.setStartX(x);
                line.setEndX(x);
                line.setStartY(0.5);
                line.setEndY(Math.round(getHeight()) - 0.5);
            }
        };
    }

    public static void main(String[] args) {
        launch(args);
    }
}

说明

有关更多信息,请参阅标题为“与坐标交互”的部分 系统”为

Shape

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

避免这些模糊轮廓的两种常见解决方案是使用更广泛的 完全覆盖更多像素的笔画 - 通常是笔画宽度 如果没有有效的比例变换,2.0 的版本将实现这一点 - 或指定 StrokeType.INSIDE 或 StrokeType.OUTSIDE 描边样式 - 它将默认的单个单位描边偏向 位于内部或外部的完整像素行或列之一 形状的边框。

对于线条,与填充形状不同,调整

StrokeType
不会给您所需的结果,因为线条没有宽度,只有长度和位置。
StrokeType.INSIDE
表示线条将导致该线条不显示,而
StrokeType.OUTSIDE
将导致线条宽度为笔画宽度的两倍。

出于这些原因,我调整线条开始和结束位置的坐标,假设默认

StrokeType.CENTERED
而不是调整笔划类型。 这使得线条笔划变得以该线所遍历的像素的中心为中心,并且,由于笔划是一个像素宽并且该线是垂直的,所以该线完全覆盖了它所遍历的像素,而不覆盖其他像素。

© www.soinside.com 2019 - 2024. All rights reserved.