【问题标题】:How to replace the AWT EventQueue with own implementation [closed]如何用自己的实现替换 AWT EventQueue [关闭]
【发布时间】:2011-03-10 15:38:23
【问题描述】:

为了调试 Swing 应用程序中的奇怪行为,我想用我自己的实现替换 AWT EventQueue。

这可能吗?怎么样?

以防万一您有兴趣:

  • 实现将是对普通事件队列的简单包装,进行一些日志记录。

  • 我要调试的问题是 TableCellEditor,它在一个小演示应用程序中运行良好,但是当放入实际应用程序时,由于某些事件,stopCellEditing 会立即被调用。我想访问该事件以了解它的来源。

【问题讨论】:

  • registering an AWTEventListener 会是一个更简单的解决方案吗?
  • @andrew-barber 这个问题怎么太宽泛了?对于不同的 java 版本,它有两个非常简洁的答案

标签: java swing eventqueue


【解决方案1】:

EventQueue 有一个名为 push() 的方法,它可以完全按照您的意愿进行操作。这是一个小演示:

public class QueueTest {
    public static void main(String[] args) throws InterruptedException, InvocationTargetException {
        EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
        eventQueue.push(new MyEventQueue());

        EventQueue.invokeAndWait(new Runnable() {
            public void run() {
                System.out.println("Run");
            }
        });
    }

    private static class MyEventQueue extends EventQueue {
        public void postEvent(AWTEvent theEvent) {
            System.out.println("Event Posted");
            super.postEvent(theEvent);
        }
    }
}

【讨论】:

  • 我可能错了,但我认为问题不在于编写 EventQueue 子类,而在于如何让 AWT/Swing 使用它而不是 EventQueue
  • 但这正是 push 似乎所做的。来自 javadoc: push(EventQueue newEventQueue) 将现有的 EventQueue 替换为指定的。
【解决方案2】:

谨慎使用 java 1.7。有一个bug。 rancidfishbreath 发布的解决方案在 java 1.6 中是完美的,但导致 Swing 应用程序永远不会在 java 1.7 中退出。 在 JDK 1.7 下,您必须在 Event Dispatch 线程中安装新的 EvenQueue ...并在 JDK 1.6 的外部安装...编写一次,到处运行 ;-)

这是一个通用的解决方案...希望 1.8 不会改变它;-)

import java.awt.AWTEvent;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;

public class QueueTest {
    public static void main(String[] args) throws InterruptedException, InvocationTargetException {
        if (!isJava7Like()) setQueue();

        EventQueue.invokeAndWait(new Runnable() {
            public void run() {
                if (QueueTest.isJava7Like()) setQueue();
                System.out.println("Run");
            }
        });
    }

    private static void setQueue() {
        EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
        eventQueue.push(new MyEventQueue());
    }

    private static boolean isJava7Like() {
        return Float.parseFloat(System.getProperty("java.specification.version")) > 1.6;
    }

    private static class MyEventQueue extends EventQueue {
        public void postEvent(AWTEvent theEvent) {
            System.out.println("Event Posted");
            super.postEvent(theEvent);
        }
    }
}

【讨论】:

  • 有趣 - 虽然我注意到键事件和鼠标事件(我感兴趣的那些)不会发送到“post”,而是从系统事件队列转发到“postEventPrivate()”即使具有完全访问权限也无法覆盖。 :|
【解决方案3】:

这很好。扩展 EventQueue 将为您提供所有 AWTEvents 的句柄。

您将如何处理所有事件。 事件列表如下。

[AWTEvent, BeanContextEvent, CaretEvent, ChangeEvent, ConnectionEvent, DragGestureEvent, DragSourceEvent, DropTargetEvent, FlavorEvent, HandshakeCompletedEvent, HyperlinkEvent, LineEvent, ListDataEvent, ListSelectionEvent, MenuEvent, NamingEvent, NamingExceptionEvent, NodeChangeEvent, Notification, PopupMenuEvent, PreferenceChangeEvent, PrintEvent, PropertyChangeEvent, RowSetEvent、RowSorterEvent、SSLSessionBindingEvent、StatementEvent、TableColumnModelEvent、TableModelEvent、TreeExpansionEvent、TreeModelEvent、TreeSelectionEvent、UndoableEditEvent、UnsolicitedNotificationEvent]

【讨论】:

    猜你喜欢
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 2013-05-23
    • 2017-05-09
    • 2015-01-12
    • 1970-01-01
    • 2017-10-26
    相关资源
    最近更新 更多