Windows 具有防止 Windows 窃取焦点的功能;相反,它会闪烁任务栏图标。在 XP 中,默认情况下它是打开的(我见过的唯一改变它的地方是使用 TweakUI,但在某处有一个注册表设置)。在 Vista 中,他们可能已经更改了默认设置和/或将其作为用户可访问的设置通过开箱即用的 UI 公开。
自 Windows 2K 以来,防止窗口将自己强制放在前面并获得焦点是一项功能(我对此表示感谢)。
也就是说,我有一个小 Java 应用程序,用于提醒我在工作时记录我的活动,它每 30 分钟将自己设为活动窗口(当然是可配置的)。它始终在 Windows XP 下始终如一地工作,并且从不闪烁标题栏窗口。它使用以下代码,作为定时器事件触发的结果在 UI 线程中调用:
if(getState()!=Frame.NORMAL) { setState(Frame.NORMAL); }
toFront();
repaint();
(如果最小化第一行会恢复...实际上如果最大化也会恢复它,但我从来没有这样)。
虽然我通常将此应用程序最小化,但通常它只是在我的文本编辑器后面。而且,就像我说的,它总是有效的。
我确实知道您的问题可能是什么 - 也许您的 setVisible() 调用存在竞争条件。 toFront() 可能无效,除非在调用它时实际显示了窗口;我之前在 requestFocus() 上遇到过这个问题。您可能需要将 toFront() 调用放在窗口激活事件的 UI 侦听器中。
2014-09-07: 上述代码在某个时间点停止工作,可能在 Java 6 或 7 中。经过一些调查和实验后,我不得不更新代码以覆盖窗口的 @ 987654323@ 方法这样做(结合上面的修改代码):
setVisible(true);
toFront();
requestFocus();
repaint();
...
public @Override void toFront() {
int sta = super.getExtendedState() & ~JFrame.ICONIFIED & JFrame.NORMAL;
super.setExtendedState(sta);
super.setAlwaysOnTop(true);
super.toFront();
super.requestFocus();
super.setAlwaysOnTop(false);
}
从 Java 8_20 开始,这段代码似乎运行良好。