2012-04-22 80 views

回答

3

如果您從EDT創建一個新線程,該線程與EDT不同。這不清楚嗎?
您應該通過EDT更新控件。
您可以爲繁重任務創建自己的後臺線程,但控件的更新只能通過EDT。 有一些構造可供您用來簡化代碼,例如通過Runnable,由EDT通過SwingUtilities invoke Runnable撥打。你應該學習關於Concurrency in Swing

+0

'invokeAndWait'是不可能從'的actionPerformed()'運行,因爲這個線程可能在'EDT'結束,然後返回了幾個'exception',沒有好的建議 – mKorbel 2012-04-22 09:09:44

+0

您好我知道控制更新應該在EDT內部。我只是認爲新創建的線程會分享EDT,因爲它已經在EDT環境內部了。< – MinhHoang 2012-04-22 09:10:39

+0

@mKorbel:好點。但我懷疑他想爲某個任務創建後臺線程,然後更新GUI,這是通常的進入Swing的錯誤。我將更新答案以澄清此問題。 – Cratylus 2012-04-22 09:10:58

1

1)AWT或Swing GUI調用並創建EDT,本次活動是由做(也許還有其他)方法包(),並調用setVisible(真)

2)如果所有事件等待如果(EventQueue.isDispatchThread()){返回false,但EDT線程在那裏,直到當前的JVM實例存在爲止

3)如調用EDT隊列所述,您可以使用invokeLater或invokeAndWait,注意invokeAndWait只有當isDispatchThread返回false時才能使用,否則返回異常

4)通過從Swing Listener調用Thread.sleep(int)或其方法可以凍結和鎖定EDT,導致從事件隊列中丟失某些事件,

兩個代碼示例用於測試isDispatchThread()以及如何從Java對象

import java.awt.EventQueue; 
import java.lang.reflect.InvocationTargetException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 

public class IsThereEDT { 

    private ScheduledExecutorService scheduler; 
    private AccurateScheduledRunnable periodic; 
    private ScheduledFuture<?> periodicMonitor; 
    private int taskPeriod = 30; 
    private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 
    private Date dateRun; 
    private JFrame frame1 = new JFrame("Frame 1"); 

    public IsThereEDT() { 
     scheduler = Executors.newSingleThreadScheduledExecutor(); 
     periodic = new AccurateScheduledRunnable() { 

      private final int ALLOWED_TARDINESS = 200; 
      private int countRun = 0; 
      private int countCalled = 0; 
      private int maxCalled = 10; 

      @Override 
      public void run() { 
       countCalled++; 
       if (countCalled < maxCalled) { 
        if (countCalled % 3 == 0) { 
         /*if (EventQueue.isDispatchThread()) { 
          SwingUtilities.invokeLater(new Runnable() { 

           @Override 
           public void run() { 
            //some stuff 
           } 
          }); 
         } else { 
          try { 
           SwingUtilities.invokeAndWait(new Runnable() { 

            @Override 
            public void run() { 
             //some stuff 
            } 
           }); 
          } catch (InterruptedException ex) { 
           Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex); 
          } catch (InvocationTargetException ex) { 
           Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex); 
          } 
         }*/ 
         SwingUtilities.invokeLater(new Runnable() { 

          @Override 
          public void run() { 
           System.out.println("Push a new event to EDT"); 
           frame1.repaint(); 
           isThereReallyEDT(); 
          } 
         }); 
        } else { 
         if (this.getExecutionTime() < ALLOWED_TARDINESS) { 
          countRun++; 
          isThereReallyEDT(); // non on EDT 
         } 
        } 
       } else { 
        System.out.println("Terminating this madness"); 
        System.exit(0); 
       } 
      } 
     }; 
     periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS); 
     periodic.setThreadMonitor(periodicMonitor); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       isThereReallyEDT(); 
       frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame1.getContentPane().add(new JLabel("Hello in frame 1")); 
       frame1.pack(); 
       frame1.setLocation(100, 100); 
       frame1.setVisible(true); 
      } 
     }); 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame frame2 = new JFrame("Frame 2"); 
       frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame2.getContentPane().add(new JLabel("Hello in frame 2")); 
       frame2.pack(); 
       frame2.setLocation(200, 200); 
       frame2.setVisible(true); 
       isThereReallyEDT(); 
      } 
     }); 
    } 

    private void isThereReallyEDT() { 
     dateRun = new java.util.Date(); 
     System.out.println("       Time at : " + sdf.format(dateRun)); 
     if (EventQueue.isDispatchThread()) { 
      System.out.println("EventQueue.isDispatchThread"); 
     } else { 
      System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that "); 
     } 
     if (SwingUtilities.isEventDispatchThread()) { 
      System.out.println("SwingUtilities.isEventDispatchThread"); 
     } else { 
      System.out.println("There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that "); 
     } 
     System.out.println(); 
    } 

    public static void main(String[] args) { 
     IsThereEDT isdt = new IsThereEDT(); 
    } 
} 

