首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当有几个AWT-EventQueue线程时,如何选择它们

当有几个AWT-EventQueue线程时,如何选择它们
EN

Stack Overflow用户
提问于 2015-12-11 15:38:05
回答 4查看 1.8K关注 0票数 10

我成功地在运行中的Oracle窗体应用程序中注入了自己的Java代码,使用了DLL注入和一些jni技巧。(Windows 7,32位,Oracle Forms 11,JRE Java 8)

我能够遍历组件树,并在一些基本的Java对象中查询和设置值,例如来自类oracle.forms.ui.VTextField的值。

当我试图模拟用户点击oracle.apps.fnd.ui.Button时,我被困住了

我试了两件事:

  1. 调用simulatePush类的AbstractButton方法
  2. 调用activate类的PushButton方法

(这两个类位于Button的类层次结构中)

结果是一致的: 1。首先,它工作良好:当按钮是“搜索”按钮时,搜索完成并显示结果。2.然后,它会立即中断应用程序,弹出的名称为FRM-92100 Your connection to the Server was interrupted

从那里起,申请就挂起了。

更新:似乎导致与服务器断开连接的错误是:

java.awt.KeyboardFocusManager.checkCurrentKFMSecurity(Unknown :这个KeyboardFocusManager没有安装在当前线程的上下文中--在java.awt.KeyboardFocusManager.getGlobalFocusOwner(Unknown Source)、在java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer(Unknown Source)、在java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer(Unknown Source)、在sun.awt.windows.WComponentPeer.processSynchronousLightweightTransfer(Native Source)、在sun.awt.windows.WComponentPeer.requestFocus(Unknown Source)、在java.awt.Component.requestFocusHelper(未知源)、在java.awt.Component上。(未知源)在oracle.forms.handler.UICommon.updateFocus(Unknown源的java.awt.Component.requestFocus(未知源)在oracle.forms.handler.UICommon.setFVP(未知源)在oracle.forms.handler.UICommon.setFVP(未知源)在oracle.forms.handler.ComponentItem.onUpdate(Unknown源(在oracle.forms.handler.JavaContainer.onUpdate(Unknown源)oracle.forms.handler.UICommon.onUpdate(Unknown来源)在oracle.forms.engine.Runform.onUpdateHandler(Unknown来源)在oracle.forms.engine.Runform.processMessage(Unknown来源)在oracle.forms.engine.Runform.processSet(Unknown来源)在oracle.forms.engine.Runform.onMessageReal(Unknown来源)在oracle.forms.engine.Runform.onMessage(未知来源在oracle.forms.engine.Runform.processEventEnd(Unknown来源)在甲骨文。oracle.ewt.lwAWT.LWComponent.processEvent(Unknown源(未知源)、sun.reflect.NativeMethodAccessorImpl.invoke0(Native方法(未知源)、sun.reflect.NativeMethodAccessorImpl.invoke(Unknown源( sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown源)、java.lang.reflect.Method.invoke(未知源)、CustomAWT.run(CustomAWT.java:34)(未知来源)在java.awt.EventQueue$2.运行(未知源)在java.awt.EventQueue$2.运行(未知源)在java.security.AccessController.doPrivileged(Native方法运行(未知源)在java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown来源)在java.awt.EventQueue.dispatchEvent(未知源)在java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown源)在java.awt.EventDispatchThread.pumpEventsForFilter(Unknown源)在java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown源)在java.awt.EventDispatchThread.pumpEvents(Unknown源)在java.awt.EventDispatchThread.pumpEvents(Unknown源)在java.awt.EventDispatchThread.run(未知源)

我的代码在这里:CustomAWT.run(CustomAWT.java:34),并与invokeLater一起调用。问题可能是:当调用oracle.ewt.button.PushButton.activate方法时,I不在正确的EDT.中。

在Java控制台中使用“列表线程”,我得到了:

代码语言:javascript
复制
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) )。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-12-21 17:21:25

经过大量的实验和谷歌搜索的关键字,如EventQueueThreadGroup,我终于找到了一个解决方案(在为我的工作类别,请注意)。

我使用sun.awt.AppContext类。一些文档和源这里 (grepcode.com)

  1. 使用AppContext方法获取正在运行的getAppContexts的集合。
  2. 对于每个检索到的AppContext,使用getThreadGroup方法获取他的ThreadGroup
  3. 对于ThreadGroup对象,使用getName方法。
  4. 当线程组的名称以窗体应用程序的http: address开头时,使用Objectget方法检索键名为sun.awt.AppContext.EVENT_QUEUE_KEYAppContext属性。
  5. 检索到的对象是一个EventQueue。创建一个java.awt.event.InvocationEvent对象,将您的Runnable传递给CTOR,并使用EventQueuepostEvent方法。
  6. 您的run方法将在正确的线程中执行。

备注:

  • 这个答案是一个特定的,为我工作,一个通过Internet链接启动的Oracle应用程序的解决方案,并且运行在一个java.exe进程中。在这种情况下,三个线程组如问题中所示:mainPlugin Thread Grouphttp://xxxx.xxxx.xxxxx.xx:8001/OA_JAVA/-threadGroup --您的里程可能有所不同。
  • 如果您不使用完全反射,而是导入sun.awt.AppContext,编译器可能会以warning: sun.awt.AppContext is Sun proprietary API and may be removed in a future release的形式发出警告,这不是很酷,但我暂时会接受这一点。
  • run方法中,我使用oracle.ewt.lwAWT.AbstractButtonsimulatePush方法测试OK。
  • 这里模拟的方法是invokeLater。对于invokeAndWait,围绕postEvent调用需要更多的代码。作为起点,请参阅EventQueue类的一些源代码。
票数 1
EN

Stack Overflow用户

发布于 2017-10-10 10:57:46

要获得正确的EDT线程,而不管您的线程组是什么,您可以使用SunToolkit.targetToAppContext(Object target),对于参数,可以将您想要操作的AWT组件提供给它。例如来源

然后使用EventQueue获取EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);

最后,使用可运行的InvocationEvent创建一个新的postEvent,并在EQ上调用postEvent。

票数 1
EN

Stack Overflow用户

发布于 2015-12-17 10:46:09

您应该能够扩展VButton类,您的类定义应该如下所示:

代码语言:javascript
复制
public class AmazingButton extends VButton implements FocusListener

然后需要一个init类,如下所示:

代码语言:javascript
复制
public void init(IHandler handler)
  {
    m_handler = handler;
    super.init(handler);
    addMouseListener(new ButtonMouseAdapter());
    addFocusListener(this);
  }  

然后,您需要实现侦听器,并在其中做一些事情:

代码语言:javascript
复制
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 ;
    }

  }

我希望这个代码对你有用。

问候

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34227178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档