Reputation: 7890
Please consider the following code:
public class MyClass extends javax.swing.JFrame {
private JTree jTree;
//Code ommited for clarity
public void methodCalledByAnotherThread(){
final DefaultTreeModel t = new DefaultTreeModel();
//Do some thing with t
SwingUtilities.invokeLater(new Runnable(){
public void Run(){
jTree.setModel(t);
}
});
}
}
MyClass
is created and executed on the Swing thread. Some time during its execution it starts a second thread which will eventually call the methodCalledByAnotherThread()
. Not this method will NEVER be called on the Swing thread.
methodCalledByAnotherThread()
creates a (local) DefaultTreeModel
object and does some work with it but because this is NOT on the Swing thread it cannot set the model into jTree
hence the call to SwingUtilities.invokeLater()
. In the Runnable object , which is executed on the Swing thread, it sets the LOCAL DefaultTreeModel
t into the JTree
.
My question is (and I haven't actually compiled and run this code yet so it may not work).. is the above BAD programming practice? If so how can I set a TreeModel
created on a NON-Swing thread into a Swing object?
Upvotes: 3
Views: 284
Reputation: 109813
1) don't extends javax.swing.JFrame
more in Composition versus Inheritance, e.i.
2) better would be getModel
from currnet JTree
instance rathen than recreate DefaultTreeModel
on runtime and maybe with un_know life cycle
3) correct is that you adding model
by wrapping into invokeLater
, sugestion easiest way is from Runnable#Thread
, better from SwingWorker
,
Upvotes: 3
Reputation: 40256
That looks fine (in fact its the best way to do it). So long as //Do some thing with t
does not include any elements that are already displayed on the UI.
Upvotes: 3