abstract class AccurateScheduledRunnable implements Runnable { 

    private ScheduledFuture<?> thisThreadsMonitor; 

    public void setThreadMonitor(ScheduledFuture<?> monitor) { 
     this.thisThreadsMonitor = monitor; 
    } 

    protected long getExecutionTime() { 
     long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS); 
     return delay; 
    } 
} 

和簡單的代碼

import java.awt.EventQueue; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.*; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.*; 

public class IsThereEDT { 

    private ScheduledExecutorService scheduler; 
    private AccurateScheduledRunnable periodic; 
    private ScheduledFuture<?> periodicMonitor; 
    private int taskPeriod = 30; 
    private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); 
    private Date dateRun; 
    private JFrame frame1 = new JFrame("Frame 1"); 

    public IsThereEDT() { 
     scheduler = Executors.newSingleThreadScheduledExecutor(); 
     periodic = new AccurateScheduledRunnable() { 

      private final int ALLOWED_TARDINESS = 200; 
      private int countRun = 0; 
      private int countCalled = 0; 
      private int maxCalled = 10; 

      @Override 
      public void run() { 
       countCalled++; 
       if (countCalled < maxCalled) { 
        if (countCalled % 3 == 0) { 
         SwingUtilities.invokeLater(new Runnable() { 

          @Override 
          public void run() { 
           System.out.println("Push a new event to EDT"); 
           frame1.repaint(); 
           isThereReallyEDT(); 
          } 
         }); 
        } else { 
         if (this.getExecutionTime() < ALLOWED_TARDINESS) { 
          countRun++; 
          isThereReallyEDT(); // non on EDT 
         } 
        } 
       } else { 
        System.out.println("Terminating this madness"); 
        System.exit(0); 
       } 
      } 
     }; 
     periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS); 
     periodic.setThreadMonitor(periodicMonitor); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       isThereReallyEDT(); 
       frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame1.getContentPane().add(new JLabel("Hello in frame 1")); 
       frame1.pack(); 
       frame1.setLocation(100, 100); 
       frame1.setVisible(true); 
      } 
     }); 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(IsThereEDT.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame frame2 = new JFrame("Frame 2"); 
       frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame2.getContentPane().add(new JLabel("Hello in frame 2")); 
       frame2.pack(); 
       frame2.setLocation(200, 200); 
       frame2.setVisible(true); 
       isThereReallyEDT(); 
      } 
     }); 
    } 

    private void isThereReallyEDT() { 
     dateRun = new java.util.Date(); 
     System.out.println("       Time at : " + sdf.format(dateRun)); 
     if (EventQueue.isDispatchThread()) { 
      System.out.println("EventQueue.isDispatchThread"); 
     } else { 
      System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that "); 
     } 
     if (SwingUtilities.isEventDispatchThread()) { 
      System.out.println("SwingUtilities.isEventDispatchThread"); 
     } else { 
      System.out.println("There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that "); 
     } 
     System.out.println(); 
    } 

    public static void main(String[] args) { 
     IsThereEDT isdt = new IsThereEDT(); 
    } 
} 

abstract class AccurateScheduledRunnable implements Runnable { 

    private ScheduledFuture<?> thisThreadsMonitor; 

    public void setThreadMonitor(ScheduledFuture<?> monitor) { 
     this.thisThreadsMonitor = monitor; 
    } 

    protected long getExecutionTime() { 
     long delay = -1 * thisThreadsMonitor.getDelay(TimeUnit.MILLISECONDS); 
     return delay; 
    } 
} 
相關問題