2011-08-26 81 views
3

我有一個Swing JFrame。如果我在程序執行期間在新線程中創建一個新的JFrame,那麼將會是EDT?在最後一個JFrame窗口的當前線程中或在第一個窗口中。編輯: 感謝您的回答。EDT位置有幾個JFrame窗口

我明白他們,我對他們很好。我知道我們不必在美國東部時間的其他地方創建搖擺物,但我遇到了問題。

我解釋一下;我開發了一個用於創建和提取壓縮文件的JAVA應用程序,比如winrar。您可以在多線程的同一時間創建多個arhive。最近,我希望在創建歸檔文件時以JprogressBar的形式在每次創建時在新的JFrame中添加信息狀態。但我的問題是在新的狀態框架和創建存檔的線程中生成通信。這就是爲什麼我在歸檔線程中創建JFrame來更新當前的進度條。

但是就像我可以在潛水員的信息源和你的回答/評論中看到它,它反對java swing和performance;我無法在EDT的其他地方創建擺動物體。

但是,那麼,我該如何解決我的問題?

+6

你不應該創建EDT以外的任何Swing對象,所以你的問題是基於一個前提無效。 ;-) –

+0

看起來好像其中一個'JFrame'實例應該是一個模態'JDialog'。當對話框可見時,框架的輸入將被阻止。 –

回答

7

EDT - 事件調度線程 - 與任何具體的GUI組件(如JFrame)分離。

通常,您應該在EDT上創建所有GUI組件,但這並不意味着它們擁有EDT,也不是EDT擁有這些組件。

要在美國東部時間創建兩個JFrames,兩者可以做到以下幾點:

public static void main(String[] args) { 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      JFrame frame1 = new JFrame("Frame 1"); 
      frame1.getContentPane().add(new JLabel("Hello in frame 1")); 
      frame1.pack(); 
      frame1.setLocation(100, 100); 
      frame1.setVisible(true); 
     } 
    }); 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      JFrame frame2 = new JFrame("Frame 2"); 
      frame2.getContentPane().add(new JLabel("Hello in frame 2")); 
      frame2.pack(); 
      frame2.setLocation(200, 200); 
      frame2.setVisible(true); 
     } 
    }); 

} 
5

事件調度線程是固定的。它不會因爲您在另一個線程上創建Swing對象而被重新分配(您永遠不應該這樣做)。

+0

系統總是發佈到當前事件隊列,即使它是[重新啓動](http://stackoverflow.com/questions/7190297/eventqueue-inconsistent-ids)或[替換](http://stackoverflow.com/questions/3158254 /如何更換的最AWT-EventQueue中與 - 自己的實現)。 – trashgod

1

,應該是很簡單的,如果所有在當前美國東部時間完成所有事件,然後EDT不存在,另一個隊列可以說明,

  • 從Swing的聽衆,
  • 通過caling代碼包到invokeLater/invokeAndWait
  • 但safiest(和我最好的)將javax.swing.Action

輸出

run: 
         Time at : 19:35:21 
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

         Time at : 19:35:21 
Calling from EventQueue.isDispatchThread 
Calling from SwingUtilities.isEventDispatchThread 

         Time at : 19:35:21 
Calling from EventQueue.isDispatchThread 
Calling from SwingUtilities.isEventDispatchThread 

         Time at : 19:35:51 
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

         Time at : 19:36:21 
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

         Time at : 19:36:51 
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

         Time at : 19:37:21 
There isn't Live EventQueue.isDispatchThread, why any reason for that 
There isn't Live SwingUtilities.isEventDispatchThread, why any reason for that 

BUILD SUCCESSFUL (total time: 2 minutes 17 seconds) 

從代碼:

import java.awt.EventQueue; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import java.util.concurrent.*; 
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; 

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

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

      @Override 
      public void run() { 
       countCalled++; 
       if (this.getExecutionTime() < ALLOWED_TARDINESS) { 
        countRun++; 
        isThereReallyEDT(); // non on EDT 
       } 
      } 
     }; 
     periodicMonitor = scheduler.scheduleAtFixedRate(periodic, 0, taskPeriod, TimeUnit.SECONDS); 
     periodic.setThreadMonitor(periodicMonitor); 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       isThereReallyEDT(); 
       JFrame frame1 = new JFrame("Frame 1"); 
       frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame1.getContentPane().add(new JLabel("Hello in frame 1")); 
       frame1.pack(); 
       frame1.setLocation(100, 100); 
       frame1.setVisible(true); 
      } 
     }); 
     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("Calling from EventQueue.isDispatchThread"); 
     } else { 
      System.out.println("There isn't Live EventQueue.isDispatchThread, why any reason for that "); 
     } 
     if (SwingUtilities.isEventDispatchThread()) { 
      System.out.println("Calling from 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; 
    } 
} 
+0

+1即使在'add(new JLabel(String.valueOf(1/0)))'之後,EDT仍然存在! – trashgod

+0

不明白你的代碼是什麼意思來演示...的行爲與我預期的完全一致:如果isThereReallyEDT是從EDT調用的(因爲它來自invokeLater的可運行),則isEventDispatchThread是真的,如果從關閉EDT調用(因爲它在調度程序的可運行中),這是真的。不是線程專家,但可以肯定的是edt在任何時候都非常活躍,即使事件隊列可能偶爾也是空的;-) – kleopatra

+0

@jfpoilpret您能評論AWT-EventQueue真正發生了什麼,可以創建第二 – mKorbel