• Post Reply Bookmark Topic Watch Topic
  • New Topic

JTree leaf contents update - problem :(  RSS feed

 
Martin Asenov
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello, I just wrote some code that tries to construct a JTree that represents the contents of a certain directory (in this case "C:/Test Games/"), and it does. I've got a background thread that listenes for consistency changes, and when such occur, it has to update the tree. Because searching for the specific changes would be painful, I delete all the existing nodes in the root node, that is not displayed and reinitialize it again. But I experience problems with the listener. Does it get notified when the consistency changes? I tried to write different things inside it, but didn't manage to do anything that would solve the problem.

Here is my code:



Any help would be highly appreciated! Thank you in advance!

Best regards,

Martin Asenov
 
Miklos Szeles
Ranch Hand
Posts: 142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Martin,

The java tutorial says:
Note that although DefaultMutableTreeNode has methods for changing a node's content, changes should go through the DefaultTreeModel cover methods

You should check DefaultTreeModel and use it's methods to mainpulate the tree.
 
Martin Asenov
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Miklos! But,

I inserted on line 33 the following :



and changed the implementation of the listener in that way:



And nothing really changes. Would you please give me some further assistance on that issue.

Thanks in advance!
 
Miklos Szeles
Ranch Hand
Posts: 142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Martin,

I think you misunderstood this. It says that your treeChange listener won't be called since you not used DefaultTreeModel's method to manipulate the tree. Please check the documentation of DefaultTreeModel and use it's methods to manipulate the tree instead of calling DefaultMutableTreeNode's methods.
One other solution would be to simply create a new DefaultTreeModel when something changes and the call tree.setModel() to set the new model.
 
Miklos Szeles
Ranch Hand
Posts: 142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I also advice to make "stopped" variable volatile. Without volatile keyword it is possible that the value of the variable will be cached. In that case it is possible that your thread won't see the change of stopped variable.
 
Rob Spoor
Sheriff
Posts: 20903
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Martin Asenov wrote:

And nothing really changes.

That's because treeNodesChanged events are fired by the TreeModel, not by the nodes. It's the calling of nodeStructureChanged that will trigger the event. In fact, if this event is ever triggered you will trigger it again, and again, and again, and again, until you get a StackOverFlowError.

You should do the following:
1) keep a reference to the DefaultTreeModel
2a) don't modify your DefaultMutableTreeNodes directly but through the model:
or 2b) after modifying your root update the model:
I think the second one is better; not only is it easier to understand, it also only fires one single event instead of one for each removal and again one for each addition.

You see that the event must be fired from the code that actually modifies the node. This causes, in the end, to call one of the methods of the TreeModelListener. And there's another problem for you which you haven't even noticed - you have a concurrency problem.

The execution of the event listener should be handled on the Event Dispatcher Thread (EDT). However, that means that the events must be fired from the EDT, and in your code they are fired from your own thread. You must make sure that the events are fired from the EDT using EventQueue.invokeLater (note: SwingUtilities.invokeLater simply delegates to EventQueue, so you can use that one too). However, just firing the event from the EDT may still lead to race conditions when accessing the root node - that's modified from your thread and read from the EDT. The following code will be safe to work with:
Since you are working with a shadow copy of the root node that you do not edit anymore from your thread after adding the nodes there are no synchronization problems - your thread hands over all control over the root node to the EDT, so there is only one thread handling it at any given time.
 
Martin Asenov
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Miklos! It worked ... using the latter way. However, if I had to use the same DefaultTreeModel, I presume I had to call the "fire" method?!

BR,

P.S. Thank you very much, Rob, for the extensive answer. Keep it in the same way. Unfortunately not many people like to explain in the way you do...
 
Miklos Szeles
Ranch Hand
Posts: 142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No. Just read Rob's post, he answers every questions and he also draws our attention to a very important concurrency problem.

I've noticed you modified your previous post(after reading Rob's post), so please forget this one.

Unfortunately not many people like to explain in the way you do...

I'm relatively new in this community, but I think the only reason for this is that the main rules of this community dictates not give full/ready to use solutions but to get the askers thinking. Lead them toward the right way and let them find the solution for their problems. As I see several of the questions appear here since the poster haven't read (carefully) the API documentation, Java tutorial, .... In this case I think it's better to post a link, or ask the user to read the documentation instead of answering the question.
 
Martin Asenov
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miklos Szeles wrote:No. Just read Rob's post, he answers every questions and he also draws our attention to a very important concurrency problem.

I've noticed you modified your previous post(after reading Rob's post), so please forget this one.

Unfortunately not many people like to explain in the way you do...

I'm relatively new in this community, but I think the only reason for this is that the main rules of this community dictates not give full/ready to use solutions but to get the askers thinking. Lead them toward the right way and let them find the solution for their problems. As I see several of the questions appear here since the poster haven't read (carefully) the API documentation, Java tutorial, .... In this case I think it's better to post a link, or ask the user to read the documentation instead of answering the question.


Yes, Miklos, I agree. I have read this sun tutorial before. But I was unable to reveal the idea. I don't underestimate your answer, I asure you of this. Anyway, thank you both for the replies and the help, you helped me to undesrtand many things in a really short time.
 
Rob Spoor
Sheriff
Posts: 20903
81
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Miklos Szeles wrote:I think the only reason for this is that the main rules of this community dictates not give full/ready to use solutions but to get the askers thinking. Lead them toward the right way and let them find the solution for their problems.

That's right. However, Swing is quite complex, so sometimes the only reason to get the message across is by using examples. And in this case, my examples would be identical to the actual solution. The important thing though is in those cases teaching the original poster why it works this way, and that's what I usually try.

As I see several of the questions appear here since the poster haven't read (carefully) the API documentation, Java tutorial, .... In this case I think it's better to post a link, or ask the user to read the documentation instead of answering the question.

You're actually right. Therefore I think that Martin should still read the following two links, even though the code probably already is working:
http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html
http://java.sun.com/docs/books/tutorial/uiswing/concurrency/index.html
 
Miklos Szeles
Ranch Hand
Posts: 142
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're welcome Martin.

Thanks Rob, for clarifying things. I'm a new "question answerer" so I really appreciate any comment which leads me to the right direction in answering questions.(I've already read the FAQ about this).
Have a nice day
 
Martin Asenov
Ranch Hand
Posts: 34
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, both!

Anyway, some of the Sun's tuts look quite uncomprehensable to me, so there are some things that need to be asked directly.

Thank you again! Bye!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!