X-Git-Url: http://git.nikiroo.be/?p=fanfix.git;a=blobdiff_plain;f=src%2Fbe%2Fnikiroo%2Futils%2Fui%2FTreeSnapshot.java;fp=src%2Fbe%2Fnikiroo%2Futils%2Fui%2FTreeSnapshot.java;h=ef9a6fb60a0d87f2fa17ad344952b4113770c63f;hp=0000000000000000000000000000000000000000;hb=f19b48e27a56ebab18687debd9ef52581a03f06d;hpb=dfa4091ccd9f46687c7326aa6bf2eaf588a7cb83 diff --git a/src/be/nikiroo/utils/ui/TreeSnapshot.java b/src/be/nikiroo/utils/ui/TreeSnapshot.java new file mode 100644 index 0000000..ef9a6fb --- /dev/null +++ b/src/be/nikiroo/utils/ui/TreeSnapshot.java @@ -0,0 +1,127 @@ +package be.nikiroo.utils.ui; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JTree; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; + +public class TreeSnapshot { + private interface NodeAction { + public void run(TreeNode node); + } + + private JTree tree; + private TreePath[] selectionPaths; + private List expanded; + + public TreeSnapshot(JTree tree) { + this.tree = tree; + + selectionPaths = tree.getSelectionPaths(); + if (selectionPaths == null) { + selectionPaths = new TreePath[0]; + } + + expanded = new ArrayList(); + forEach(tree, new NodeAction() { + @Override + public void run(TreeNode node) { + TreePath path = nodeToPath(node); + if (path != null) { + if (TreeSnapshot.this.tree.isExpanded(path)) { + expanded.add(path); + } + } + } + }); + } + + public void apply() { + applyTo(tree); + } + + public void applyTo(JTree tree) { + final List newExpanded = new ArrayList(); + final List newSlectionPaths = new ArrayList(); + + forEach(tree, new NodeAction() { + @Override + public void run(TreeNode newNode) { + TreePath newPath = nodeToPath(newNode); + if (newPath != null) { + for (TreePath path : selectionPaths) { + if (isSamePath(path, newPath)) { + newSlectionPaths.add(newPath); + if (expanded.contains(path)) { + newExpanded.add(newPath); + } + } + } + } + } + }); + + for (TreePath newPath : newExpanded) { + tree.expandPath(newPath); + } + + tree.setSelectionPaths(newSlectionPaths.toArray(new TreePath[0])); + } + + // You can override this + protected boolean isSamePath(TreePath oldPath, TreePath newPath) { + return newPath.toString().equals(oldPath.toString()); + } + + private void forEach(JTree tree, NodeAction action) { + forEach(tree.getModel(), tree.getModel().getRoot(), action); + } + + private void forEach(TreeModel model, Object parent, NodeAction action) { + if (!(parent instanceof TreeNode)) + return; + + TreeNode node = (TreeNode) parent; + + action.run(node); + int count = model.getChildCount(node); + for (int i = 0; i < count; i++) { + Object child = model.getChild(node, i); + forEach(model, child, action); + } + } + + private static TreePath nodeToPath(TreeNode node) { + List nodes = new LinkedList(); + if (node != null) { + nodes.add(node); + node = node.getParent(); + while (node != null) { + nodes.add(0, node); + node = node.getParent(); + } + } + + return nodes.isEmpty() ? null : new TreePath(nodes.toArray()); + } + + @Override + public String toString() { + StringBuilder builder = new StringBuilder(); + builder.append("Tree Snapshot of: ").append(tree).append("\n"); + builder.append("Selected paths:\n"); + for (TreePath path : selectionPaths) { + builder.append("\t").append(path).append("\n"); + } + builder.append("Expanded paths:\n"); + for (TreePath epath : expanded) { + builder.append("\t").append(epath).append("\n"); + } + + return builder.toString(); + } +}