当了Swing UI线程创建的?

当在运行一个Swing程序的过程,就是UI线程(事件分派线程,EDT)首先催生了? 想必任何给定的JVM可以为所欲为(例如,产卵总是在EDT在启动时,不论其是否是使用过),但作为一个实际问题时的EDT通常产生的?

是否得到创建时SwingUtilities.invokeLater()首先叫什么名字? 当一个JPanel第一次实例? 而如果事件泵从创建EDT单独启动,什么时候,通常发生的呢?

--------------解决方案-------------

通过代码看后,好像它的“延迟初始化”,意思是它的初始化只要它的需要,如果尚未初始化。 在这种情况下,无论何时发布任何事件到它的队列中。



下面是完整的故事:

EventDispatchThread被封装内EventQueue 。 每个EventQueue有它自己的EDT:

/**
* Just a summary of the class
*/
public class EventQueue {
private static final int ULTIMATE_PRIORITY = 3;
private static final int NUM_PRIORITIES = ULTIMATE_PRIORITY + 1;

private Queue[] queues = new Queue[NUM_PRIORITIES];
private EventQueue nextQueue;
private EventQueue previousQueue;
private EventDispatchThread dispatchThread;
}

dispatchThread使用包私有方法初始化initDispatchThread()

final void initDispatchThread() {
pushPopLock.lock();
try {
if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) {
dispatchThread = AccessController.doPrivileged(
new PrivilegedAction<EventDispatchThread>() {
public EventDispatchThread run() {
EventDispatchThread t =
new EventDispatchThread(threadGroup,
name,
EventQueue.this);
t.setContextClassLoader(classLoader);
t.setPriority(Thread.NORM_PRIORITY + 1);
t.setDaemon(false);
AWTAutoShutdown.getInstance().notifyThreadBusy(t);
return t;
}
}
);
dispatchThread.start();
}
} finally {
pushPopLock.unlock();
}
}

检查此方法的引用后,有3个地方调用此方法:

  1. 在私有方法EventQueue#wakeup(boolean)
  2. 在私有方法EventQueue#postEventPrivate(AWTEvent) (这是由公共方法调用EventQueue#postEvent(AWTEvent)
  3. 在包私有方法EventQueue#createSecondaryLoop(Conditional, EventFilter, long)

initDispatchThread()被调用时, dispatchThread检查确保它尚未初始化。 有几个方法,你可以查看在JDK类的全部源代码(最简单的幸福附加源); 看看这些方法,如果你真的有兴趣。

所以,现在我们知道EventQueue包含线程,每当它实际上需要的是创建线程(事件被发布)。 时间谈这个的地方队列所在,以及如何的事情与它进行通信。

如果检查代码EventQueue#invokeLater(Runnable) (这是由它的所谓SwingUtilities对应),你会看到它调用Toolkit.getEventQueue().postEvent(...) 这告诉我们队列位于Toolkit

里面的Toolkit类,我们可以看到,它的创建(如果没有的话),我们要求它的任何时间。 它使用反射来创建对象:

public static synchronized Toolkit getDefaultToolkit() {
if (toolkit == null) {
try {
java.lang.Compiler.disable();

java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
String nm = null;
Class<?> cls = null;
try {
nm = System.getProperty("awt.toolkit");
try {
cls = Class.forName(nm);
} catch (ClassNotFoundException e) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
if (cl != null) {
try {
cls = cl.loadClass(nm);
} catch (ClassNotFoundException ee) {
throw new AWTError("Toolkit not found: " + nm);
}
}
}
if (cls != null) {
toolkit = (Toolkit)cls.newInstance();
if (GraphicsEnvironment.isHeadless()) {
toolkit = new HeadlessToolkit(toolkit);
}
}
} catch (InstantiationException e) {
throw new AWTError("Could not instantiate Toolkit: " + nm);
} catch (IllegalAccessException e) {
throw new AWTError("Could not access Toolkit: " + nm);
}
return null;
}
});
loadAssistiveTechnologies();
} finally {
// Make sure to always re-enable the JIT.
java.lang.Compiler.enable();
}
}
return toolkit;
}

工具包是一个抽象类。 相反,这个实例化类的一个对象,我们正在创建工具包的一个子类的实例: SunToolkit 。 我们需要知道这一点,看看在创建队列的位置。

一旦我们有了工具包,我们可以访问它的EventQueue使用Toolkit#getSystemEventQueue() 该望远镜被保护的抽象方法getSystemEventQueueImpl() 我们必须检查出的子类,看看这个方法的实现。 在SunToolkit类,我们有:

protected EventQueue getSystemEventQueueImpl() {
return getSystemEventQueueImplPP();
}

// Package private implementation
static EventQueue getSystemEventQueueImplPP() {
return getSystemEventQueueImplPP(AppContext.getAppContext());
}

public static EventQueue getSystemEventQueueImplPP(AppContext appContext) {
EventQueue theEventQueue = (EventQueue) appContext.get(AppContext.EVENT_QUEUE_KEY);
return theEventQueue;
}

(EventQueue) appContext.get(AppContext.EVENT_QUEUE_KEY)队列快到appContext工具包。 现在我们要做的就是寻找到队列被添加到应用程序上下文:

public SunToolkit() {
Runnable initEQ = new Runnable() {
public void run() {
EventQueue eventQueue;

String eqName = System.getProperty("AWT.EventQueueClass", "java.awt.EventQueue");

try {
eventQueue = (EventQueue) Class.forName(eqName).newInstance();
} catch (Exception e) {
e.printStackTrace();
System.err.println("Failed loading " + eqName + ": " + e);
eventQueue = new EventQueue();
}
AppContext appContext = AppContext.getAppContext();
appContext.put(AppContext.EVENT_QUEUE_KEY, eventQueue); //queue added here

PostEventQueue postEventQueue = new PostEventQueue(eventQueue);
appContext.put(POST_EVENT_QUEUE_KEY, postEventQueue);
}
};

initEQ.run();
}

因此,一个快速概述:

  1. 该EDT位于内的EventQueue
  2. EventQueue中位于工具箱内
  3. 在创建工具包创建的队列
  4. 该工具包要么手动创建(通过调用Toolkit.getDefaultToolkit()或者当程序的其他部分(如Swing组件发布的数据队列)的调用)
  5. 由于EDT随时创建一个事件发布到队列(和EDT心不是已经运行)

让我知道如果您对此有任何疑问,

分类:java的 时间:2015-03-15 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.515 (s). 10 q(s)