<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FJDK_6%2FSwing_Worker</id>
		<title>Java/JDK 6/Swing Worker - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://jexp.ru/index.php?action=history&amp;feed=atom&amp;title=Java%2FJDK_6%2FSwing_Worker"/>
		<link rel="alternate" type="text/html" href="http://jexp.ru/index.php?title=Java/JDK_6/Swing_Worker&amp;action=history"/>
		<updated>2026-04-07T22:11:09Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://jexp.ru/index.php?title=Java/JDK_6/Swing_Worker&amp;diff=6393&amp;oldid=prev</id>
		<title>Admin: 1 версия</title>
		<link rel="alternate" type="text/html" href="http://jexp.ru/index.php?title=Java/JDK_6/Swing_Worker&amp;diff=6393&amp;oldid=prev"/>
				<updated>2010-06-01T06:12:30Z</updated>
		
		<summary type="html">&lt;p&gt;1 версия&lt;/p&gt;
&lt;table class=&quot;diff diff-contentalign-left&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr style=&quot;vertical-align: top;&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: white; color:black; text-align: center;&quot;&gt;Версия 06:12, 1 июня 2010&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; style=&quot;text-align: center;&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Admin</name></author>	</entry>

	<entry>
		<id>http://jexp.ru/index.php?title=Java/JDK_6/Swing_Worker&amp;diff=6392&amp;oldid=prev</id>
		<title> в 18:01, 31 мая 2010</title>
		<link rel="alternate" type="text/html" href="http://jexp.ru/index.php?title=Java/JDK_6/Swing_Worker&amp;diff=6392&amp;oldid=prev"/>
				<updated>2010-05-31T18:01:43Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Swing Worker from JDK 6 SE ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
