2011-08-26 51 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