TreeView:在TreeItem展开前拦截branchExpandedEvent并执行任务
如何在TreeItem展开前执行任务?
需求是:当节点被点击触发展开操作后、实际展开前执行任务。目前使用branchExpandedEvent的方式会在分支展开后才执行任务:
treeItem.addEventHandler(TreeItem.branchExpandedEvent(), e -> { // 此处任务会在TreeItem分支展开后执行 });
参考@James_D的设计思路,核心是通过属性与监听器检查TreeItem的子节点是否加载。我在特定场景中使用该方案时,不仅用于节点展开操作,还适配自定义TreeItem的右键菜单,同时不希望监听器始终绑定在TreeItem上。因此,除了已有的实现方案外,我创建了一个针对该属性的自定义自移除监听器,可用于各类「即时处理」流程:
public class ChildrenLoadedListener implements ChangeListener<Boolean> { private final CustomTreeItem customTreeItem; private final Runnable r; public ChildrenLoadedListener(CustomTreeItem customTreeItem, Runnable r) { this.customTreeItem = customTreeItem; this.r = r; } @Override public void changed( ObservableValue<? extends Boolean> observableValue, Boolean aBoolean, Boolean t1 ) { if (t1) { r.run(); customTreeItem.loadedProperty().removeListener(this); } } }
以下是在展开特定类型子节点方法中的使用示例:
private void ifChildrenIsThisTypeThenExpand(CustomTreeItem customTreeItem) { if (customTreeItem.getValue().isTheTypeThatNeedToBeExpanded()) { customTreeItem.loadedProperty().addListener( new ChildrenLoadedListener( customTreeItem, () -> { customTreeItem.getChildren().forEach(child -> { ifChildrenIsThisTypeThenExpand( (CustomTreeItem) child ); }); } ) ); } }
@Override public void customExpand() { // 将场景光标设置为等待状态 CustomTreeItem customTreeItem = (CustomTreeItem) treeView .getSelectionModel() .getSelectedItem() .get(0); if (!customTreeItem.getValue().isTheTypeThatNeedToBeExpanded()) { customTreeItem.setExpanded(true); } else { ifChildrenIsThisTypeThenExpand(customTreeItem); } // 将场景光标恢复为默认状态 }
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