import java.awt.LayoutManager;&lt;br /&gt;
import java.awt.event.ActionEvent;&lt;br /&gt;
import java.awt.event.ActionListener;&lt;br /&gt;
import java.beans.PropertyChangeEvent;&lt;br /&gt;
import java.beans.PropertyChangeListener;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import javax.swing.BoxLayout;&lt;br /&gt;
import javax.swing.JButton;&lt;br /&gt;
import javax.swing.JFrame;&lt;br /&gt;
import javax.swing.JPanel;&lt;br /&gt;
import javax.swing.JProgressBar;&lt;br /&gt;
import javax.swing.JScrollPane;&lt;br /&gt;
import javax.swing.JTextArea;&lt;br /&gt;
import javax.swing.SwingWorker;&lt;br /&gt;
public class SwingWorkerDemo {&lt;br /&gt;
  public static void main(String[] args) {&lt;br /&gt;
    JTextArea textArea = new JTextArea(10, 20);&lt;br /&gt;
    final JProgressBar progressBar = new JProgressBar(0, 10);&lt;br /&gt;
    final CounterTask task = new CounterTask();&lt;br /&gt;
    task.addPropertyChangeListener(new PropertyChangeListener() {&lt;br /&gt;
      public void propertyChange(PropertyChangeEvent evt) {&lt;br /&gt;
        if (&amp;quot;progress&amp;quot;.equals(evt.getPropertyName())) {&lt;br /&gt;
          progressBar.setValue((Integer) evt.getNewValue());&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    JButton startButton = new JButton(&amp;quot;Start&amp;quot;);&lt;br /&gt;
    startButton.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        task.execute();&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    JButton cancelButton = new JButton(&amp;quot;Cancel&amp;quot;);&lt;br /&gt;
    cancelButton.addActionListener(new ActionListener() {&lt;br /&gt;
      public void actionPerformed(ActionEvent e) {&lt;br /&gt;
        task.cancel(true);&lt;br /&gt;
      }&lt;br /&gt;
    });&lt;br /&gt;
    JPanel buttonPanel = new JPanel();&lt;br /&gt;
    buttonPanel.add(startButton);&lt;br /&gt;
    buttonPanel.add(cancelButton);&lt;br /&gt;
    JPanel cp = new JPanel();&lt;br /&gt;
    LayoutManager layout = new BoxLayout(cp, BoxLayout.Y_AXIS);&lt;br /&gt;
    cp.setLayout(layout);&lt;br /&gt;
    cp.add(buttonPanel);&lt;br /&gt;
    cp.add(new JScrollPane(textArea));&lt;br /&gt;
    cp.add(progressBar);&lt;br /&gt;
    JFrame frame = new JFrame(&amp;quot;SwingWorker Demo&amp;quot;);&lt;br /&gt;
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);&lt;br /&gt;
    frame.setContentPane(cp);&lt;br /&gt;
    frame.pack();&lt;br /&gt;
    frame.setVisible(true);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
class CounterTask extends SwingWorker&amp;lt;Integer, Integer&amp;gt; {&lt;br /&gt;
  private static final int DELAY = 1000;&lt;br /&gt;
  public CounterTask() {&lt;br /&gt;
  }&lt;br /&gt;
  @Override&lt;br /&gt;
  protected Integer doInBackground() throws Exception {&lt;br /&gt;
    int i = 0;&lt;br /&gt;
    int count = 10;&lt;br /&gt;
    while (!isCancelled() &amp;amp;&amp;amp; i &amp;lt; count) {&lt;br /&gt;
      i++;&lt;br /&gt;
      publish(new Integer[] { i });&lt;br /&gt;
      setProgress(count * i / count);&lt;br /&gt;
      Thread.sleep(DELAY);&lt;br /&gt;
    }&lt;br /&gt;
    return count;&lt;br /&gt;
  }&lt;br /&gt;
   &lt;br /&gt;
  protected void process(List&amp;lt;Integer&amp;gt; chunks) {&lt;br /&gt;
    for (int i : chunks)&lt;br /&gt;
      System.out.println(i);&lt;br /&gt;
  }&lt;br /&gt;
  @Override&lt;br /&gt;
  protected void done() {&lt;br /&gt;
    if (isCancelled())&lt;br /&gt;
      System.out.println(&amp;quot;Cancelled !&amp;quot;);&lt;br /&gt;
    else&lt;br /&gt;
      System.out.println(&amp;quot;Done !&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
        &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Swing worker from org.jdesktop.swingworker ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* &lt;br /&gt;
 * $Id: AccumulativeRunnable.java,v 1.2 2006/09/28 20:20:28 idk Exp $&lt;br /&gt;
 * &lt;br /&gt;
 * Copyright ?2005 Sun Microsystems, Inc. All rights&lt;br /&gt;
 * reserved. Use is subject to license terms.&lt;br /&gt;
 */&lt;br /&gt;
package org.jdesktop.swingworker;&lt;br /&gt;
import java.util.*;&lt;br /&gt;
import javax.swing.SwingUtilities;&lt;br /&gt;
/**&lt;br /&gt;
 * An abstract class to be used in the cases where we need {@code Runnable}&lt;br /&gt;
 * to perform  some actions on an appendable set of data.&lt;br /&gt;
 * The set of data might be appended after the {@code Runnable} is&lt;br /&gt;
 * sent for the execution. Usually such {@code Runnables} are sent to&lt;br /&gt;
 * the EDT.&lt;br /&gt;
 *&lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * Usage example:&lt;br /&gt;
 * &lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * Say we want to implement JLabel.setText(String text) which sends&lt;br /&gt;
 * {@code text} string to the JLabel.setTextImpl(String text) on the EDT. &lt;br /&gt;
 * In the event JLabel.setText is called rapidly many times off the EDT&lt;br /&gt;
 * we will get many updates on the EDT but only the last one is important.&lt;br /&gt;
 * (Every next updates overrides the previous one.)&lt;br /&gt;
 * We might want to implement this {@code setText} in a way that only&lt;br /&gt;
 * the last update is delivered.&lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * Here is how one can do this using {@code AccumulativeRunnable}:&lt;br /&gt;
 * &amp;lt;pre&amp;gt;&lt;br /&gt;
 * AccumulativeRunnable&amp;lt;String&amp;gt; doSetTextImpl = &lt;br /&gt;
 * new  AccumulativeRunnable&amp;lt;String&amp;gt;() {&lt;br /&gt;
 *     @Override &lt;br /&gt;
 *     protected void run(List&amp;amp;lt;String&amp;amp;gt; args) {&lt;br /&gt;
 *         //set to the last string being passed&lt;br /&gt;
 *         setTextImpl(args.get(args.size() - 1);&lt;br /&gt;
 *     }&lt;br /&gt;
 * }&lt;br /&gt;
 * void setText(String text) {&lt;br /&gt;
 *     //add text and send for the execution if needed.&lt;br /&gt;
 *     doSetTextImpl.add(text);&lt;br /&gt;
 * }&lt;br /&gt;
 * &amp;lt;/pre&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * Say we want want to implement addDirtyRegion(Rectangle rect)&lt;br /&gt;
 * which sends this region to the &lt;br /&gt;
 * handleDirtyRegions(List&amp;lt;Rect&amp;gt; regions) on the EDT.&lt;br /&gt;
 * addDirtyRegions better be accumulated before handling on the EDT.&lt;br /&gt;
 * &lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * Here is how it can be implemented using AccumulativeRunnable:&lt;br /&gt;
 * &amp;lt;pre&amp;gt;&lt;br /&gt;
 * AccumulativeRunnable&amp;lt;Rectangle&amp;gt; doHandleDirtyRegions = &lt;br /&gt;
 *     new AccumulativeRunnable&amp;lt;Rectangle&amp;gt;() {&lt;br /&gt;
 *         @Override &lt;br /&gt;
 *         protected void run(List&amp;amp;lt;Rectangle&amp;amp;gt; args) {&lt;br /&gt;
 *             handleDirtyRegions(args);&lt;br /&gt;
 *         }&lt;br /&gt;
 *     };&lt;br /&gt;
 *  void addDirtyRegion(Rectangle rect) {&lt;br /&gt;
 *      doHandleDirtyRegions.add(rect);&lt;br /&gt;
 *  }&lt;br /&gt;
 * &amp;lt;/pre&amp;gt;&lt;br /&gt;
 *&lt;br /&gt;
 * @author Igor Kushnirskiy&lt;br /&gt;
 * @version $Revision: 1.2 $ $Date: 2006/09/28 20:20:28 $&lt;br /&gt;
 *&lt;br /&gt;
 * @param &amp;lt;T&amp;gt; the type this {@code Runnable} accumulates&lt;br /&gt;
 * &lt;br /&gt;
 */&lt;br /&gt;
abstract class AccumulativeRunnable&amp;lt;T&amp;gt; implements Runnable {&lt;br /&gt;
    private List&amp;lt;T&amp;gt; arguments = null;&lt;br /&gt;
    &lt;br /&gt;
    /**&lt;br /&gt;
     * Equivalent to {@code Runnable.run} method with the&lt;br /&gt;
     * accumulated arguments to process.&lt;br /&gt;
     *&lt;br /&gt;
     * @param args accumulated arguments to process.&lt;br /&gt;
     */&lt;br /&gt;
    protected abstract void run(List&amp;lt;T&amp;gt; args);&lt;br /&gt;
    &lt;br /&gt;
    /**&lt;br /&gt;
     * {@inheritDoc}&lt;br /&gt;
     *&lt;br /&gt;
     * &amp;lt;p&amp;gt;&lt;br /&gt;
     * This implementation calls {@code run(List&amp;lt;T&amp;gt; args)} method&lt;br /&gt;
     * with the list of accumulated arguments.&lt;br /&gt;
     */&lt;br /&gt;
    public final void run() {&lt;br /&gt;
        run(flush());&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /**&lt;br /&gt;
     * appends arguments and sends this {@code Runnable} for the&lt;br /&gt;
     * execution if needed.&lt;br /&gt;
     * &amp;lt;p&amp;gt;&lt;br /&gt;
     * This implementation uses {@see #submit} to send this &lt;br /&gt;
     * {@code Runnable} for execution. &lt;br /&gt;
     * @param args the arguments to accumulate&lt;br /&gt;
     */&lt;br /&gt;
    public final synchronized void add(T... args) {&lt;br /&gt;
        boolean isSubmitted = true;&lt;br /&gt;
        if (arguments == null) {&lt;br /&gt;
            isSubmitted = false;&lt;br /&gt;
            arguments = new ArrayList&amp;lt;T&amp;gt;();&lt;br /&gt;
        }&lt;br /&gt;
        Collections.addAll(arguments, args);&lt;br /&gt;
        if (!isSubmitted) {&lt;br /&gt;
            submit();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Sends this {@code Runnable} for the execution&lt;br /&gt;
     *&lt;br /&gt;
     * &amp;lt;p&amp;gt;&lt;br /&gt;
     * This method is to be executed only from {@code add} method.&lt;br /&gt;
     *&lt;br /&gt;
     * &amp;lt;p&amp;gt;&lt;br /&gt;
     * This implementation uses {@code SwingWorker.invokeLater}.&lt;br /&gt;
     */&lt;br /&gt;
    protected void submit() {&lt;br /&gt;
        SwingUtilities.invokeLater(this);&lt;br /&gt;
    }&lt;br /&gt;
        &lt;br /&gt;
    /**&lt;br /&gt;
     * Returns accumulated arguments and flashes the arguments storage.&lt;br /&gt;
     *&lt;br /&gt;
     * @return accumulated arguments&lt;br /&gt;
     */&lt;br /&gt;
    private final synchronized List&amp;lt;T&amp;gt; flush() {&lt;br /&gt;
        List&amp;lt;T&amp;gt; list = arguments;&lt;br /&gt;
        arguments = null;&lt;br /&gt;
        return list;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
///////////////////////////////////////////////////////////&lt;br /&gt;
/* &lt;br /&gt;
 * $Id: SwingPropertyChangeSupport.java,v 1.1 2005/06/18 21:27:14 idk Exp $&lt;br /&gt;
 * &lt;br /&gt;
 * Copyright ?2005 Sun Microsystems, Inc. All rights&lt;br /&gt;
 * reserved. Use is subject to license terms.&lt;br /&gt;
 */&lt;br /&gt;
package org.jdesktop.swingworker;&lt;br /&gt;
import java.beans.PropertyChangeSupport;&lt;br /&gt;
import java.beans.PropertyChangeEvent;&lt;br /&gt;
import javax.swing.SwingUtilities;&lt;br /&gt;
/**&lt;br /&gt;
 * This subclass of {@code java.beans.PropertyChangeSupport} is almost&lt;br /&gt;
 * identical in functionality. The only difference is if constructed with &lt;br /&gt;
 * {@code SwingPropertyChangeSupport(sourceBean, true)} it ensures&lt;br /&gt;
 * listeners are only ever notified on the &amp;lt;i&amp;gt;Event Dispatch Thread&amp;lt;/i&amp;gt;.&lt;br /&gt;
 *&lt;br /&gt;
 * @author Igor Kushnirskiy&lt;br /&gt;
 * @version $Revision: 1.1 $ $Date: 2005/06/18 21:27:14 $&lt;br /&gt;
 */&lt;br /&gt;
public final class SwingPropertyChangeSupport extends PropertyChangeSupport {&lt;br /&gt;
    /**&lt;br /&gt;
     * Constructs a SwingPropertyChangeSupport object.&lt;br /&gt;
     *&lt;br /&gt;
     * @param sourceBean  The bean to be given as the source for any&lt;br /&gt;
     *        events.&lt;br /&gt;
     * @throws NullPointerException if {@code sourceBean} is &lt;br /&gt;
     *         {@code null}&lt;br /&gt;
     */&lt;br /&gt;
    public SwingPropertyChangeSupport(Object sourceBean) {&lt;br /&gt;
        this(sourceBean, false);&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Constructs a SwingPropertyChangeSupport object.&lt;br /&gt;
     * &lt;br /&gt;
     * @param sourceBean the bean to be given as the source for any events&lt;br /&gt;
     * @param notifyOnEDT whether to notify listeners on the &amp;lt;i&amp;gt;Event&lt;br /&gt;
     *        Dispatch Thread&amp;lt;/i&amp;gt; only&lt;br /&gt;
     *&lt;br /&gt;
     * @throws NullPointerException if {@code sourceBean} is &lt;br /&gt;
     *         {@code null}&lt;br /&gt;
     * @since 1.6&lt;br /&gt;
     */&lt;br /&gt;
    public SwingPropertyChangeSupport(Object sourceBean, boolean notifyOnEDT) {&lt;br /&gt;
        super(sourceBean);&lt;br /&gt;
        this.notifyOnEDT = notifyOnEDT;&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * {@inheritDoc}&lt;br /&gt;
     *&lt;br /&gt;
     * &amp;lt;p&amp;gt;&lt;br /&gt;
     * If {@see #isNotifyOnEDT} is {@code true} and called off the&lt;br /&gt;
     * &amp;lt;i&amp;gt;Event Dispatch Thread&amp;lt;/i&amp;gt; this implementation uses &lt;br /&gt;
     * {@code SwingUtilities.invokeLater} to send out the notification&lt;br /&gt;
     * on the &amp;lt;i&amp;gt;Event Dispatch Thread&amp;lt;/i&amp;gt;. This ensures  listeners&lt;br /&gt;
     * are only ever notified on the &amp;lt;i&amp;gt;Event Dispatch Thread&amp;lt;/i&amp;gt;.&lt;br /&gt;
     *&lt;br /&gt;
     * @throws NullPointerException if {@code evt} is &lt;br /&gt;
     *         {@code null}&lt;br /&gt;
     * @since 1.6&lt;br /&gt;
     */&lt;br /&gt;
    public void firePropertyChange(final PropertyChangeEvent evt) {&lt;br /&gt;
        if (evt == null) {&lt;br /&gt;
            throw new NullPointerException();&lt;br /&gt;
        }&lt;br /&gt;
        if (! isNotifyOnEDT()&lt;br /&gt;
            || SwingUtilities.isEventDispatchThread()) {&lt;br /&gt;
            super.firePropertyChange(evt);&lt;br /&gt;
        } else {&lt;br /&gt;
            SwingUtilities.invokeLater(&lt;br /&gt;
                new Runnable() {&lt;br /&gt;
                    public void run() {&lt;br /&gt;
                        firePropertyChange(evt);&lt;br /&gt;
                    }&lt;br /&gt;
                });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    /**&lt;br /&gt;
     * Returns {@code notifyOnEDT} property.&lt;br /&gt;
     * &lt;br /&gt;
     * @return {@code notifyOnEDT} property&lt;br /&gt;
     * @see #SwingPropertyChangeSupport(Object sourceBean, boolean notifyOnEDT)&lt;br /&gt;
     * @since 1.6&lt;br /&gt;
     */&lt;br /&gt;
    public final boolean isNotifyOnEDT() {&lt;br /&gt;
        return notifyOnEDT;&lt;br /&gt;
    }&lt;br /&gt;
    // Serialization version ID&lt;br /&gt;
    static final long serialVersionUID = 7162625831330845068L;&lt;br /&gt;
    /**&lt;br /&gt;
     * whether to notify listeners on EDT&lt;br /&gt;
     * &lt;br /&gt;
     * @serial &lt;br /&gt;
     * @since 1.6&lt;br /&gt;
     */ &lt;br /&gt;
    private final boolean notifyOnEDT;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
///////////////////////////////////////////////////////////&lt;br /&gt;
/* &lt;br /&gt;
 * $Id: SwingWorker.java,v 1.5 2007/03/01 19:55:54 idk Exp $&lt;br /&gt;
 * &lt;br /&gt;
 * Copyright ?2005 Sun Microsystems, Inc. All rights&lt;br /&gt;
 * reserved. Use is subject to license terms.&lt;br /&gt;
 */&lt;br /&gt;
package org.jdesktop.swingworker;&lt;br /&gt;
import java.beans.PropertyChangeListener;&lt;br /&gt;
import java.beans.PropertyChangeSupport;&lt;br /&gt;
import java.beans.PropertyChangeEvent;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import java.util.concurrent.*;&lt;br /&gt;
import java.util.concurrent.atomic.AtomicInteger;&lt;br /&gt;
import java.util.concurrent.locks.*;&lt;br /&gt;
import java.awt.event.*;&lt;br /&gt;
import javax.swing.SwingUtilities;&lt;br /&gt;
import javax.swing.Timer;&lt;br /&gt;
/**&lt;br /&gt;
 * An abstract class to perform lengthy GUI-interacting tasks in a&lt;br /&gt;
 * dedicated thread.&lt;br /&gt;
 * &lt;br /&gt;
 * &amp;lt;p&amp;gt;&lt;br /&gt;
 * When writing a multi-threaded application using Swing, there are&lt;br /&gt;
 * two constraints to keep in mind:&lt;br /&gt;
 * (refer to &lt;br /&gt;
 * &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Swing Worker Image Loader ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- start source code --&amp;gt;&lt;br /&gt;
   &lt;br /&gt;
    &amp;lt;source lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
import java.awt.*;&lt;br /&gt;
import java.awt.event.*;&lt;br /&gt;
import javax.swing.*;&lt;br /&gt;
import java.util.List;&lt;br /&gt;
import java.util.ArrayList;&lt;br /&gt;
import java.io.File;&lt;br /&gt;
import java.io.IOException;&lt;br /&gt;
import java.awt.Image;&lt;br /&gt;
import javax.swing.ImageIcon;&lt;br /&gt;
import javax.swing.JLabel;&lt;br /&gt;
import javax.swing.JPanel;&lt;br /&gt;
import javax.swing.JTextArea;&lt;br /&gt;
import javax.imageio.ImageIO;&lt;br /&gt;
import org.jdesktop.swingworker.SwingWorker;&lt;br /&gt;
public class ImageLoader extends JFrame {&lt;br /&gt;
    private JTextArea log;&lt;br /&gt;
    private JPanel viewer;&lt;br /&gt;
    &lt;br /&gt;
    public ImageLoader() {&lt;br /&gt;
        super(&amp;quot;Image Loader&amp;quot;);&lt;br /&gt;
        &lt;br /&gt;
        this.log = new JTextArea(4, 4);&lt;br /&gt;
        this.viewer = new JPanel();&lt;br /&gt;
        &lt;br /&gt;
        JButton start = new JButton(&amp;quot;Start&amp;quot;);&lt;br /&gt;
        start.addActionListener(new ActionListener() {&lt;br /&gt;
           public void actionPerformed(ActionEvent e) {&lt;br /&gt;
               String[] files = new String[] {&lt;br /&gt;
                   &amp;quot;Bodie_small.png&amp;quot;, &amp;quot;Carmela_small.png&amp;quot;,&lt;br /&gt;
                   &amp;quot;Death Valley_small.png&amp;quot;, &amp;quot;Lake_small.png&amp;quot;&lt;br /&gt;
               };&lt;br /&gt;
               new ImageLoadingWorker(log, viewer, files).execute();&lt;br /&gt;
           }&lt;br /&gt;
        });&lt;br /&gt;
        &lt;br /&gt;
        add(new JScrollPane(log), BorderLayout.NORTH);&lt;br /&gt;
        add(new JScrollPane(viewer), BorderLayout.CENTER);&lt;br /&gt;
        add(start, BorderLayout.SOUTH);&lt;br /&gt;
        &lt;br /&gt;
        setSize(360, 280);&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    public static void main(String... args) {&lt;br /&gt;
        SwingUtilities.invokeLater(new Runnable() {&lt;br /&gt;
            public void run() {&lt;br /&gt;
                new ImageLoader().setVisible(true);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Final result is a list of Image&lt;br /&gt;
// Intermediate result is a message as a String&lt;br /&gt;
class ImageLoadingWorker extends SwingWorker&amp;lt;List&amp;lt;Image&amp;gt;, String&amp;gt; {&lt;br /&gt;
  private JTextArea log;&lt;br /&gt;
  private JPanel viewer;&lt;br /&gt;
  private String[] filenames;&lt;br /&gt;
  public ImageLoadingWorker(JTextArea log, JPanel viewer, String... filenames) {&lt;br /&gt;
    this.log = log;&lt;br /&gt;
    this.viewer = viewer;&lt;br /&gt;
    this.filenames = filenames;&lt;br /&gt;
  }&lt;br /&gt;
  // In the EDT&lt;br /&gt;
  @Override&lt;br /&gt;
  protected void done() {&lt;br /&gt;
    try {&lt;br /&gt;
      for (Image image : get()) {&lt;br /&gt;
        viewer.add(new JLabel(new ImageIcon(image)));&lt;br /&gt;
        viewer.revalidate();&lt;br /&gt;
      }&lt;br /&gt;
    } catch (Exception e) { }&lt;br /&gt;
  }&lt;br /&gt;
  // In the EDT&lt;br /&gt;
  @Override&lt;br /&gt;
  protected void process(String... messages) {&lt;br /&gt;
    for (String message : messages) {&lt;br /&gt;
      log.append(message);&lt;br /&gt;
      log.append(&amp;quot;\n&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  // In a thread&lt;br /&gt;
  @Override&lt;br /&gt;
  public List&amp;lt;Image&amp;gt; doInBackground() {&lt;br /&gt;
    List&amp;lt;Image&amp;gt; images = new ArrayList&amp;lt;Image&amp;gt;();&lt;br /&gt;
    for (String filename : filenames) {&lt;br /&gt;
      try {&lt;br /&gt;
        images.add(ImageIO.read(new File(&amp;quot;./build/&amp;quot;+filename)));&lt;br /&gt;
        publish(&amp;quot;Loaded &amp;quot; + filename);&lt;br /&gt;
      } catch (IOException ioe) {&lt;br /&gt;
        publish(&amp;quot;Error loading &amp;quot; + filename);&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return images;&lt;br /&gt;
  }  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
           &lt;br /&gt;
       &amp;lt;/source&amp;gt;&lt;br /&gt;
    &lt;br /&gt;
   &lt;br /&gt;
  &amp;lt;!-- end source code --&amp;gt;&lt;/div&gt;</summary>
			</entry>

	</feed>