字形的一些_实例_消失了——如何查明原因?

Some _instances_ of glyph disappear - how to pinpoint reason?

我在使用 JavaFX 和 Font Awesome 时遇到了一个奇怪的问题,我无法确定问题的原因。问题变得更加复杂,因为我无法真正共享代码,而且无论我如何尝试在更简单的情况下复制问题 - 我都做不到。

问题如下 - 我有一个 TableView,其中每一列都有一个 Hyperlink 作为图形,带有 Font Awesome 字形。这一切都很好,除了一个阶段 - 在这个阶段,第一次显示一切都很好,但第二次三个列的字形恢复为正方形。这很奇怪,因为所有列都使用相同字体的相同字形。

这是之前和之后的图片 - 注意字形都是一样的,但左边的变成了正方形:

字形和字体通过 FXML 设置,所有列都相同:

<TableColumn fx:id="col1" prefWidth="83.0" text="Column 1"><graphic>
            <Hyperlink onAction="#requestFilter" text="" visited="true">
                <font>
                    <Font name="FontAwesome Regular" size="13.0" />
                </font></Hyperlink>
        </graphic>
</TableColumn>
<TableColumn fx:id="col2" prefWidth="138.0" text="Column 2"><graphic>
            <Hyperlink onAction="#requestFilter" text="" visited="true">
                <font>
                    <Font name="FontAwesome Regular" size="13.0" />
                </font></Hyperlink>
        </graphic>
</TableColumn>
<TableColumn fx:id="col3" prefWidth="59.0" text="Column 3"><graphic>
            <Hyperlink onAction="#requestFilter" text="" visited="true">
                <font>
                    <Font name="FontAwesome Regular" size="13.0" />
                </font></Hyperlink>
        </graphic>
</TableColumn>
<TableColumn fx:id="col4" prefWidth="103.0" text="Column 4"><graphic>
            <Hyperlink onAction="#requestFilter" text="" visited="true">
                <font>
                    <Font name="FontAwesome Regular" size="13.0" />
                </font></Hyperlink>
        </graphic>
</TableColumn>

这里的最后两列是丢失字形的列(场景是从右到左的方向)。

此外 - 总是最后三列丢失了它们的字形,也就是说 - 如果在第一次显示时我重新排序该列,我在 table 中最后留下的列(再次向左- 场景是从右到左)将在下次显示舞台时丢失其字形。随后的 hiding/showing 不会再丢失字形。

我用 Stage#showAndWait 展示舞台,我保留对舞台的引用,所以它只创建一次。

我意识到当我无法共享任何代码(客户机密)时很难提供帮助,所以我要问的是 - 我在哪里可以看到发生了什么?为什么相同字形的某些实例会消失而其他实例却不会?有没有其他人遇到过这样的事情?根本原因是什么?

编辑: 我添加了超链接属性的调试打印,事实上,第二个显示的字体在最后三列恢复为 "System"。寻找变化的来源,我添加了一个变化监听器,并在其中放置了断点。堆栈显示更改发生在 applyCSS 内部,在 showAndWait 之后的大量内部调用之后,我自己的代码中没有这些调用(即 - 全部在 JavaFX 库代码中)。似乎出于某种原因,JavaFX 决定重新设置某些控件的字体定义,尽管它们的定义完全相同!事实证实了这一点,它是哪个 table 列并不重要,但它在 TableView 中的位置。

因此,似乎某些错误的 JavaFX 行为正在将字体重置为默认值(“-fx-font”),而不是节点本身定义的字体。任何人都足够了解 JavaFX CSS 逻辑来帮助找到错误?
所有超链接都没有自定义样式或 classes 集,只有 'visited' 伪 class 集。

编辑 2: 将字体名称添加到 CSS 可解决此问题。我仍然很想找到错误的来源(我敢肯定,它在 JavaFX CSS 处理中),但它太混乱了,我现在无法完成它。我使用的CSS是:

.table-column .hyperlink {
    -fx-font-family: "FontAwesome";
}

我敢打赌,某处的某些代码或 css 样式正在改变超链接字体或样式或 css class。您可以使用一些调试。例如,您可以在 TableView 附近添加按钮以打印一些调试信息,如下所示:

    Button b = new Button("Debug");
    b.setOnAction(e->{
        TableView<?> tv = (TableView) scene.lookup("#tableView");
        for(TableColumn<?,?> tc : tv.getColumns()) {
            Hyperlink link = (Hyperlink)tc.getGraphic();
            System.out.println("Column "+tc.getText());
            System.out.println("link text: "+link.getText());
            System.out.println("link Style: "+link.getStyle());
            System.out.println("link CSS Classes: " + link.getStyleClass());
            System.out.println("link CSS Pseudo Classes: " + link.getPseudoClassStates());
            System.out.println("link Font: " + link.getFont());
        }
    });

然后在 table 看起来正常时单击此按钮并将调试信息保存在某处。当方块出现时再次单击并将输出与第一个进行比较。还要检查可以访问 TableColumns 的 css 文件和代码,如果其中任何一个会影响超链接样式。
编辑
好吧,这对我来说似乎很奇怪,JavaFX 本身的内部逻辑决定重新计算和重新应用 css 样式,仅针对特定列而不是整个场景(EDIT:根据 JavaFX CSS Reference 它实际上只能在场景图中的特定分支上重新应用 css)。我仍然认为根本原因在您的样式或代码中。我怀疑任何人都可以指出您要查看的地方,因为这似乎是非常具体的问题,而且正如您所说,无法在简单的场景中重现。也许你执行了一些特定的布局逻辑,recreating/replacing table 节点或类似的东西,很难说没有看到代码。
无论如何,如果你只是想解决问题,我建议在 css 文件中设置超链接字体样式,而不是在 fxml 中。通过这种方式,您可以确保即使在 css 重新计算或任何布局操作的情况下,样式也是相同的。无论如何,这将是正确的做法。
如果你想找出问题的真正原因,恐怕你得花些时间在你的调试器上:)我会从搜索正常列和字体损坏的列之间的区别开始。为什么他们的待遇不同?