如何在Java中生成事件?
首先,我不是在问事件处理的问题。我知道处理是使用观察者模式实现的 让我举一个小例子。假设我在JFrame上有一个Jbutton。我点击这个按钮的顶部。 现在按钮怎么知道我点击了它 1) 是否有java线程等待单击?如果是这样的话,这个代码从哪里来(等到我点击了部分)?那么每个swing组件是否都在线程顶部等待事件?我想这是一项非常昂贵的任务 2) 如果没有,这是如何工作的 是否有java线程等待单击 是的,它被称为事件调度线程(EDT) 由于Swing中的所有组件都是轻量级的,这意味着只是一个漂亮的动画而已,因此它实际上是顶级组件,比如说,跟踪鼠标单击并将其传递给该像素上的组件的如何在Java中生成事件?,java,swing,events,Java,Swing,Events,首先,我不是在问事件处理的问题。我知道处理是使用观察者模式实现的 让我举一个小例子。假设我在JFrame上有一个Jbutton。我点击这个按钮的顶部。 现在按钮怎么知道我点击了它 1) 是否有java线程等待单击?如果是这样的话,这个代码从哪里来(等到我点击了部分)?那么每个swing组件是否都在线程顶部等待事件?我想这是一项非常昂贵的任务 2) 如果没有,这是如何工作的 是否有java线程等待单击 是的,它被称为事件调度线程(EDT) 由于Swing中的所有组件都是轻量级的,这意味着只是一个漂
JFrame
是否有java线程等待单击
是,java.awt.EventDispatchThread
。下面引用java教程的一段话:
Swing事件处理代码在称为事件的特殊线程上运行
调度线程。大多数调用Swing方法的代码也在上运行
这根线。这是必要的,因为大多数Swing对象方法都是
非“线程安全”:从多个线程调用它们会导致线程风险
干扰或内存一致性错误。一些摆动部件
方法在API规范中标记为“线程安全”;这些可以
可以从任何线程安全地调用。所有其他Swing组件方法
必须从事件分派线程调用。忽略的程序
此规则可能在大多数情况下都能正常运行,但会受到影响
难以重现的不可预测的错误
要回答你的下一个问题
如果是这样的话,这个代码从哪里来(等我被点击后再说)
部分
EventDispatchThread
通过在其run
方法中调用pumpEvents(Conditional)
启动永久事件泵
public void run() {
try {
pumpEvents(new Conditional() {
public boolean evaluate() {
return true;
}
});
} finally {
getEventQueue().detachDispatchThread(this);
}
}
任何事件处理程序都可以选择随时阻止此事件泵,但应通过再次调用pumpEvents(Conditional)
来启动新的泵(而不是新的EDT)。一旦条件
评估为假
,并发送额外的事件
,该辅助事件泵将自动退出
泵事件将调用AWTEvent#getNextEvent
,它将从事件队列中检索事件
然后,是否每个swing组件都在顶部等待事件
线的数量?我想这是一项非常昂贵的任务
java教程再次回答了这个问题
考虑在事件分派线程上运行的代码是很有用的
作为一系列简短的任务。大多数任务都是对
事件处理方法,如ActionListener.actionPerformed。其他
任务可以通过应用程序代码,使用invokeLater或
调用EANDWAIT。事件调度线程上的任务必须快速完成;
如果没有,未处理的事件将备份,用户界面将变为
反应迟钝
事件在独立于平台的类java.awt.EventQueue
中排队。事件存储在给定优先级的队列中,为每个优先级创建一个队列
private static final int LOW_PRIORITY = 0;
private static final int NORM_PRIORITY = 1;
private static final int HIGH_PRIORITY = 2;
private static final int ULTIMATE_PRIORITY = 3;
事件从事件队列中拉出,从
最高优先权。我们在所有队列中按降序前进
请注意,一些通常调用的事件会被缓存以获得更好的性能,例如PaintEvent.Paint
,PaintEvent.UPDATE
,MouseEvent.MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u MOUSE\u
这并不像您想象的那么昂贵。整个堆栈中都使用观察者模式:
用户释放鼠标按钮
鼠标向CPU发送消息,触发硬件中断
操作系统的中断处理程序意识到鼠标在按下按钮后没有移动,即发生鼠标点击。它标识鼠标位置的窗口以及负责该窗口的应用程序,并将鼠标单击的消息放入应用程序的事件队列中
我们的Swing应用程序的“事件调度线程”运行以下形式的循环:
while (!shutdownRequested) {
Event e = retrieveEventFromEventQueue(); // for instance our mouse clicked event
handleEvent(e);
}
在AWT/Swing中,有一个线程执行该代码。第一个调用将被阻止,直到新事件可用为止,handleEvent()将为此事件调用侦听器。也就是说,一个线程执行所有UI更新(这就是为什么不应该在事件侦听器中执行长时间运行的任务,因为这会冻结UI),如果用户不与应用程序交互,则该线程处于睡眠状态
所有谈论世界上设计模式的人和MouseEvent
都知道JFrame
的功能;)我确实想要一个这样的答案