1

我有一个 Swing 应用程序,它由一个设置为 Always On Top 的 JFrame 组成。

在 Windows 下运行时,我使用以下代码分别打开本机默认的电子邮件客户端和浏览器:

Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + Utils.formatMailtoUrl(to, subject, body));
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);

因为 JFrame 设置为 Always On Top 而典型的默认浏览器或电子邮件客户端(我们客户的 IE 和 Outlook)没有以 Always On Top 的方式打开,所以前者阻碍了后者。

我们当前的“解决方案”是在打开原生窗口的同时最小化 JFrame。但事实证明这是一个 508 合规问题,我们被要求:

  1. 不要最小化 JFrame。
  2. 在浏览器或电子邮件客户端关闭后将焦点返回到 JFrame

我想到的策略是“关闭” JFrame 的 Always On Top 状态,并有某种回调或事件侦听器,它将通知 JFrame 电子邮件或浏览器窗口已关闭,然后将 JFrame 切换回Always On Top 状态并设置焦点。

因为这是一个 Java 应用程序,我担心这几乎是不可能的,因为我们正在谈论本机互操作。我的策略是否可行,是否有更好的可行策略,最重要的是,如何做到?!

提前致谢!

4

2 回答 2

1

我不确定是否有本地方法来执行此操作,但您可以运行 tasklist.exe 或 vb 脚本,捕获结果并从那里确定 Outlook 或 IExplore 是否正在运行。这将要求您以合理的时间间隔运行检查,而不是等待事件。

Process p = Runtime.getRuntime().exec("tasklist.exe /FO CSV /FI eq outlook.exe");
BufferedReader input = new BufferedReader (new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
    look for a line containing outlook.exe
}
input.close();

您将不得不分别检查outlook.exe 和iexplorer.exe,因为我认为您不能在此或那个上过滤任务列表。

我敢肯定,这可以概括为查找原始呼叫打开的任何内容。

编辑:既然我已经写了所有这些,我突然想到您的原始调用返回一个进程并且可以使用。所以要尝试一下,启动一个新线程,在该线程中打开默认的电子邮件程序或浏览器,删除“始终在顶部”条件并在返回的进程上调用 waitfor。在那次通话之后,设置“总是在最上面”的条件。该线程将等待进程结束而不会锁定您的 gui 或其他程序功能。

于 2010-10-30T17:37:20.307 回答
0

我在以下方面取得了一些成功:

  1. 当打开浏览器的动作(例如)被触发时,关闭 JFrame Always On Top 设置。
  2. 有一个打开 JFrame Always On Top 设置的窗口焦点操作。
  3. 如果用户没有导航到浏览器以外的任何其他窗口,那么当浏览器关闭时,JFrame 将自动重新获得焦点并因此设置回 Always On Top

我看到这种方法有两个缺点。第一个是用户可能会在关闭浏览器窗口之前手动返回 JFrame 窗口,导致 JFrame 重新获得焦点并卡在 Always On Top 模式。但这可能是可以接受的。第二个问题是 JAWS 版本 9 屏幕阅读器会在 JFrame 重新获得焦点后发疯并重新阅读最后一个焦点组件至少 3 次。

于 2010-11-08T17:28:44.607 回答