Как выбрать поток AWT-EventQueue, если их несколько
я успешно ввел свой собственный Java-код в запущенное приложение Oracle Forms, используя DLL-инъекцию и некоторые уловки jni. (Windows 7, 32 бита, Oracle Forms 11, JRE Java 8)
я могу пересечь дерево компонентов и запросить и установить значения в некоторых основных объектах Java, таких как объекты из класса oracle.forms.ui.VTextField
я застрял при попытке имитировать пользователя нажмите на oracle.apps.fnd.ui.Button
я пробовал 2 вещи :
- звоните
simulatePush
методAbstractButton
класс - вызов
activate
методPushButton
класс
(2 класса находятся в иерархии классов для Button
)
результаты были идентичны:
1. Сначала он работает нормально: когда кнопка является кнопкой "поиск", поиск выполняется и отображаются результаты.
2. Затем он сразу же разбивает приложение, с всплывающим сообщением FRM-92100 Your connection to the Server was interrupted
.
оттуда, приложение подвешенный.
обновление: Кажется, что ошибка, которая вызывает отключение от сервера:
java.ленг.SecurityException: этот KeyboardFocusManager не является установлен в контексте текущего потока в Ява.ОУ.Keyboardfocusmanager не.checkCurrentKFMSecurity (неизвестный источник) на Яве.ОУ.Keyboardfocusmanager не.getGlobalFocusOwner (неизвестный источник) на Ява.ОУ.Keyboardfocusmanager не.processSynchronousLightweightTransfer (неизвестно Источник) в солнце.ОУ.окна.WComponentPeer.processSynchronousLightweightTransfer (родной Метод) на солнце.ОУ.окна.WComponentPeer.requestFocus(неизвестный Источник) на java.ОУ.Деталь.requestFocusHelper (неизвестный источник) на Ява.ОУ.Деталь.requestFocusHelper (неизвестный источник) на Ява.ОУ.Деталь.requestFocus(неизвестный источник) на оракул.формы.обработчик.UICommon.updateFocus (неизвестный источник) на оракул.формы.обработчик.UICommon.setFVP (неизвестный источник) на оракул.формы.обработчик.UICommon.setFVP (неизвестный источник) на оракул.формы.обработчик.UICommon.onUpdate (неизвестный источник) в оракул.формы.обработчик.ComponentItem.onUpdate (неизвестный источник) в оракул.формы.обработчик.JavaContainer.onUpdate (неизвестный источник) в оракул.формы.обработчик.UICommon.onUpdate (неизвестный источник) в оракул.формы.двигатель.Runform.onUpdateHandler (неизвестный источник) в оракул.формы.двигатель.Runform.processMessage (неизвестный источник) на оракул.формы.двигатель.Runform.processSet (неизвестный источник) на оракул.формы.двигатель.Runform.onMessageReal (неизвестный источник) at оракул.формы.двигатель.Runform.onMessage (неизвестный источник) в оракул.формы.двигатель.Runform.processEventEnd (неизвестный источник) на оракул.ewt.lwAWT.LWComponent.redispatchEvent(неизвестный источник) на оракул.ewt.lwAWT.LWComponent.processEvent (неизвестный источник) at оракул.ewt.кнопка.кнопка.запустить(неизвестный источник) на солнце.отражать.NativeMethodAccessorImpl.invoke0 (собственный метод) at солнце.отражать.NativeMethodAccessorImpl.invoke (неизвестный источник) at солнце.отражать.DelegatingMethodAccessorImpl.invoke (неизвестный источник) at Ява.ленг.отражать.Метод.invoke (неизвестный источник) at CustomAWT.run (CustomAWT.java: 34) at Ява.ОУ.событие.InvocationEvent.отправка (неизвестный источник) по адресу Ява.ОУ.EventQueue.dispatchEventImpl (неизвестный источник) на Ява.ОУ.EventQueue.доступ к 400$(неизвестный источник) на Ява.ОУ.EventQueue$2.выполнить (неизвестный источник) в Ява.ОУ.EventQueue$2.выполнить (неизвестный источник) в Ява.безопасность.AccessController.doPrivileged(родной метод) на Ява.безопасность.Accesscontrolcontext, в$1.doIntersectionPrivilege (неизвестно Источник) на java.ОУ.EventQueue.dispatchEvent (неизвестный источник) на Ява.ОУ.EventDispatchThread.pumpOneEventForFilters (неизвестный источник) на Яве.ОУ.EventDispatchThread.pumpEventsForFilter (неизвестный источник) на Ява.ОУ.EventDispatchThread.pumpEventsForHierarchy (неизвестно Источник) на java.ОУ.EventDispatchThread.pumpEvents (неизвестный источник) на Яве.ОУ.EventDispatchThread.pumpEvents (неизвестный источник) на Ява.ОУ.EventDispatchThread.запустить(неизвестный источник)
мой код здесь: CustomAWT.run(CustomAWT.java:34)
и с invokeLater
. Проблема: при вызове oracle.ewt.button.PushButton.activate
метод я не в правильном EDT.
используя "список потоков" в консоли Java, I got:
Dump thread list ...
Group main,ac=30,agc=2,pri=10
main,5,alive
traceMsgQueueThread,5,alive,daemon
Timer-0,5,alive
Java Plug-In Pipe Worker Thread (Client-Side),5,alive,daemon
AWT-Shutdown,5,alive
AWT-Windows,6,alive,daemon
AWT-EventQueue-0,6,alive
SysExecutionTheadCreator,5,alive,daemon
CacheMemoryCleanUpThread,5,alive,daemon
CacheCleanUpThread,5,alive,daemon
Browser Side Object Cleanup Thread,5,alive
JVM[id=0]-Heartbeat,5,alive,daemon
Windows Tray Icon Thread,5,alive
Thread-13,5,alive
Group Plugin Thread Group,ac=3,agc=0,pri=10
AWT-EventQueue-1,6,alive
TimerQueue,5,alive,daemon
ConsoleWriterThread,6,alive,daemon
Group http://xxxx.xxxx.xxxxx.xx:8001/OA_JAVA/-threadGroup,ac=13,agc=0,pri=4
Applet 1 LiveConnect Worker Thread,4,alive
AWT-EventQueue-2,4,alive
thread applet-oracle/apps/fnd/formsClient/FormsLauncher.class-1,4,alive
Applet 2 LiveConnect Worker Thread,4,alive
thread applet-oracle.forms.engine.Main-2,4,alive
Forms-StreamMessageReader,4,alive
Forms-StreamMessageWriter,4,alive
HeartBeat,4,alive
Busy indicator,1,alive,daemon
TaskScheduler timer,4,alive
CursorIdler,4,alive
Thread-14,4,alive
Flush Queue,4,alive
Done.
Итак, есть три AWT-EventQueue
потоки... Теперь вопрос: как запросить / получить правильный, и как сделать Runnable
перешло к invokeLater
для запуска в " хорошем потоке "(я думаю, что хороший-последний (AWT-EventQueue-2
)
5 ответов
после многих экспериментов и поисков google с ключевыми словами, как EventQueue
и ThreadGroup
Я, наконец, нашел решение (в Для Меня категория, заметь).
я использую sun.awt.AppContext
класса. Некоторые документы и источники здесь (grepcode.com)
- получить коллекцию работает
AppContext
С помощьюgetAppContexts
метод. - для каждого полученного
AppContext
, егоThreadGroup
С помощьюgetThreadGroup
метод. - с
чтобы получить правильный поток EDT независимо от вашей группы потоков, вы можете использовать SunToolkit.targetToAppContext(Object target)
, и для параметра вы можете кормить его компонентом AWT, на который вы собираетесь действовать. Пример источник.
затем получите EventQueue с помощью EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);
наконец, создайте новый InvocationEvent с вашим runnable и вызовите postEvent на эквалайзере.
вы должны иметь возможность расширить класс VButton Ваше определение класса должно быть чем-то вроде:
public class AmazingButton extends VButton implements FocusListener
тогда вам нужен init
класс:
public void init(IHandler handler)
{
m_handler = handler;
super.init(handler);
addMouseListener(new ButtonMouseAdapter());
addFocusListener(this);
}
а затем вам нужно реализовать слушателей и сделать некоторые вещи в нем:
public void focusGained(FocusEvent e)
{
if (e.getComponent() == this)
{
// put the focus on the component
e.getComponent().requestFocus();
bFocus = true ;
}
}
public void focusLost(FocusEvent e)
{
bFocus = false ;
}
/**
* Private class to handle user mouse actions
*/
class ButtonMouseAdapter extends MouseAdapter
{
/**
* User moved the mouse over the button
*/
public void mouseEntered(MouseEvent me)
{
bFocus=true ;
mouseON();
}
/**
* User moved the mouse out of the button
*/
public void mouseExited(MouseEvent me)
{
bFocus=false ;
mouseOFF();
}
/**
* User moved the mouse out of the button
*/
public void mousePressed(MouseEvent me)
{
bPressed = true ;
}
/**
* User moved the mouse out of the button
*/
public void mouseReleased(MouseEvent me)
{
bPressed = false ;
}
}
Я надеюсь, что этот код работает для вас.
в отношении
я успешно ввел свой собственный Java-код в запущенное приложение Oracle Forms, используя DLL-инъекцию и некоторые уловки jni.
это настоящая проблема здесь, ИМО.
вы страдаете от цель ремонта, что означает, что вы, программист, имеете фиксированное ментальное представление о том, какого рода решение они хотят, и это ослепляет вас ко всему остальному. Фиксация цели привела к авиакатастрофам, так как даже высоко опытные и умные пилоты (на самом деле целые кабины! ) настолько зациклились на одной проблеме в одном мышлении, что пропустили мимо ушей другие катастрофы.
выйти из этого настроения.
ваше желаемое решение не работает, поэтому двигайтесь дальше и попробуйте что-то еще. Как и разумный вариант, уже представленный вам @nightfox79 и вариациями на этот счет.
вы пытаетесь обойти сложный класс объектов, когда вы, вероятно, просто должны быть расширение существующего класса вы пытаетесь взломать свой путь вокруг. В этом вся основа развития Упс.
DLL / JNI Trickery не имеет места в разумном решении, IMO.
и мне жаль человека, который должен поддерживать и ремонтировать любое решение кода на основе DLL/JNI hack. В этом и заключается безумие.
Ваша теория, что invokeLater()
не работает под правильным EDT, вероятно, неправильно. invokeLater()
будет, согласно документации,всегда очередь код, который вы запрашиваете в списке ожидающий код для обработчика событий AWT, который именно там, где он должен быть. Попытка обойти это почти наверняка вызовет ужасные проблемы. Вся цель invokeLater()
- отложить тяжеловесную обработку в EDT, из которого вы ее вызываете, и запустить ее позже в том же потоке. Это ошибка в invokeLater()
если это не так, ИМО.
Если, однако, вы хотите проверить, какой код потока выполняется, то единственный тест, который я знаю, - это использовать это в вашем коде ;
if (SwingUtilities.isEventDispatchThread())
{
System.err.println("Is running on EDT");
}
else
{
System.err.println("Is not running on EDT");
}
Я пытаюсь подтолкнуть мой код Java в Оракл форм приложение, в основном, я пытаюсь автоматизировать Оракл форм потоков через интерфейс ,сверху комментария кажется, что вы сделали фантастическую работу, чтобы сделать это , вы можете направлять мне, для этого я создал агент Java, проблема состоит в том, чтобы придать, что в ОС Oracle форм апплет, который работает в интернете.и вторая проблема - при работе над методом premain в моем Java agent, что я должен использовать для идентификации объектов oracle forms, для обычного апплет я использую Toolkit tk = Toolkit.getDefaultToolkit (); а затем я слушаю отправленное событие из windows .пожалуйста, направьте меня на это, я серьезно сталкиваюсь с проблемой автоматизации этого