2013-07-22 5 views
0

Я прочитал эту статью в EDT (Thread Dispatch Thread) javaworld.com, где показано, как правильно настроить графический интерфейс Swing на EDT и ставить длинные задачи, которые изменяют GUI внутри Runnables.Java Event-Dispatch Thread пример программы зависает

Все это имеет смысл, однако, пример программы (я вставил ниже), где единственная модификация, которую я сделал, это Thread.sleep (6000), чтобы имитировать длительное отставание, делает интерфейс безответственным в течение нескольких секунд.

Я что-то упустил?

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); 
    } 
} 

ответ

2

ли я что-то отсутствует?

Да.

Runnable - это просто интерфейс, не другой поток. Здесь с этой строкой вы завершаете вызов для выполнения позже в Event Dispatch Thread.

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

Тогда вы называете

Thread.sleep(6000);

Это выполняется в EDT и не делают безответственность графического интерфейса пользователя до конца.

Для длительной задачи вы должны использовать другие потоки или SwingWorker и для короткой задачи с некоторыми повторениями SwingTimer. Подробнее о Concurrency in Swing

+0

Можете ли вы подтвердить, что в статье javaworld есть ошибка, в которой он говорит: «Листинг 4 отличается от листинга 3 тем, что он создает рабочий поток для чтения документа HTML через runnable». Действительно, он фактически создает Runnable, а не рабочий поток, а также где он говорит: «Результат - отзывчивый интерфейс, потому что EDT никогда не задерживается». это на самом деле по причине, которую вы только что описали. – dendini

+0

Листинг 4 содержит следующую строку: 'new Thread (worker) .start();' Однако любой учебник, чей код кода имеет 4 уровня вложенных анонимных классов, показывает довольно слабые навыки преподавания. Кроме того, он предупреждает никогда не вызывать invokeAndWait из потока событий, но [документацию] (http://docs.oracle.com/javase/7/docs/api/java/awt/EventQueue.html#invokeAndWait%28java.lang .Runnable% 29) четко заявляет, что он немедленно выдает ошибку, а не висит нить. Вам лучше учиться из официального учебника, такого как [this] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/). – VGR

Смежные вопросы