Skip to main content

JTreeTable: How to navigate to the parent?

6 replies [Last post]
siva
Offline
Joined: 2003-07-15
Points: 0

Hi, in case of a JTree, when a node is deleted, it's easy to navigate to the parent by coding something like

DefaultMutableTreeNode oldSelectedItem = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
DefaultMutableTreeNode newSelectedItem = (DefaultMutableTreeNode)oldSelectedItem.getParent();
tree.setSelectionPath(new TreePath(newSelectedItem.getPath()));

How do I do the same with JTreeTable?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
rameshgupta
Offline
Joined: 2004-06-04
Points: 0

> Hi, in case of a JTree, when a node is deleted, it's
> easy to navigate to the parent by coding something
> like
>
> DefaultMutableTreeNode oldSelectedItem =
> =
> (DefaultMutableTreeNode)tree.getLastSelectedPathCompon
> ent();
> DefaultMutableTreeNode newSelectedItem =
> (DefaultMutableTreeNode)oldSelectedItem.getParent();
> tree.setSelectionPath(new
> TreePath(newSelectedItem.getPath()));
>
> How do I do the same with JTreeTable?

How do you plan to delete rows from a treetable? DefaultTreeTableModel does not define methods to delete rows. Did you define your own model class or subclass the default impl to provide this feature?

Ramesh

siva
Offline
Joined: 2003-07-15
Points: 0

Here is how I coded deleting a node.

public void deleteNode(MyNode node) {
MyNode parent = (MyNode)node.getParent();
if(parent == null) return;
int indexes[] = new int[1];
indexes[0] = parent.getIndex(node);
Object objs[] = new Object[1];
objs[0] = node;
node.removeFromParent();
fireTreeNodesRemoved(parent,parent.getPath(),indexes,objs);
}

where deleteNode is a member function of my TreeTable model. This works fine. That is, it deletes the node and updates the UI. However, my selection doesn't move to the parent as I don't know how to do that.

rameshgupta
Offline
Joined: 2004-06-04
Points: 0

> Here is how I coded deleting a node.
>
> public void deleteNode(MyNode node) {
> MyNode parent = (MyNode)node.getParent();
> if(parent == null) return;
> int indexes[] = new int[1];
> indexes[0] = parent.getIndex(node);
> Object objs[] = new Object[1];
> objs[0] = node;
> node.removeFromParent();
>
>
>
>
> fireTreeNodesRemoved(parent,parent.getPath(),indexes,
> objs);
> }
>
> where deleteNode is a member function of my TreeTable
> model. This works fine. That is, it deletes the node
> and updates the UI. However, my selection doesn't
> move to the parent as I don't know how to do that.

Oh. Unfortunately, you will have to add some code in JXTreeTable.TreeTableModelAdapter to make this work right now :-( I'm still thinking of a good way to open up this feature in a way so that this can be cleanly supported through a public api. Meanwhile, ...

The constructor for TreeTableModelAdapter has references to both the tree model and the tree. It installs an anonymous TreeModelListener that responds to treeNodesRemoved(...) by calling delayedFireTableDataChanged(), but in the process, throws away the TreeModelEvent that carries important information in this case.

So, ...

In treeNodesRemoved(), extract the parent's path from the TreeModelEvent, and call tree.getRowForPath(parentPath) to get the row index in the tree/table. Finally, call treeTable.setRowSelectionInterval(index, index).

Hope this works for you! Could you please also file a new issue describing this in our bug database?

Thanks.

Ramesh

siva
Offline
Joined: 2003-07-15
Points: 0

I filed an issue for this. In the interim, here is how I implemented this without touching the JXTreeTable's code. This is not a good scalable implementation as I essentially keep looping back to find the parent's row, but for now I will use it in my code.

TreeNode parent = node.getParent();
deleteNode(node);
TableModel tableModel = getModel();
for(int i=selectedRow;i>=0;i--) {
if(tableModel.getValueAt(i,0) == parent) {
changeSelection(i,0,false,false);
break;
}
}

Also, though it was strongly adviced not to get the table model adapter using the getModel(), I am assuming piece of code doesn't violate anything.

rameshgupta
Offline
Joined: 2004-06-04
Points: 0

> I filed an issue for this. In the interim, here is
> how I implemented this without touching the
> JXTreeTable's code. This is not a good scalable
> implementation as I essentially keep looping back to
> find the parent's row, but for now I will use it in
> my code.
>
> TreeNode parent = node.getParent();
> deleteNode(node);
> TableModel tableModel = getModel();
> for(int i=selectedRow;i>=0;i--) {
> if(tableModel.getValueAt(i,0) == parent) {
> changeSelection(i,0,false,false);
> break;
> }
> }
>
>
> Also, though it was strongly adviced not to get the
> table model adapter using the getModel(), I am
> assuming piece of code doesn't violate anything.

As long as you don't pass the handle of the table model adapter to another table/treetable, you should be fine. However, since you are performing view-related operations here, be aware that accessing data directly through the model might give you different results depending on whether there are any filters attached to the view or not.

Ramesh

siva
Offline
Joined: 2003-07-15
Points: 0

Haven't got any answer. Hmm, either this must be too simple for people to bother responding or currently there is no way to do it.