title: Update java UI by different threads
body: <p>I order to develop a swing application, I am using a simplified version of the <em>MVC</em> pattern, in which the controller is interposed between the view and the model in both directions:</p>
  
  <ul>
  <li>when the user interacts with a swing control, if this interaction requires access to the model, then the event raised by the swing control calls for an appropriate method of controller;</li>
  <li>when the view should be updated after a model update, the controller invokes one or more public methods of the view.</li>
  </ul>
  
  <p>A complex application may request different threads running: for example, if you must write a file on disk, you could start a background thread, and at the end of the writing of the file, this thread should send a notification to view via the controller. In this case, it may happen that more than one thread wants to refresh the view, so I assume that this issue should be handled in some way.</p>
  
  <p>I took inspiration from <a href="https://stackoverflow.com/a/7237224/364056">this answer</a> in order to write the methods <code>appendText</code> and <code>updateLastText</code> of the following <a href="http://www.sscce.org/" rel="nofollow noreferrer">SSCCE</a>.</p>
  
  <pre><code>public class NewJFrame extends javax.swing.JFrame {
  
      private volatile String lastText;
  
      /**
       * Creates new form NewJFrame
       */
      public NewJFrame() {
          initComponents();
      }
  
      /**
       * This method is called from within the constructor to initialize the form.
       * WARNING: Do NOT modify this code. The content of this method is always
       * regenerated by the Form Editor.
       */
      @SuppressWarnings("unchecked")
      // &lt;editor-fold defaultstate="collapsed" desc="Generated Code"&gt;                          
      private void initComponents() {
  
          jScrollPane1 = new JScrollPane();
          jTextArea1 = new JTextArea();
  
          setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
  
          jTextArea1.setEditable(false);
          jTextArea1.setColumns(20);
          jTextArea1.setRows(5);
          jScrollPane1.setViewportView(jTextArea1);
  
          getContentPane().add(jScrollPane1, BorderLayout.CENTER);
  
          pack();
      }// &lt;/editor-fold&gt;                        
  
  
      // Variables declaration - do not modify                     
      private JScrollPane jScrollPane1;
      private JTextArea jTextArea1;
      // End of variables declaration                   
  
      /**
       *
       * @param text
       */
      public void appendText(final String text) {
          updateLastText(text);
          SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                  jTextArea1.append(String.format("%s\n", lastText));
              }
          });
      }
  
      /**
       *
       * @param text
       */
      private synchronized void updateLastText(String text) {
          lastText = text;
      }
  
      /**
       * @param args the command line arguments
       */
      public static void main(String args[]) {
  
          final NewJFrame frame = new NewJFrame();
  
          /* Create and display the form */
          java.awt.EventQueue.invokeLater(new Runnable() {
              @Override
              public void run() {
                  frame.setVisible(true);
              }
          });
  
          Thread counter = new Thread() {
              @Override
              public void run() {
                  for (int i = 0; i &lt; 10; i++) {
                      try {
                          Thread.sleep(1000);
                      } catch (InterruptedException ex) {
                          Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
                      }
                      frame.appendText((new Date()).toString());
                  }
              }
          };
          counter.start();
      }
  }
  </code></pre>
  
  <p>The above solution seems to work properly, so should I use the same technique to update other swing component of the UI? Or is there a more compact solution?</p>