3

I am using dom4j to create a DocumentTreeModel from a dom4j document.

I display this DocumentTreeModel inside JScrollPane.

I have a button that adds a new node to the dom4j document, and recreates the DocumentTreeModel

I am using getPathForRow but this seems pretty limited. I need to be able to work with multiple tree depth. Basically looking for something like tree.getPathOfLastModifiedChildrensParent()

onAddNewNodeButtonClickEventFired {
   dom4jdocument.addElement( "1" );                               
   tree.setModel(new DocumentTreeModel(dom4jdocument));                                
   tree.expandPath(tree.getPathForRow(1));                             
}  

Basically I am trying to get the Jtree to redraw the document everytime document is edited.

jzd
  • 23,473
  • 9
  • 54
  • 76
KJW
  • 15,035
  • 47
  • 137
  • 243
  • I see this question is from last year but have you considered implementing `TreeModel`? This should give you the possibility of keeping track of element changes in the dom4j document. – James P. Apr 11 '12 at 11:50
  • 1
    @JamesPoulson, oh yes...shortly after asking this question I used TreeModel. – KJW Apr 12 '12 at 04:28
  • Glad to hear that. It works great on my side. The only issue I have is the tree collapsing when I send a treeStructureChanged event to listeners. For usability the tree should stay open. – James P. Apr 13 '12 at 13:47

2 Answers2

3

Seeing you setting a new model whenever you edit the document looks like you still don't have the notification running, right? If so, you don't need any special method on the JTree - what you need is a well-behaved implementation of TreeModel ;-)

Just for fun, I looked up the DocumentTreeModel: that's an extremely small cover on top of DefaultTreeModel with no support whatever to glue changes in the Document to changes in the DocumentTreeModel. The fact that the Leaf-/BranchTreeNode implement TreeNode only (as opposed to going a step further and implement MutableTreeNode) even disables the models helper methods to insert/remove node. Short story: all the hard work is left to you.

Basically, you have to make the treeModel aware of any change in the underlying Document. Something like (pseudo-code):

 DocNode newElement = document.addElement(...)
 DocNode parentElement = newElement.getParent();
 // walk the tree until you find the TreeNode which represents the DocNode
 BranchTreeNode root = treeModel.getRoot();
 BranchTreeNode parentNode = null;
 forEach (root.child)
     if child.getXMLNode().equals(parentElement)
          parentNode = child;
 // now find the childNode which corresponds to the new element
 forEach (parentNode.child)
    if (parentNode.child.getXMLNode().equals(newElement)
         childNode = child;
 // now notify the treeModel that an insertion has happened
 treeModel.nodesWhereInserted(parentNode, childNode ...)

Hmm ... in your shoes I would look for a more comfortable implementation, can't believe that there isn another implementation around somewhere?

CU Jeanette

kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • yeah im not sure if it exists....dom4j.swing is really good but it seems like I ahve to implement all those plumbing code. – KJW Apr 11 '11 at 09:13
  • the base problem seems to be that there's no way the model itself can keep track of changes in the document because the document doesn't support notification. One way out is to add those plumbing into the DocumentTreeModel and do all changes to the Document only through those plumbing code. Not very robust, though. Another might be to find a dom implementation which supports EventTarget, then the treeModel could listen to its changes (there's a DOMTreeModel by Piet Blok which does it) No happy coin ;-) – kleopatra Apr 11 '11 at 09:29
  • http://www.pbjar.org/docs/src/org/pbjar/dom/DOMTreeModel.java that is the correct one yes ? This seems like what I was looking for but you say that there's a problem with this ? – KJW Apr 12 '11 at 09:42
  • no problem as such - but you'll need a dom implementation which supports EventTarget. With one of those (like the default that comes with the jdk, which is xerces (? I think)) the nofification is working smoothly. The price to pay is a more complex element processing as compared to dom4j (beware: I'm far from being a dom expert - my job is Swing/X :-) due to supporting mixed content. – kleopatra Apr 12 '11 at 11:10
  • just noticed: the "nofification" handling in DOMTreeModel is rather coarse-grained. It listens to DOMSubTreeModified only and reacts by firing a nodeStructureChanged which has undesirable side-effects, like f.i. collapsing all siblings. So there's work ahead: a) change install to listen to more fine-grained notifications from the DOM b) change handleEvent to react accordingly. – kleopatra Apr 13 '11 at 14:30
  • is there a sample code of that ? I am not sure whether you mean to continue using dom4j or xerces? – KJW Apr 19 '11 at 20:39
1

Try - tree.revalidate(); It should refresh the component tree.

Manish
  • 11
  • 1