java 是否可以将 JFrame 放在前面而不是焦点?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4788953/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to bring JFrame to front but NOT focus?
提问by Johann Fridriksson
I'm writing a Java app (Swing GUI) that periodically pops up a JFrame.
我正在编写一个定期弹出 JFrame 的 Java 应用程序(Swing GUI)。
Is it possible somehow to bring the window to front (foo.setAlwaysOnTop(true) would be even better) but withouthaving it focus?
是否有可能以某种方式将窗口放在前面(foo.setAlwaysOnTop(true) 会更好)但没有焦点?
Some people move their eyes away from the screen from time to time to look at their keyboard while typing, and I'm sure that if this window would always capture the keyboard focus people would get really annoyed as it's causing them to lose quite a few keystrokes every time it pops up unnoticed.
有些人在打字时不时将视线从屏幕上移开看键盘,我敢肯定,如果这个窗口总是捕捉到键盘焦点,人们会非常生气,因为这会导致他们失去很多每次弹出时都会被忽视。
In other cases, even when the user is actually capable of typing without looking at the keyboard all the time, having a window pop up and get focus could cause unwanted actions from the pop-up window itself (some Tab
+Enter
combination for example, where the user accidentally selects an option she really wouldn't had selected otherwise).
在其他情况下,即使用户实际上能够在不一直看键盘的情况下打字,弹出窗口并获得焦点可能会导致弹出窗口本身发生不需要的操作(例如某些Tab
+Enter
组合,其中用户不小心选择了一个她原本不会选择的选项)。
Thanks in advance!
提前致谢!
Update
更新
As Jonas suggests, foo.setFocusableWindowState(false);
seems to work if called after the window has been rendered (tested on Gnome only).
正如 Jonas 所建议的,foo.setFocusableWindowState(false);
如果在渲染窗口之后调用似乎可以工作(仅在 Gnome 上测试)。
This does not work:
这不起作用:
foo.setFocusableWindowState(false);
foo.setVisible(true);
foo.setFocusableWindowState(true);
However, this does:
但是,这确实:
foo.setFocusableWindowState(false);
foo.setVisible(true);
Thread.sleep(1000);
foo.setFocusableWindowState(true);
I'll have to see if there's an event I can catch/listen to that allows me to do foo.setFocusableWindowStatue(true);
when appropriate.
我必须看看是否有我可以捕捉/聆听的事件,以便我foo.setFocusableWindowStatue(true);
在适当的时候做。
I consider my problem solved.
我认为我的问题解决了。
回答by Jonas
This may work:
这可能有效:
foo.setFocusableWindowState(false);
回答by Daniel
As of Java 1.7 you can call
从 Java 1.7 开始,您可以调用
frame.setAutoRequestFocus(false);
回答by Spencer Kormos
I recently ran into the same problem, and the tentative solution has been:
我最近遇到了同样的问题,暂定的解决方案是:
JFrame frame = ...;
frame.setExtendedState(JFrame.NORMAL);
frame.setAlwaysOnTop(true);
frame.requestFocus();
frame.setAlwaysOnTop(false);
回答by Manidip Sengupta
Suggestion: In the GUI Component that creates the Frame, put 2 consecutive calls:
建议:在创建Frame的GUI组件中,连续调用2次:
frameJustCreated.requestFocus();
this.requestFocus();
1st one bring the window of the new JFrame to the top, 2nd one keeps the window where the user is typing at the top.
第一个将新 JFrame 的窗口带到顶部,第二个将用户正在键入的窗口保持在顶部。
回答by Christoph Bimminger
If you want to call setFocusableWindowState(true) in an event (so, not to wait e.g. 1 second), you can add a WindowListener (e.g. derived from WindowAdapter) that changes the property:
如果您想在事件中调用 setFocusableWindowState(true)(因此,不要等待例如 1 秒),您可以添加更改属性的 WindowListener(例如派生自 WindowAdapter):
appFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
super.windowOpened(e);
e.getWindow().setFocusableWindowState(true);
}
});
appFrame.setFocusableWindowState(false);
appFrame.setVisible(true);
回答by Ravinda lakshan
JInternalFrame toFront()
calls to moveToFront()
JInternalFrametoFront()
调用moveToFront()
Override moveToFront()
覆盖 moveToFront()
public void moveToFront() {
Window window = SwingUtilities.getWindowAncestor(this);
Component focusOwner = (window != null) ? window.getFocusOwner() :
null;
boolean descendant = false;
if (window != null && focusOwner != null &&
SwingUtilities.isDescendingFrom(focusOwner, this)) {
descendant = true;
requestFocus();
}
super.moveToFront();
if (descendant) {
focusOwner.requestFocus();
}
}
the fix is in moveToFront to check if a child has focus, if it does, then temporarily request focus on the internal frame. After the internal frame has movthe ed to front, then request focus back on the previously focused component. This will ensure the appropriate events are generated.
修复是在 moveToFront 中检查孩子是否有焦点,如果有,则暂时请求将焦点放在内部框架上。在内部框架将 ed 移到前面后,然后请求焦点回到先前聚焦的组件上。这将确保生成适当的事件。