The Artima Developer Community
Sponsored Link

Java Buzz Forum
Foxtrot - Api for Threading in Swing apps

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Sam Dalton

Posts: 143
Nickname: samd
Registered: Jun, 2003

Sam Dalton is a Java Developer with ThoughtWorks in teh UK
Foxtrot - Api for Threading in Swing apps Posted: Aug 3, 2004 3:48 AM
Reply to this message Reply

This post originated from an RSS feed registered with Java Buzz by Sam Dalton.
Original Post: Foxtrot - Api for Threading in Swing apps
Feed Title: import java.*;
Feed URL: http://www.samjdalton.com/pebble/rss.xml
Feed Description: Random, Infrequent Bloggings of a Techie
Latest Java Buzz Posts
Latest Java Buzz Posts by Sam Dalton
Latest Posts From import java.*;

Advertisement

Having done some pretty hardcore Swing work over the last few months, I have come across the problem of "Gui Freeze" quite a lot. This is the situation where you click a button and the Gui freezes becuase the listener for the button performs a relatively long running task.
Obviously the way around this is to use threading and have you listeners return as soon as possible. This comes with its own problems in that Gui updates need to be processed on the Event Dispatcher thread. This necessitates the use of the SwingUtilities.invokeLater() method. All of this works just fine, but can result in some nasty looking code that is hard to read, and even harder to maintain! Typically, Swing developers have used the SwingWorker utility class to cope with the creation and management of worker threads to perform long running tasks. An example of this in use is:

public class AsyncExample extends JFrame
{
   public static void main(String[] args)
   {
      AsyncExample example = new AsyncExample();
      example.setVisible(true);
   }

   public AsyncExample()
   {
      super("SwingWorker Example");

      final JButton button = new JButton("Take a nap !");
      button.addActionListener(new ActionListener()
      {
         public void actionPerformed(ActionEvent e)
         {
            button.setText("Sleeping...");

            new SwingWorker()
            {
               protected Object construct() throws Exception
               {
                  Thread.sleep(10000);
                  return "Slept !";
               }
               protected void finished()
               {
                  try
                  {
                     String text = (String)get();
                     button.setText(text);
                  }
                  catch (InterruptedException ignored) {}
                  catch (InvocationTargetException x)
                  {
                     // Do exception handling
                     Throwable t = x.getException();
                     if (t instanceof InterruptedException) ...
                     else if (t instanceof RuntimeException) ...
                   &nb 8 sp;& 1ff8 nbsp;else if (t instanceof Error) ...
                  }
               }
            }.start();

            somethingElse();
         }
      });

      setDefaultCloseOperation(EXIT_ON_CLOSE);

      Container c = getContentPane();
      c.setLayout(new GridBagLayout());
      c.add(button);

      setSize(300,200);

      Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
      Dimension size = getSize();
      int x = (screen.width - size.width) >> 1;
      int y = (screen.height - size.height) >> 1;
      setLocation(x, y);
   }
}

As you can see this is pretty nasty code.

  • There are lots nested if-then-else statements to deal with exception handling
  • the two calls to setText are asymetric (one is made outside of the worker, and one within the worker)
  • SwingWorker.start() is always executed before the worker completes (as the event dispatch thread is released as soon as the worker starts)
  • a nested SwingWorker would be required if you wanted to perform another time consuming operation in the finished() method

Foxtrot solves all of these issues for us. Below is the same example written using the Foxtrot Api:

public class FoxtrotExample extends JFrame
{
   public static void main(String[] args)
   {
      FoxtrotExample example = new FoxtrotExample();
      example.setVisible(true);
   }

   public FoxtrotExample()
   {
      super("Foxtrot Example");

      final JButton button = new JButton("Take a nap !");
      button.addActionListener(new ActionListener()
      {
         public void actionPerformed(ActionEvent e)
         {
            button.setText("Sleeping...");

            String text = null;
            try
            {
               text = (String)Worker.post(new Task()
               {
                  public Object run() throws Exception
                  {
                     Thread.sleep(10000);
                     return "Slept !";
                  }
               });
            }
            catch (Exception x) ...

            button.setText(text);

            somethingElse();
         }
      });

      setDefaultCloseOperation(EXIT_ON_CLOSE);

      Container c = getContentPane();
      c.setLayout(new 8 &nbs 1ff8 p;GridBagLayout());
      c.add(button);

      setSize(300,200);

      Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
      Dimension size = getSize();
      int x = (screen.width - size.width) >> 1;
      int y = (screen.height - size.height) >> 1;
      setLocation(x, y);
   }
}

As you can see this code is a lot simpler and it is far easier to see what is going on. For example:

  • Both setText() calls are within the listener
  • The code after the Worker.post is always executed after the timeconsuming task.
  • There is no nesting required for multiple tasks, simply place another Worker.post after the first one.

This is all achieved with some clever re-routing of the Swing Event thread so that is does not return before the timeconsuming task has completed, which is the same way that Modal dialogs are handled within the Swing Api.

Read: Foxtrot - Api for Threading in Swing apps

Topic: Bosworth Bails Out, Leaves BEA Systems for Google, Inc. Previous Topic   Next Topic Topic: Why do we drive manual/stick shifts?

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use