javaswingswingxjxtreetable

JXTreeTable expandPath after filtering


I have JXTreeTable which I can filter. When I filter a keyword a new model is set. It works ok for me.

Now I want to expand all the filtered results. For that I save the position where the matching node was found. (It cant be a leaf.)

For that positions I create a List of TreePaths with this method:

public TreePath getPath(TreeNode node) {
    List<TreeNode> list = new ArrayList<TreeNode>();

    while (node != null) {
        list.add(node);
        node = node.getParent();
    }
    Collections.reverse(list);

    return new TreePath(list.toArray());
}

Now I iterate over this list and call expandPath (after the new model was set) Where getTreePaths() is a list of TreePaths which I created with the method before.

for (TreePath elem : f.getTreePaths()) {
        tree.expandPath(elem);
        tree.scrollPathToVisible(elem);
}

But it has no effect, only the root is expanded and all the children are collapsed. In the TreePath the last element is no leaf. In a System.out in this loop I get for all:

-1 true true true

System.out.println(tree.getRowForPath(elem)); System.out.println(f.isPathValid(elem,tree.getTreeTableModel())); System.out.println(tree.isVisible(elem)); System.out.println(tree.isExpanded(elem));

The -1 for getRowForPath is maybe the problem?

isPathValid():

public boolean isPathValid(TreePath path,TreeTableModel model) {
    if (path.getPathCount() == 0) {
        return model.getRoot().equals(path.getPathComponent(0));
    }

    for (int x = 1; x < path.getPathCount(); x++) {
        if (model.getIndexOfChild(path.getPathComponent(x - 1),
                path.getPathComponent(x)) == -1) {
            return false;
        }
    }
    return true;
}

Solution

  • I know it is an old post, but I'll drop here my findings after spending an hour in a similar problem.

    The method "isPathValid" only validates if the sequence is correct by checking if the child (x) belongs to the parent (x - 1), but it doesn't validate if the root is the same as the table model (unless the path count is zero).

    When filtering, you usually trigger a new root to the table model, so if you captured the TreePaths "before" updating the model (and triggering a new root), the table won't be able to find the path, although the path itself is valid.

    It should work with a few of changes:

    public **List** getPath(TreeNode node) {
    List<TreeNode> list = new ArrayList<TreeNode>();
    
    **while (node != model.getRoot()) {**
        list.add(node);
        node = node.getParent();
    }
        Collections.reverse(list);
    
        **return list;**
    }
    
    **for (List elem : f.getTreePaths()) {**
            elem.add(0, model.getRoot());
            tree.expandPath(new TreePath(elem.toArray());
            tree.scrollPathToVisible(elem);
    }