Java 如何设计TreeCell儿童的风格?

Java 如何设计TreeCell儿童的风格?,java,css,javafx,treeview,javafx-8,Java,Css,Javafx,Treeview,Javafx 8,首先,一些上下文:我在JavaFX应用程序中有一个TreeView,带有一个自定义TreeCell实现。此实现添加一个HBox以显示标签(使用LabeledText)和右侧的一个(或多个)图标/状态指示器。 标签和图标还会附加工具提示。使用检查时,结果如下所示: 如上图所示,一个单元格包含一个带有标签(LabeledText)、间距区域的HBox,在本例中还有一个图标(使用字体,因此使用Glyph+LabeledText)。更多的图标可能会使用字体或在某些时候可能是图像来添加 根据所表示的项目

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

如上图所示,一个单元格包含一个带有标签(LabeledText)、间距区域的HBox,在本例中还有一个图标(使用字体,因此使用Glyph+LabeledText)。更多的图标可能会使用字体或在某些时候可能是图像来添加

根据所表示的项目的状态,我希望标签的样式有所不同(例如不同的文本颜色、斜体等等)。生成的TreeView当前如下所示:

实际问题:我尝试了几种不同的方法,但逻辑解决方案无法正常工作,尽管看起来应该如此。我错过什么了吗?我是否在JavaFXCSS处理中发现了一个bug

我有一个解决方案,目前正在工作(但可能会停止这样做,如果我添加某些功能到我的树状视图),所以我仍然想知道为什么这不工作的预期

基本方法 根据显示的项目及其状态,将相关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节点可能会导致项目3突然变为斜体,即使该节点从未添加过此类CSS

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

备选方案1:使用伪类而不是常规类 与上述基本方法相同的问题

CSS示例:

*.tree-cell:mystatus > HBox > .text {
    -fx-font-style: italic;
}
.text:mystatus {
    -fx-font-style: italic;
}
备选方案2:将类或伪类直接应用于LabeledText,而不是TreeCell 与上述基本方法相同的问题

CSS示例:

*.tree-cell:mystatus > HBox > .text {
    -fx-font-style: italic;
}
.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,并为我不希望设置样式的子元素添加异常/覆盖以恢复默认布局

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

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


更新:我放了一个例子来说明这个问题

项目中的演示数据应将项目1.1和1.3以斜体显示,所有其他项目显示正常。展开/折叠项目1时,不应以斜体显示的项目(在Windows上)


另外,在创建这个示例时,我注意到在OSX上没有一个项目被斜体化(CSS本身被正确加载,我临时添加到测试中的另一个样式被应用)。在Windows上,出现上述问题。

错误在于使用
com.sun.javafx.scene.control.skin.LabeledText
显示项目文本

如果您使用普通的
javafx.scene.control.Label.Label
javafx.scene.text.text
,那么在您的示例中一切都可以正常工作

LabeledText
在内部使用一个
StyleablePropertyMirror
,它将自身作为
TreeItem
的各种属性的侦听器,并将这些样式更改应用于自身(“code>LabeledText)

解释一下:
TreeView
基本上只是一个定制的
ListView
,带有一些缩进。请注意,两者都尽可能依赖于回收电池的概念


如果我们在倒塌前观察你的结构:

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

崩溃后:

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


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

您能分享您的代码吗?我相信我们可以使用一些CSS选择器来实现所需的结果,但我想先看看您的代码。顺便说一下,坐l