2013-07-22 9 views
0

EDT (이벤트 발송 스레드) javaworld.com에서이 기사를 읽었습니다. EDT에서 Swing GUI를 올바르게 설정하고 Runnables 내의 GUI를 수정하는 장기 실행 작업을 수행하는 방법을 보여줍니다.Java Event-Dispatch Thread 예제 프로그램이 응답하지 않는다

내가 만든 유일한 수정은 Threadsleep (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 

그런 다음 당신은이 EDT 실행 및 종료 될 때까지 응답 불가 GUI를하게됩니다

Thread.sleep(6000);

호출합니다.

긴 작업의 경우 다른 스레드 또는 SwingWorker을 사용해야하며 짧은 작업의 경우 약간의 반복을 위해 SwingTimer을 사용해야합니다. 읽어보기 Concurrency in Swing

+0

javaworld 기사에 "Listing 4는 실행 파일을 통해 HTML 문서를 읽는 작업자 스레드를 생성한다는 점에서 Listing 3과 다릅니다"라는 실수를 할 수 있습니까? 실제로 실제로 실제로 작업자 스레드가 아닌 Runnable 및 "EDT가 지연되지 않기 때문에 결과는 반응 형 UI입니다." 그것은 방금 설명한 이유 때문입니다. – dendini

+0

목록 4에는 다음 행이 포함되어 있습니다.'new Thread (worker) .start();'그러나 예제 코드에 네 가지 익명 클래스가있는 튜토리얼은 매우 열악한 교수법을 보여줍니다. 또한 이벤트 스레드에서 invokeAndWait를 호출하지 말라고 경고하지만 [documentation] (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

관련 문제