如何设计TreeCell儿童的风格?

bra*_*n99 5 css java treeview javafx javafx-8

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

我的TreeView风景

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

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

TreeView在应用程序中显示

实际问题:我尝试了一些我的方法的变体,但逻辑解决方案虽然看起来应该没有正常工作.我错过了什么吗?我是否发现了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;
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,一旦用户开始在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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

CSS示例:

.text:mystatus {
    -fx-font-style: italic;
}
Run Code Online (Sandbox Code Playgroud)

备选方案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);
Run Code Online (Sandbox Code Playgroud)

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

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

解决方法

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

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

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


更新:我在GitHub上放了一个项目来演示这个问题.

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

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

eck*_*kig 1

错误是使用com.sun.javafx.scene.control.skin.LabeledText来显示您的项目文本。

如果您使用正常的javafx.scene.control.Label.Labeljavafx.scene.text.Text相反,在您的示例中一切正常。

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

解释一下:这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,因为它基本上是相同的单元格(在相同的索引位置)现在显示不同的项目。