java.awt.Robot.waitForIdle() 是无法实现的



我们在夜间UI测试中经常看到计时问题。 测试经常失败,因为在测试代码尝试验证结果之前,java.awt.Robot 执行的事件尚未完成。

我们的代码就像使用:

Point p = cb.getLocationOnScreen();
int m = 5;
if (cb.getWidth()<5||cb.getHeight()<5)
m=3;
System.out.println("Click at " + (p.x+m) + "," + (p.y+m));
robot.mouseMove(p.x + m, p.y + m);
robot.mousePress(MouseEvent.BUTTON1_MASK);
robot.mouseRelease(MouseEvent.BUTTON1_MASK);
robot.waitForIdle();
Thread.sleep(100);
// Verify results...

尽管有java.awt.Robot.waitForIdle()调用,我们仍在增加Thread.sleep以确保事件线程上的事情完成(例如单击按钮或键入文本)。

我发现了这个问题(java.awt.Robot.waitForIdle()是否等待事件被调度?),它说使用java.awt.Toolkit.realSync(),但这不是一个可访问的方法,随着Java 9的到来,我宁愿不在我们的测试中添加任何不必要的反射。

有更好的解决方案吗? 或者人们是否使用 realSync() 或只是增加等待时间,直到测试可靠地通过?

更新

我尝试使用sun.awt.SunToolkit.realSync(),但它在某些测试中挂起并且永远不会返回。 看起来事件线程正在绘制边框等。

看起来我唯一的解决方案是增加睡眠时间,直到测试实际上可以可靠地通过。 呸。

更新 2

我想出了我第一次挂在realSync()上。 这是我们代码中的一个问题,其中一些油漆代码称为 get 方法,该方法调用一个将另一个油漆排队的 set 方法。 永远重复。

修复了我们的代码,realSync() 工作了一段时间,有点。 它似乎仍然在它应该返回之前返回。 不知道为什么,我没有解决方法。

另外,我已经看到realSync()在Java 1.7下运行的Linux机器上挂起和超时,但它在Java 1.8下工作。 这里有非常可靠的工具。/s

所以,回到原来的问题。 判断 UI 更新何时完成的体面方法是什么?

我得出的结论是我确实需要使用SunToolkit.realSync(),它似乎也适用于Java 9。

看起来,虽然我找不到任何确凿的证据,但realSync()等待所有与图形相关的线程,而Robot.waitForIdle()和SwingUntilities.invokeLater()只等待Java EventThread完成它的工作。

如果有人想出更好的答案,我会接受它而不是我的答案。

最新更新