Hiding/filtering nodes in a JTree? - java

I have a data object represented in a TreeModel, and I'd like to show only part of it in my JTree--for the sake of argument, say the leaves and their parents. How can I hide/filter the unnecessary nodes?

My eventual implementation:
Have two TreeModels, the underlying one and the filtered one.
When a change occurs on the underlying TreeModel, rebuild the filtered TreeModel from scratch. Clone each node that should be visible, and add it to its first visible ancestor in the filtered TreeModel (or the root if none are visible). See teh codez below, if you're curious.
This has the unfortunate side effect of collapsing every path the user had open. To get around this, I added a TreeModelListener to the filtered TreeModel. When the model changes, I save the expanded paths in the JTree (using getExpandedDescendants()), then re-expand them later (using SwingUtilities.invokeLater()).
I had to override equals() in the TreeNode class I was using so that the new cloned nodes would be the same as the old cloned nodes.
...
populateFilteredNode(unfilteredRoot, filteredRoot);
...
void populateFilteredNode(TreeNode unfilteredNode, TreeNode filteredNode)
{
for (int i = 0; i < unfilteredNode.getChildCount(); i++)
{
TreeNode unfilteredChildNode = unfilteredNode.getChildAt(i);
if (unfilteredChildNode.getType() == Type.INVISIBLE_FOLDER)
{
populateFilteredNode(unfilteredChildNode, filteredNode);
}
else
{
TreeNode filteredChildNode = unfilteredChildNode.clone();
filteredNode.add(filteredChildNode);
populateFilteredNode(unfilteredChildNode, filteredChildNode);
}
}
}

You should be aware of GlazedLists. It's a fantastic library for doing complex table transformations with little effort. They've also expanded to trees too. It may require a little refactoring of your existing code to get it into the GlazedLists way of working. But check out the demo and the webcasts to see how powerful it is. (It's one of the essential Swing libraries in my view, and it's open source.)

Have you tried JXTree ? (unfortunately the website is down right now, but you can google for mirrors)

Take a look at this implementation: http://www.java2s.com/Code/Java/Swing-Components/InvisibleNodeTreeExample.htm
It creates subclasses of DefaultMutableNode adding a "isVisible" property rather then actually removing/adding nodes from the TreeModel.

If you're looking for a commercial solution, JideSoft has a filterable treemodel. Other than that, SwingX has a Filter API which'll work on JXTable, JXTreeTable, JXTree, and JXList.

So long as it is still a tree you are displaying, then TreeModel that filters you existing TreeModel should be simple enough.

Leverage the code you use to build your TreeNode(s) and rebuild the TreeNode(s) only including the elements you want. Set the root node on the TreeModel with the filtered root node.

Related

JavaFX TreeView remember last selected item after refresh

I develop a JavaFX GUI application and I have a problem with a node called "TreeView". My tree should represent a file structure inside a specific directory. The user is supposed to conduct some typical operations on those files like copying, removing or renaming them.
After that happens, I'd like the tree to be refreshed (it means that it is supposed to load once again the structure from the file system). The issue is that, once it is done, the selection on one of the tree items is lost and every directory is collapsed. I would like the selection to be persistent, and all the parent directories to be expanded, even after the content of the tree has been refreshed.
I've tried numerous solutions so far to address this issue, but none of them let me select the same tree item (apart from the deleting operation of course) and expand all needed roots as before. My question is, how can this be achieved? I guess the main problem here is the fact, that I load all the data once again and therefore my new tree items do not match with the "old" ones.
I would appreciate all hints that you can give me in that matter.
I tried to save the item with getSelectionModel() and then set it, it doesn't select the same item as before (it ignores that directories are not expanded).

Given a Node, how can I select the equivalent Node in a Document?

