Some _instances_ of glyph disappear - how to pinpoint reason?

时间:2016-07-11 22:01:16

标签: javafx font-awesome fxml

I am having a weird problem with JavaFX and Font Awesome, which I'm having trouble pin-pointing the cause of. The problem is further complicated because I can't really share the code, and no matter how much I've tried to replicate the problem in a simpler case - I couldn't.

The problem is as follows - I have a TableView, in which every column has a Hyperlink as a graphic, with a Font Awesome glyph. This all works well, except for one stage - in this stage, the first time it is shown everything is fine, but the second time three of the columns' glyphs revert to squares. This is weird, as all columns use the same glyph of the same font.

Here are before and after pictures - notice the glyphs are all the same, but the left ones become squares:

First showing of stage

Second showing of stage

The glyphs and font are set through FXML, and are the same for all columns:

<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>

Here the last two columns are the ones who lose their glyph (the scene is in right-to-left orientation).

Furthermore - it is always the last three columns that lose their glyph, that is - if on the first showing I reorder the column, the columns I leave last in the table (to the left, again - the scene is right-to-left) will lose their glyph the next time the stage is shown. Subsequent hiding/showing won't lost any more glyphs.

I show the stage with Stage#showAndWait, and I keep a reference to the stage, so it is only created once.

I realize it is hard to help when I can't share any code (client confidentiality), so what I'm asking is - where can I look to see what is happening? How come some instances of the same glyph disappear and others don't? Did anyone else encounter something like this? What was the underlying reason?

Edit: I have added debug prints of the hyperlinks' properties, and indeed with the second showing the font reverts to "System" for the last three columns. Looking for the source of the change, I have added a change listener, and put breakpoint inside it. The stack shows that the change happens inside applyCSS, after a lot of internal calls following showAndWait, non of them in my own code (i.e. - all in the JavaFX library code). It seems for some reason JavaFX decides to reset the font definition of some of the controls, although they are all defined exactly the same! This is corroborated by the fact that it doesn't matter which table-column it is, but where it is in the TableView.

So it seems like some erroneous JavaFX behavior is resetting the font to the default ("-fx-font") instead of the one defined on the node itself. Anyone know enough about the JavaFX CSS logic to help find the bug?
All hyperlinks have no custom styles or classes set, and only the 'visited' pseud-class set.

Edit 2: Adding a font name to the CSS fixes the issue. I would still love to find the source of the bug (which, I am certain, is in the JavaFX CSS handling), but it is too messy for me to go through it now. The CSS I use is:

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

1 个答案:

答案 0 :(得分:1)

我敢打赌某些代码或css样式正在改变Hyperlink字体或样式或css类。你可以使用一些调试。例如,您可以在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());
        }
    });

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