Как заменить AWQ EventQueue собственной реализацией
Чтобы отладить странное поведение в Swing-приложении, я бы хотел заменить AWT EventQueue своей собственной реализацией.
Возможно ли это? Как?
На всякий случай вам интересно:
-
реализация будет простой оболочкой вокруг обычной Eventqueue, выполняя некоторые протоколирования.
-
Проблема, которую я хотел бы отлаживать, - это TableCellEditor, который отлично работает в небольшом демонстрационном приложении, но когда он помещается в реальное приложение, stopCellEditing вызывается немедленно из-за какого-то события. Я хотел бы получить доступ к событию, чтобы узнать, откуда он отправляется.
Ответы
Ответ 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);
}
}
}
Ответ 2
Будьте осторожны с java 1.7. Там bug. Решение, размещенное rancidfishbreath, отлично с java 1.6, но приводит к применению Swing, которое никогда не выходит с java 1.7.
В JDK 1.7 вам нужно установить новый EvenQueue в поток Event Dispatch... и вне его в 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);
}
}
}
Ответ 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]