dendini
dendini

Reputation: 3952

Java Event-Dispatch Thread example program hangs

I have read this article on the EDT (Event Dispatch Thread) javaworld.com which shows how to correctly setup a Swing GUI on the EDT and put long running tasks which modify the GUI inside Runnables.

It all makes sense however the example program (I pasted below) where the only modification I made is a Thread.sleep(6000) to simulate a long lag makes the interface irresponsive for some seconds.

Am I missing something?

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class ViewPage
{

    public static void main(String[] args)
    {
        Runnable r;
        r = new Runnable()
        {
            @Override
            public void run()
            {
                final JFrame frame = new JFrame("View Page");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JPanel panel = new JPanel();
                panel.add(new JLabel("Enter URL"));
                final JTextField txtURL = new JTextField(40);
                panel.add(txtURL);
                frame.getContentPane().add(panel, BorderLayout.NORTH);
                final JTextArea txtHTML = new JTextArea(10, 40);
                frame.getContentPane().add(new JScrollPane(txtHTML),
                        BorderLayout.CENTER);
                ActionListener al;
                al = new ActionListener()
                {
                    public void actionPerformed(ActionEvent ae)
                    {
                        txtURL.setEnabled(false);
                        Runnable worker = new Runnable()
                        {
                            public void run()
                            {
                                InputStream is = null;
                                try
                                {
                                    URL url = new URL(txtURL.getText());
                                    is = url.openStream();
                                    final StringBuilder sb;
                                    sb = new StringBuilder();
                                    int b;
                                    while ((b = is.read()) != -1)
                                    {
                                        sb.append((char) b);
                                    }
                                    Runnable r = new Runnable()
                                    {
                                        public void run()
                                        {
                                            try
                                            {
                                                Thread.sleep(6000);
                                            }
                                            catch (InterruptedException ex)
                                            {
                                                Logger.getLogger(ViewPage.class.getName()).log(Level.SEVERE, null, ex);
                                            }
                                            txtHTML.setText(sb.toString());
                                            txtURL.setEnabled(true);
                                        }
                                    };
                                    try
                                    {
                                        EventQueue.invokeAndWait(r);
                                    }
                                    catch (InterruptedException ie)
                                    {
                                    }
                                    catch (InvocationTargetException ite)
                                    {
                                    }
                                }
                                catch (final IOException ioe)
                                {
                                    Runnable r = new Runnable()
                                    {
                                        public void run()
                                        {
                                            txtHTML.setText(ioe.getMessage());
                                            txtURL.setEnabled(true);
                                        }
                                    };
                                    try
                                    {
                                        EventQueue.invokeAndWait(r);
                                    }
                                    catch (InterruptedException ie)
                                    {
                                    }
                                    catch (InvocationTargetException ite)
                                    {
                                    }
                                }
                                finally
                                {
                                    Runnable r = new Runnable()
                                    {
                                        public void run()
                                        {
                                            txtHTML.setCaretPosition(0);
                                            txtURL.setEnabled(true);
                                        }
                                    };
                                    try
                                    {
                                        EventQueue.invokeAndWait(r);
                                    }
                                    catch (InterruptedException ie)
                                    {
                                    }
                                    catch (InvocationTargetException ite)
                                    {
                                    }
                                    if (is != null)
                                    {
                                        try
                                        {
                                            is.close();
                                        }
                                        catch (IOException ioe)
                                        {
                                        }
                                    }
                                }
                            }
                        };
                        new Thread(worker).start();
                    }
                };
                txtURL.addActionListener(al);
                frame.pack();
                frame.setVisible(true);
            }
        };
        EventQueue.invokeLater(r);
    }
}

Upvotes: 0

Views: 2721

Answers (1)

nachokk
nachokk

Reputation: 14413

Am I missing something?

Yes.

Runnable is just an interface not another thread. Here with this line you are wrapping the call to execute later in the Event Dispatch Thread.

EventQueue.invokeLater(r); // you can use SwingUtilities.invokeLater(r) too 

Then you call

Thread.sleep(6000);

This is executed in EDT and make irresponsive the gui until finish.

For long task you should use another threads or SwingWorker and for short task with some repetitions SwingTimer. Read about Concurrency in Swing

Upvotes: 2

Related Questions