title: Swing, Passive View and Long running tasks
body: <p>I'm trying to implement a <a href="http://martinfowler.com/eaaDev/PassiveScreen.html" rel="nofollow noreferrer">Passive</a> <a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/05/30/build-your-own-cab-part-4-the-passive-view.aspx" rel="nofollow noreferrer">View</a> based gui system in swing. Basically i want to keep my view implementation (the part that actually contains swing code) minimal, and do most of the work in my Presenter class. the Presenter should have no dependency on swing and also should "run the show", i.e. tell the view what to do and not vice versa.</p>
  
  <p>I run into problems when dealing with long running tasks, and threads separation in general. I want GUI updates to run on the EDT, and the presenter logic to run on a different thread. If i want the presenter to update some part of the GUI it's pretty easy, i write something like that:</p>
  
  <pre><code>public interface View {
      void setText(String text);
  }
  
  public class Presenter {
      View view;
      ...
      public void setTextInVIew() {
          view.setText("abc");
      }
  }
  
  public class MyFrame implements View {
      JTextField textField;
      ...
      public void setText(final String text) {
          SwingUtilities.InvokeLater(new Runnable() {
              public void run() {
                  textField.setText(text);
              }
          });
      }
  }
  </code></pre>
  
  <p>However, when the GUI is to inform the presenter that some action has occurred, i want to switch out of the EDT in react to it in a different thread:</p>
  
  <pre><code>public class Presenter {
      ...
      public void buttonPressed() {
           // shouldn't run on EDT
      }
  }
  
  public class MyFrame implements View {
      JButton button;
      public MyFrame() {
          ...
          button.addActionListener(new ActionListener() {
              @Override public void actionPerformed(ActionEvent e) {
                  presenter.ButtonPressed();
              }
          });
      }
  }
  </code></pre>
  
  <p>since the actionPerformed code is running from the EDT, so will the presenter.buttonPressed. I know swing has the concept of SwingWorker - running tasks in a different thread, however it looks like i'll have to insert swing code into my presenter, and the view is running the show. Any ideas how to solve this?</p>