gpt4 book ai didi

不同类字段的 JavaFX TreeItem css 样式

转载 作者:太空宇宙 更新时间:2023-11-04 07:30:39 24 4
gpt4 key购买 nike

我的 TreeView 由我自己的树填充。在 Node 类中,我有一个字段“type”,它是 NodeType 之一。问题是我想为每种类型的 NodeType 设置样式,例如“type1”文本颜色应为绿色,“type2”文本颜色应为红色。我是 javaFX 的新手。我找到了 james-d ( https://github.com/james-d/heterogeneous-tree-example ) 的解决方案,但在此示例中,css 样式取决于类名,我如何为类字段制作它?

View of TreeView

最佳答案

我的理解是你想要一个 TreeCell样式因 NodeType 而异的 Node包含在 TreeItem 中说 TreeCell .全部通过 CSS。我说得对吗?

假设我是对的,我可以想到两种方法来实现这一点;如果有少量已知 NodeType,这两种方法效果最好秒。第一个涉及使用 PseudoClass第二个使用与 JavaFX 相同的策略 Chart API。


第一个选项

创建自定义 TreeCell适合使用您的 Node类型(即适本地指定通用签名)。在这个习惯TreeCell你声明了多少 PseudoClass根据需要静态最终字段;每个人一个NodeType .然后你观察 NodeType什么的Node当前显示在TreeCell并更新 PseudoClass据此说明。

这是一个假设 NodeType 的例子是一个 enum有两个常量:HAPPYSAD .

public class CustomTreeCell<T extends Node> extends TreeCell<T> {

private static final PseudoClass HAPPY = PseudoClass.getPseudoClass("happy");
private static final PseudoClass SAD = PseudoClass.getPseudoClass("sad");

// this listener will activate/deactivate the appropriate PseudoClass states
private final ChangeListener<NodeType> listener = (obs, oldVal, newVal) -> {
pseudoClassStateChanged(HAPPY, newVal == NodeType.HAPPY);
pseudoClassStateChanged(SAD, newVal == NodeType.SAD);
};

// use a weak listener to avoid a memory leak
private final WeakChangeListener<NodeType> weakListener = /* wrap listener */;

public CustomTreeCell() {
getStyleClass().add("custom-tree-cell");
itemProperty().addListener((obs, oldVal, newVal) -> {
if (oldVal != null) {
oldVal.nodeTypeProperty().removeListener(weakListener);
}
if (newVal != null) {
newVal.nodeTypeProperty().addListener(weakListener);
// need to "observe" the initial NodeType of the new Node item.
// You could call the listener manually to avoid code duplication
pseudoClassStateChanged(HAPPY, newVal.getNodeType() == NodeType.HAPPY);
pseudoClassStateChanged(SAD, newVal.getNodeType() == NodeType.SAD);
} else {
// no item in this cell so deactivate all PseudoClass's
pseudoClassStateChanged(HAPPY, false);
pseudoClassStateChanged(SAD, false);
}
});
}
}

然后在您的 CSS 文件中您可以使用:

.custom-tree-cell:happy {
/* style when happy */
}

.custom-tree-cell:sad {
/* style when sad */
}

第二个选项

JavaFX 做什么 Chart API 在处理多系列数据时执行。它所做的是动态更新 style class节点的数量取决于列表中系列的索引(例如 .line-chart-series-data-<index> <-- 可能完全不是这个)。

/*
* Create a custom TreeCell like in the first option but
* without any of the PseudoClass code. This listener should
* be added/removed from the Node item just like weakListener
* is above.
*/
ChangeListener<NodeType> listener = (obs, oldVal, newVal) -> {
// You have to make sure you keep "cell", "indexed-cell", and "tree-cell"
// in order to keep the basic modena styling.
if (newVal == NodeType.HAPPY) {
getStyleClass().setAll("cell", "indexed-cell", "tree-cell", "custom-tree-cell-happy");
} else if (newVal == NodeType.HAPPY) {
getStyleClass().setAll("cell", "indexed-cell", "tree-cell", "custom-tree-cell-sad");
} else {
getStyleClass().setAll("cell", "indexed-cell", "tree-cell"); // revert to regular TreeCell style
}
};

然后在 CSS 中:

.custom-tree-cell-happy {
/* styles */
}

.custom-tree-cell-sad {
/* styles */
}

这两个选项实际上仅在存在一小组已知类型时才可行。当你有 10+ NodeType 之类的东西时,它可能变得无法维护。秒。如果 NodeType 的数量变得几乎不可能s 在运行时是动态的。

NodeType 可能更容易,或一些中间类/数据结构,知道文本应该是什么颜色并根据 NodeType 以编程方式设置颜色.

注意:我在回答中快速输入了代码,并没有测试它。我的代码中可能存在编译器错误、运行时异常或逻辑错误。


编辑

我想到了其他事情。我上面的代码假设 NodeType保存在一个属性中,可以在运行时更改。如果NodeType对于每个 Node 都是静态的(不变的)那么代码可以大大简化。您可以简单地覆盖 javafx.scene.control.Cell 中声明的以下方法,而不是使用任何监听器。 :

protected void updateItem(Node item, boolean empty)

每次在单元格上设置新元素时都会调用此方法。阅读 documentation ,但是,因为覆盖此方法需要开发人员执行某些操作(例如调用 super 实现)。

关于不同类字段的 JavaFX TreeItem css 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49444909/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com