How can I expand the node to its root node?
So I have this method to expand its parent node recursively
private void expand( Object object ) {
if ( object.getParent() != null ) {
tree.setExpandedState( object.getParent(), true );
expand( object.getParent() );
}
}
Use the expandToLevel TreeViewer method:
viewer.expandToLevel(element, 1);
element can be your model element (the object your content provider provides) or it can be a TreePath. You may need to call setUseHashlookup(true) on the viewer to speed up element lookup.
Related
I am doing lazy loading for my app. I want a node to load only user click to it's icon. The point is i don't know that node have it's children or not.My temporary solution is to define a node having children then loading them based on selection event, i don't use tree will expand event for lazy loading. Is there any ways for me to just implement treeWillExpand event. You can reference in TreeWillExpanListener and TreeExpandEventDemo2.
// Have a tree with some unexpanded root items
// When an item is expanded, add some children
tree.addListener(new Tree.ExpandListener() {
public void nodeExpand(ExpandEvent event) {
// No children for the first node
if (!hasChildren(event.getItemId())) {
tree.setChildrenAllowed(event.getItemId(), false);
} else {
// Add a few new child nodes to the expanded node
tree.addItem(childId);
tree.setParent(childId, event.getItemId());
}
}
});
you can implement hasChildren to find the child based on tree node being expanded and then find child and add
Is it possible not to remove the node from the original PrimeFacesTree after dragging it? The default behaviour is that a node that was dragged and dropped in another place is removed. Can i prevent that from happening?
I'm using Primefaces 4.0
There isn't any premade attribute to duplicate node on dropEvent.
The solution is to add a listener to your <p:tree> element :
<p:tree listener="#{managingBean.onDragDrop}" />
Then you need to re-create node on initial location by duplicating it in your backbean method :
public void onDragDrop(TreeDragDropEvent event) {
TreeNode dragNode = event.getDragNode();
TreeNode dropNode = event.getDropNode();
int dropIndex = event.getDropIndex();
// Logic to repopulate initial Tree element
}
And don't forget to re-draw your tree
I want to copy a tree structure(source) to another one(target), but I got java.util.ConcurrentModificationException when I execute the method below:
private void mergeNode(TreeLayoutNode source, TreeLayoutNode target){
List<TreeLayoutNode> children = source.getChildren();
if(CollectionUtils.isEmpty(children)){
return;
}
Iterator<TreeLayoutNode> it = children.iterator();
while(it.hasNext()){
**TreeLayoutNode child = it.next();**
TreeLayoutNode copy = new TreeLayoutNode();
copy.setName(child.getName());
copy.setCapacity(child.getCapacity());
copy.setParent(child.getParent());
copy.setChildren(child.getChildren());
copy.setProportions(child.getProportions());
target.addChildNode(copy);
mergeNode(child, copy);
}
}
The code started with "**" is where exception occurs.Could any one give any hints?
Remove the call to 'copy.setChildren(child.getChildren())'. This results in references to children from the source tree being added to the destination tree, which is not what you want. The recursive method call will handle filling in the children.
Also you need to set the parent of the new node to the correct node in the new tree rather than calling 'copy.setParent(child.getParent())', which sets the parent reference to a node in the old tree. The call should probably be 'copy.setParent(target)'.
I'm using a JTree that is populated from a database.
The tree is created by setting the root node and its childs with custom objects this way:
private DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("Categorias");
...
ResultSet primaryCategories = dbm.fetchAllCategories();
while (primaryCategories.next()){
Category category = new Category(primaryCategories.getLong("_id"),
primaryCategories.getString("category"));
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(category);
rootNode.add(childNode);
ResultSet currentSubcategory = dbm.fetchChildSubcategories(category.getCatId());
while (currentSubcategory.next()){
Category subcategory = new Category(currentSubcategory.getLong("_id"),
currentSubcategory.getString("category"));
childNode.add(new DefaultMutableTreeNode(subcategory, false));
}
}
...
After this, the tree is perfectly created. Populated with "Category" Objects, every object has its own ID number and its name to use in toString() method.
The problem comes when it's set editable. Once the node is renamed, the Category node is also converted into a String Object, so I cant update the new Category name value to the database.
I've tried to capture the renaming event with treeNodesChanged(TreeModelEvent e) but, the userObject is already changed to a String Object, and can't get a referece of what object was edited.
What way can I solve this? Should I have a copy of the tree that's shown and another of the downloaded from the database and uptade both everytime a change occurs?
*PD: *
I also tried to capture the changed node from the model overriding the method:
public void nodeChanged(TreeNode newNode) {
DefaultMutableTreeNode parent = ((DefaultMutableTreeNode)newNode.getParent());
int index = getIndexOfChild(parent, newNode);
DefaultMutableTreeNode oldNode = (DefaultMutableTreeNode) getChild(parent, index);
System.out.println(parent.getUserObject().getClass().toString());
System.out.println(oldNode.getUserObject().getClass().toString());
}
this prints:
class com.giorgi.commandserver.entity.Category
class java.lang.String
So the old node here has already been changed to a String and I've lost completely the reference to the older Category and its ID so I cannot update it in the database.
Any help is wellcome.
Okay, that took a bit of digging.
Basically, when the editing is "stopped", the JTree will request the editor's value via editor's getCellEditorValue. This is then passed to the model via the valuesForPathChanged method, which finally calls the node's setUserObject method.
Presumably, you are using either the default editor or one based on text field. This will return a String value.
What you need to do is trap the change to the setUserObject method of your tree node, access the value coming (ie, check if it's a String or not) and update as required.
Final solution was as MadProgrammer said to get it in:
public void valueForPathChanged(TreePath path, Object newValue) {
DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)path.getLastPathComponent();
Category catNode = (Category) aNode.getUserObject();
catNode.setCategory((String) newValue);
catNode.updateFromDatabase();
nodeChanged(aNode);
}
I have a checkbox node tree build based on a named vector .
And i have a button called select all .
When i click the select all button , i need all the nodes on the chekbox node tree to be selected .
The code i have used is
for (CheckBoxNode rowNode: CheckBoxNodeTree. checkBoxCoulmn)
{
if(rowNode instanceof CheckBoxNode)
rowNode.setSelected((true));
}
Here checkBoxColumn is a arraylist which contains all the nodes of the tree as (Node , isSelected) .
But when i do this , nothing happens to the tree.
I've done it by casting the tree node to a default mutable tree node and get an enumeration of the children. Then you can iterate through them and setSelected(true). Your way could run into problems with threading or concurrent modifications if the user repeatedly clicks.
Enumeration<TreeNode> children = ((DefaultMutableTreeNode) node).breadthFirstEnumeration();
while (children.hasMoreElements()) {
TreeNode child = children.nextElement();
Object currentNode = ((DefaultMutableTreeNode) child).getUserObject();
//cast your currentNode to the check box and set selected or unselected.
}
Also, are you doing this on the event dispath thread? If not that might be why you aren't seeing any updates to the screen.