gpt4 book ai didi

javafx - 在CellFactory中有条件地提供不同的TreeCell

转载 作者:行者123 更新时间:2023-12-02 09:59:01 24 4
gpt4 key购买 nike

我有一个 TreeView ,其中单元格必须根据 TreeItem's value 的实际实现显示不同的信息。 .

我的域模型如下所示:

Domain model

对我来说,将“如何在单元格中显示任务”或“如何在单元格中显示组”的行为分成两个不同的类似乎很自然。

public abstract class ComponentTreeCell<T extends Component> extends TreeCell<T>
{
@Override
protected void updateItem(T item, boolean empty)
{
//Some common logic...
}
}

public class GroupTreeCell extends ComponentTreeCell<Group>
{
@Override
protected void updateItem(Group item, boolean empty)
{
super.updateItem(item, empty);

//Some group-specific-logic
}
}

public class TaskTreeCell extends ComponentTreeCell<Task>
{
@Override
protected void updateItem(Task item, boolean empty)
{
super.updateItem(item, empty);

//Some task-specific-logic
}
}

以下 Controller 类包含 TreeView我在其中设置 CellFactory。

public class Controller implements Initializable
{
@FXML
private TreeView<Component> treeview;

@Override
public void initialize(URL url, ResourceBundle bundle)
{
treeview.setCellFactory(new Callback<TreeView<Component>, TreeCell<Component>>()
{
@Override
public TreeCell<Component> call(TreeView<Component> arg0)
{
if(/* stuck */ instanceof Group)
{
return new GroupTreeCell();
}
else if(/* stuck */ instanceof Task)
{
return new TaskTreeCell();
}
else
{
return new DefaultTreeCell();
}
}
});
}
}

但现在我陷入困境,无法决定必须返回哪种类型的单元格。事实上,我的参数中只有相关的 TreeView不是相关的TreeItem !

在我看来,这似乎是 JavaFX 的一种弱点。当您只需要检索一个 TreeCell 时,为什么 JavaFX 向用户提供完整的 TreeView??

有没有办法以这种方式做到这一点,或者我是否必须在同一个自定义 TreeCell 实现中实现两种不同的行为?

public class ComponentTreeCell extends TreeCell<Component>
{
@Override
protected void updateItem(Component item, boolean empty)
{
//Some common logic...

if(item instanceof Group)
{
//Group-specific logic...
}
else if(item instanceof Task)
{
//Task-specific logic...
}
else
{
//Default logic...
}
}
}

最佳答案

Why JavaFX gives the full TreeView to the user when you only need to retrieve one TreeCell ??

因为 TreeItem 之间不存在 1-1 关系和 TreeCell s: TreeView只会创建少量 TreeCell s(即使树有大量项目)。 TreeCell s 被重用以显示不同的 TreeItem s,例如,如果某些节点展开/折叠,或者用户滚动。

这样做是为了提高性能。提供渲染的实际单元格是相当大的对象:它们是 UI 组件并带有 CSS 样式等。显示的实际数据,即TreeItem相对较轻;通常它们只是 String 的简单包装。 s。所以这个机制允许有 TreeView具有大量数据,不会对性能造成巨大负担。创建 TreeCell对于每个 TreeItem不会允许这样做。

正因为如此,TreeCell您从工厂提供的必须能够处理任何TreeItem这可能是由 TreeView 赋予它的。例如,当用户更改显示的项目(通过展开/折叠或滚动)时,TreeCell之前显示 Task 的实例可能用于显示 Group 。这就是 updateItem(...) 的目的方法;当 TreeCell 时调用它被重复使用。

这意味着您的设置根本无法工作。您基本上需要 TreeCell<Component>在你的最后一个代码示例中实现。如果您愿意,您当然可以将配置分解为单独的类,例如:

public class ComponentTreeCell extends TreeCell<Component>
{
@Override
protected void updateItem(Component item, boolean empty)
{
super.updateItem(item, empty);
CellConfiguratorFactory.getConfigurator(item).configure(this, item, empty);
}

}

工厂:

public class CellConfiguratorFactory {

private static CellConfigurator<Task> taskCellConfigurator ;
private static CellConfigurator<Group> groupCellConfigurator ;
private static CellConfigurator<Component> defaultCellConfigurator ;

private static CellConfigurator getConfigurator(Component item) {
if (item instanceof Task) {
if (taskCellConfigurator == null) {
taskCellConfigurator = new TaskCellConfigurator();
}
return taskCellConfigurator ;
} else if (item instanceof Group) {
if (groupCellConfigurator == null) {
groupCellConfigurator = new GroupCellConfigurator();
}
return groupCellConfigurator ;
} else {
if (defaultCellConfigurator == null) {
defaultCellConfigurator = new DefaultCellConfigurator();
}
return defaultCellConfigurator ;
}
}
}

(请注意,您可以假设工厂仅在单个线程中使用,因为所有事情都将发生在 FX 应用程序线程上。)

然后

public interface CellConfigurator<T extends Component> {
public void configureCell(ComponentTreeCell cell, T item, boolean empty);
}

例如,

public class TaskCellConfigurator implements CellConfigurator<Task> {
public void configureCell(TreeCell<Component> cell, Task item, boolean empty) {
// task-specific implementation...
}
}

但是,我不确定额外的结构是否值得在这里付出努力。

关于javafx - 在CellFactory中有条件地提供不同的TreeCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30616769/

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