9

javadoc 声明要求排队的EventQueue事件按顺序分派。

保证在后续用户事件(例如 a )之前调度Runnables 排队是否正确?换句话说,如果用户事件发生在之后,事件处理程序可以在入队之前执行。EventQueue.invokeLaterMouseEventRunnableEventQueue.invokeLater

谢谢!

4

2 回答 2

10

API 文档声明事件是

与它们入队的顺序相同。

但是,如果您检查源代码,您会发现情况并非总是如此,尽管它在大多数情况下基本上是正确的。

于 2013-01-25T17:28:57.163 回答
6

可能最好解释一下您要做什么。一般来说,事件分派系统的设计使您不应该知道或担心它的内部结构。如果您正在编写一个直接更新 UI 的事件处理程序,那么不使用 Runnable 并内联执行更新可能是有意义的。但是,如果您的事件处理程序执行一些计算或处理需要不确定的时间量,那么您将希望使用一个线程,该线程最终将使用带有 Swing.invokeLater 调用的 Runnable 执行 UI 更新。需要知道事件被分派时的顺序意味着您正在尝试在您的逻辑中建立可能属于其他地方的假设。

例如,考虑一个鼠标单击事件处理程序,它在线程中执行繁重的处理(网络下载或 DBMS 查询),然后更新 UI 中的文本标签。您可能希望确保在用户单击 UI 上的其他位置之前进行处理和 UI 更新,以避免处理单击的歧义。在这种情况下,您可能会在初始鼠标点击事件中立即禁用 UI 或 UI 的某些可点击部分,以便 UI 保持响应但保护您的 onMouse 处理程序不重新进入,直到原始点击事件完全处理。(请原谅下面的代码片段,因为我完成 Swing 已经有好几年了,它更像是伪代码。)

void setUIEnabled(boolean enable) {
   for(Button eachUIButton : getAllClickableButtons()) {
      eachUIButton.setEnabled(enable);
   }
}

void onMouseClick(MouseEvent event) {
   setUIEnabled(false);
   new Thread(
      new Runnable() {
         public void run() {
            final String result = doLengthyProcessing();
            enableRunnable = new Runnable() {
               public void run() {
                  setUIEnabled(true);
                  updateTextLabelFromLengthyProcess(result);
               }
            };
            Swing.invokeLater(enableRunnable);
         }
      }
   ).start();
}

这里的想法是您编写逻辑,使其不依赖于调度事件的随机顺序,而是承认处理可能比下一个传入的鼠标事件花费更长的时间,并为此类时间做出规定。一个微妙的改进是还绘制一个进度指示器或进度微调器,以指示正在向用户完成工作。

于 2013-01-25T17:38:17.847 回答