【问题标题】:How can I use Java to read/draw/interact with another Java window/applet如何使用 Java 读取/绘制/与另一个 Java 窗口/小程序交互
【发布时间】:2010-06-04 17:13:04
【问题描述】:

我有兴趣编写一个执行以下操作的 Java 程序。

  • 附加到当前运行的 Swing 窗口或小程序,在另一个 JVM 中运行
    • 或者,加载 Java 应用程序以便能够执行上述操作
  • 从窗口中读取颜色
  • 向窗口发送鼠标和键盘事件

我希望制作某种直接与 GUI 交互的测试和自动化工具。

我正在寻找有关如何完成上述所有步骤的建议。提前致谢。

【问题讨论】:

    标签: java swing automation applet jvm


    【解决方案1】:

    捕获另一个进程的输出不会那么容易 - 如果您的测试应用直接在同一个 java VM 中启动 swing 应用,这将是最简单的。

    然后您可以在 JFrame 上调用 paint(Graphics g),向组件传递屏幕外图形 (BufferedImage - details here。) 您可以通过 EventQueue.postEvent(AWTEvent) 将输入事件发送到 AWT 事件队列 - 这可以使用模拟 AWT 输入。

    但是,您是否调查过现有的测试框架? FEST 有一个专门用于操作和验证 UI 的测试框架。还有abbot,年纪大了,受到一些人的青睐。还有一些测试框架专注于功能和状态,而不是屏幕抓取和输入事件。这些不是更好/更差,而是互补的。 状态 UI 测试包括SwingUnitUISpec4J

    那里有很多好的框架,所以在构建另一个框架之前做一些研究可能是值得的!

    编辑: 启动应用程序,而不是运行

    java -cp ... a.b.c.AppToTest
    

    你跑

    java -cp ... TestWrapper AppToTest
    

    并像这样实现 TestWrapper

    public class TestWrapper {
    /* args[0] - class to launch. Remainder of args passed to launched app.*/
       public static void main(String[] args) throws Exception
       {
          Class app = Class.forName(args[0]);
          Method main = app.getDeclaredMethod("main", new Class[] { (new String[1]).getClass()});
          String[] appArgs = new String[args.length-1];
          System.arraycopy(args, 1, appArgs, 0, appArgs.length);
          main.invoke(null, appArgs);
          // now you have just launched another application inside the same VM
       }
    

    }

    启动应用后,您可以等待应用启动,然后进行投票 Window.getOwnerlessWindows 查找应用创建的任何顶级窗口。

    更直接的方法是安装您自己的RepainManager - 您可以委托给现有的。所有窗口绘制操作都会调用它,因此您可以直接进入窗口层次结构的核心,

    您还可以注册以侦听 AWT EventQueue 上的所有事件。这也将让您深入了解应用程序中发生的事情,并从中确定创建了哪些窗口、焦点所在等。

    【讨论】:

    • 我对如何在当前虚拟机中运行应用程序感到困惑。我能够启动整个应用程序,但不一定能够只实例化有问题的 JFrame,因为它在加载时有一堆复杂的东西。除了整个应用程序本身,我认为我无法运行任何东西。
    • 感谢您解释如何启动。现在我已经启动了另一个应用程序,我将如何获得对它创建的窗口的引用,可能在其生命周期的后期?
    【解决方案2】:

    如果您可以控制“已测试”应用程序,我认为您最好的选择可能是创建一个服务器,允许测试程序将调用代理到内部 java.awt.Robot

    【讨论】:

      【解决方案3】:

      您需要在目标应用中编写并支持特定协议(您自己发明的)。

      您可以使用 RMI、Sockets 或其他形式的 RCP(Protobuf、JSON、WebService 等)来实现

      关键是,您必须在应用程序中打开一个端口,并且能够理解来自外部来源的指令。

      如果您正在寻找一种测试方法,我听说Abbot 是一个不错的选择。看一看。

      如果您想操作可能更复杂的应用程序(您没有源代码)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-10
        • 1970-01-01
        • 2013-07-28
        • 1970-01-01
        • 1970-01-01
        • 2012-03-10
        • 1970-01-01
        相关资源
        最近更新 更多