如何设置TreeCell儿童的样式?

时间:2017-09-29 23:32:15

标签: java css javafx treeview javafx-8

首先,一些上下文:我的JavaFX应用程序中有一个TreeView,具有自定义的TreeCell实现。此实现添加了一个HBox以在右侧显示标签(使用LabeledText)和一个(或多个)图标/状态指示器。 标签和图标也会附加工具提示。使用Scenic View进行检查时,结果如下:

Scenic View of my TreeView

正如您在上图所示,单元格包含带有标签(LabeledText)的HBox,间距区域,在此示例中为一个图标(使用字体,因此为Glyph + LabeledText)。可以使用字体或某些点可能添加更多图标。

根据所代表项目的状态,我希望以不同的方式设置标签样式(例如,不同的文字颜色,斜体,......)。生成的TreeView目前看起来像这样:

TreeView as displayed in application

实际问题:我尝试了一些我的方法的变体,但逻辑解决方案即使看起来应该也没有正常工作。我错过了什么吗?我是否发现了JavaFX CSS处理中的错误?

我有一个当前有效的解决方法(但如果我在TreeView中添加某些功能,可能会停止这样做)所以我仍然想知道为什么这不能按预期工作

基本方法

根据显示的项目及其状态,将相关的CSS类应用于TreeCell。使用CSS选择器设置内部标签的样式。例如:

.mystatus > HBox > .text {
    -fx-font-style: italic;
}

/* the following variants give mostly the same result */
.mystatus > HBox > LabeledText {
    -fx-font-style: italic;
}
.mystatus .text { /* only difference: this messes up my icons */
    -fx-font-style: italic;
}

我遇到的问题是,一旦用户开始在UI中操作TreeView,TreeCell的子项的CSS选择似乎无法可靠地工作。 CSS应用于与给定CSS规则不匹配的节点。例如,在展开/折叠某些项目后,不匹配的标签无论如何都会使CSS选择器显示为斜体。

所以,如果你看一下上面的图片,并认为这是我的项目的正确显示。折叠/重新打开项目1节点可能会导致,即使没有将此类CSS添加到该节点,项目3突然变为斜体。

我使用Scenic View验证了应用的类,以确保我正确地设置/清除类:CustomTreeCellImpl 中有LabeledText节点,而仍然得到斜体的mystatus类。

备选方案1:使用伪类而不是常规类

与上述基本方法相同的问题

示例CSS:

*.tree-cell:mystatus > HBox > .text {
    -fx-font-style: italic;
}

备选方案2:直接将类或伪类应用于LabeledText而不是TreeCell

与上述基本方法相同的问题

示例CSS:

.text:mystatus {
    -fx-font-style: italic;
}

备选方案3:通过代码

直接将CSS属性应用于创建的标签

同样,这会遇到与以前相同的问题:在操作树之后,样式会被应用到他们不应该的地方。

以下是填充/更新TreeCell的方法的相关部分:

// add label
LabeledText text = new LabeledText(this);
text.setText("Item 1");
if(someCondition) {
    text.setStyle("-fx-font-style: italic;");
}
hbox.getChildren().add(text);

LabeledText对象的文本永远不会更改:始终会创建一个新文本。即便如此,我得到的结果也不正确。

这让我感到特别奇怪,因为这与CSS选择器无关 - 样式直接应用于节点,但问题仍然存在。

解决方法

对于那些对我如何设法解决问题感兴趣的人 - 现在:将类或伪类应用于整个TreeCell,并为子元素添加异常/覆盖,我不想将其设置为恢复默认布局。

如果/当我向细胞中添加更多元素时,这大部分都有效,但可能会变得很麻烦。此外,我推测这只有效,因为这里所有子元素(除了标签)都应用了完全相同的样式,无论它们显示的项目的状态如何(例如,所有字形都是黑色普通字体等)。

如果/当我想自定义这些样式时(例如根据上下文更改字形颜色,而不是仅仅使用不同的字形字符),我推测我可能会再次遇到这个问题 - 这次不知道如何解决因为我的解决方法将不再适用。

更新:我添加了project on GitHub来证明问题。

项目中的演示数据应该将项目1.1和1.3放在斜体中,其他所有项目都显示正常。展开/折叠第1项时,无论如何都不应该使用斜体(在Windows上)。

此外,在创建此示例时,我注意到在OS X none 项目得到斜体(CSS本身正确加载,我临时添加到测试中的不同样式已应用)。在Windows上,发生上述问题。

1 个答案:

答案 0 :(得分:1)

错误是使用com.sun.javafx.scene.control.skin.LabeledText来显示商品文字。

如果您使用普通javafx.scene.control.Label.Labeljavafx.scene.text.Text,则所有内容都可以正常运行。

LabeledText内部使用StyleablePropertyMirror将自身作为TreeItem各种属性的侦听器附加,并将这些样式更改应用于自身(LabeledText)。< / p>

要解释:TreeView基本上只是一个自定义的ListView,有一些缩进。请注意,两者都依赖于尽可能多地回收细胞的概念。

如果我们在折叠前查看你的结构:

  • (1)第1项
    • (2)项目1.1(突出显示
    • (3)项目1.2
    • (4)项目1.3(突出显示
    • (5)项目1.4
  • (6)第2项

崩溃后:

  • (1)第1项
  • (2)第2项(突出显示

现在你不应该感到惊讶Item 2现在具有Item 1.1之前的突出显示,因为它基本上是同一个单元格(在相同的索引位置),现在显示不同的项目。

相关问题