My caller is handing me an org.w3c.dom.Node and an org.w3c.dom.Document that serves as its owner document. The supplied Node, in other words, is guaranteed to be parented in the supplied Document, and represents the Node in that Document against which some work should be performed.
I am now in a position where I need to effectively clone the Document (I need to perform modifications, and cannot modify the source.)
Obviously, if I do that, the Node I still have in my hand is not owned by the new Document resulting from the clone. I have now effectively lost the selection in the cloned Document.
However, I know that there will be a Node in that cloned document that is exactly equal to the Node I have in my hand. I need to find it.
What is the best way to accomplish this, short of plowing through the whole Document and calling isEqualNode(Node) on each one?
I thought perhaps there would be some way to say document.find(myUnparentedNode), but no such method exists.
you could generate an XPath that describes the position of the node in the old document and then apply that to the new document. See this SO question for approaches how to do that.
If it's possible for you to modify the node before cloning just give it a unique attribute that doesn't collide with anything else (e.g. generated randomly) that you can then locate in the cloned document.
If it already has an id, just use that.

XML Document traversal in java

which is the most preferable xml document traversal method in java ? Using getElementsByTagName or using TreeWalker .
I've one TreeModel. a Dom Node is the root of the TreeModel. There are two Threads adding nodes to it. One Thread is adding nodes according the nodes added by the other Thread.
e.g.
One Thread adding Nodes named App. The other Thread adding nodes according to the name attribute of the Nodes named App. Sometimes the nodes are not added correctly. The TreeModel only shows the details in the elements by traversing through the nodes.
Note: Adding the App Node is according to the Name attribute of the Node.
Currently for the second Thread, the Nodes are taken by calling getElementsByTagName. Is there any advantage by changing it to TreeWalker ?
I like XPath. W3schools link here, Javadocs here. It is tedious to get started with factories and builders, IMO write your own utility class to save on that tedium. But the syntax to traverse around is expressive and powerful, and it is a "standard" with good documentation.
If you are brave, check out my beta Groovy-like xpath-like project, but I would not propose this as "the most preferable". :-)
ADDED: XPath is a query language for selecting nodes from an XML document. It is good for traversing (moving around in) a DOM structure. However, OP's updated requirements are for manipulating / modifying the DOM structure. XPath is not a good fit there.

How can I find all nodes with a specific label using the Java API in Neo4j 2.0.x?

I need to find a specific node in the entire graph using the Java low level API. I used to do this using the Reference node in versions 1.x but that concept has been removed with the 2.0 release.
I thought I could use labels to do this: I would assign a label to this node (and only this node) when it is created. Subsequently I would get all the nodes with this particular label, which should return a single hit, ie the special node I'm looking for. Unfortunately I can't find a way to look up all nodes having a specific label using the Java API.
I am able to do it with Cypher but I'd like this look up to be as fast as possible, so saving the cost of query parsing, planning and execution would be great.
This method GlobalGraphOperations.getAllNodesWithLabel(Label label) returns all nodes with the specified label.
You can use GlobalGraphOperations.at(gdb).getAllRelationshipTypes() to get all nodes with the label, and gdb is your graph database.
The provided answer is deprecated. The preferred method is now to use: GraphDatabaseService.findNodes(Label label)
GraphDatabaseService.findNodesByLabelAndProperty (Label label, String propName, String propValue) might suit your bill....
or you could save the id of the node when you create it initially, then you can call GraphDatabaseService.getNodeById(long id) - which would be, by far, the fastest way to retrieve a specific node.

Creating Multiple Child Nodes in XML for Java

I need to create multiple Child Nodes in one element node in XML, do I just append as many times as required to create these nodes? Like this:
rootElement.appendChild(creator);
creator.appendChild(name);
creator.appendChild(email);
creator.appendChild(name);
creator.appendChild(email);
Or does java automatically create the extra child nodes whenever I do this:
name.appendChild(doc.createTextNode("Bob"));
email.appendChild(doc.createTextNode("bob#email.com"));
name.appendChild(doc.createTextNode("Smith"));
email.appendChild(doc.createTextNode("smith#email.com"));
I'm not too sure how it works, any advice or help would be appreciated!
Behavior varies across different implementations, but in general you want to go with the second approach.
When appending or adding a child to a parent the previous parent is replaced. This means that the first approach does nothing but shuffle the same to children. The second approach is correct because you create new children as you go and the previously added children remain untouched by later API calls.

Categories

Resources