title: Calling method in Jframe from external class and thread to set label values
body: <p>I have two classes, one JFrame, and one external class that implements runnable.  The external class I would like to run in its own thread until given an order to stop.  I would also like it to update values on the JFrame in the background in its own thread via a method implemented within its class (or so this is how I thought the most elegant approach would be).</p>
  
  <p>I've made a simple program to illustrate what I'd like done and show that it doesn't work.  From what I understand, the JFrame's values are not updated when called from outside of the EDT.  I keep finding fixes that say to wrap the part of code in which you'd like to change text values in an <code>invokelater()</code> call.  However, this STILL doesn't work.  I'm really in a bind, and I'm sure it's something simple, I just can't see why this isn't working.</p>
  
  <p>In this simple example, I have a start button and output in the JFrame.  I instantiate my external class, and start it as a thread in the JFrame class when the start button is pressed.  The thread is in an external class and updates the output until it reaches 5.  It does this by calling a method in the JFrame that calls <code>setText()</code> on the output label.</p>
  
  <p>JFrame (I'll omit the automatically generated parts):</p>
  
  <pre><code>package javaapplicationtest;
  
  public class JavaTestForm extends javax.swing.JFrame {
  
  public JavaTestForm() {
      initComponents();
      jtf = new JavaExternClass();
      jtf_thread = new Thread(jtf);
  }
  
  /* Method I use outside of this class to update output label */
  public void setLabel(int in) {
      final int inf = in;
      System.out.println("Setting output to " + in);
  
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
              output.setText(Integer.toString(inf));
          }
      });
  }
  
  /* Start button is pressed */
  private void startActionPerformed(java.awt.event.ActionEvent evt)   {                                      
      javax.swing.SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
              jtf_thread.start();
          }
      });
  }   
  
  /* Main entry */
  public static void main(String args[]) {
      /* Create and display the form */
      java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
              new JavaTestForm().setVisible(true);
          }
      });
  }
  
  /* External class */
  private JavaExternClass jtf;
  private Thread jtf_thread;
  </code></pre>
  
  <p>My External Class:</p>
  
  <pre><code>package javaapplicationtest;
  
  import java.util.logging.Level;
  import java.util.logging.Logger;
  
  public class JavaExternClass implements Runnable {    
      public void run() {
          gui = new JavaTestForm();
          for (int i = 0; i &lt; 4; i++) {
              gui.setLabel(i); // Call method to set form output
              try {
                  Thread.sleep(1000);
              } catch (InterruptedException ex) {
                  Logger.getLogger(JavaTestForm.class.getName()).log(Level.SEVERE, null, ex);
              }
          }
      }
  
      private JavaTestForm gui;
  }
  </code></pre>