3

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?

Lahiru Ashan
  • 767
  • 9
  • 16
D-Dᴙum
  • 7,689
  • 8
  • 58
  • 97

2 Answers2

3

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.

John Vint
  • 39,695
  • 7
  • 78
  • 108
  • thanks for your quick reply. Would you have any references saying that this is a correct way to proceed? – D-Dᴙum Feb 02 '12 at 19:36
  • I found that in this question posted: http://stackoverflow.com/questions/5895481/update-jlabel-from-another-thread – John Vint Feb 02 '12 at 19:38
3

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,

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Concerning your #2 TreeModel is not thread safe to my knowledge. So, modifying the existing one it from another thread(s) should be considered a bad programming practice. – Oleg Mikheev Feb 02 '12 at 19:44
  • @ʘleg your `considering for bad programming practice` could be default way how to add/update DefaultXxxModel from the Background Task to ther Swing GUI – mKorbel Feb 02 '12 at 19:47
  • Modification of not threadsafe objects from other threads being the default way is not my problem :) – Oleg Mikheev Feb 02 '12 at 19:53
  • I don't think that _.`getModel` from current `JTree`_ returns an `AbstractXxxModel`... – Oleg Mikheev Feb 02 '12 at 20:00