是否有可能将JFrame带到前面而不是焦点?

时间:2011-01-25 00:57:00

标签: java swing jframe focus always-on-top

我正在编写一个定期弹出JFrame的Java应用程序(Swing GUI)。

是否有可能以某种方式将窗口置于前面(foo.setAlwaysOnTop(true)会更好)但是没有让它成为焦点?

有些人在打字时不时地将视线从屏幕上移开以查看键盘,我敢肯定,如果这个窗口始终能够捕捉到键盘的焦点,那么人们会非常生气,因为它会导致它们丢失每次弹出时都会发出很多次击键。

在其他情况下,即使用户实际上无需一直查看键盘也能打字,弹出一个窗口并获得焦点可能会导致弹出窗口本身出现不需要的操作(某些{{1}例如,+ Tab组合,用户不小心选择了一个她真的不会选择的选项。

提前致谢!

更新

正如Jonas所说,Enter似乎在窗口渲染后调用(仅在Gnome上测试)。

这不起作用:

foo.setFocusableWindowState(false);

但是,确实

foo.setFocusableWindowState(false);
foo.setVisible(true);
foo.setFocusableWindowState(true);

我必须看看是否有我可以捕捉/收听的事件,这使我可以在适当的时候foo.setFocusableWindowState(false); foo.setVisible(true); Thread.sleep(1000); foo.setFocusableWindowState(true);

我认为我的问题已经解决了。

6 个答案:

答案 0 :(得分:14)

这可能有效:

foo.setFocusableWindowState(false);

答案 1 :(得分:3)

从Java 1.7开始,您可以调用

frame.setAutoRequestFocus(false);

答案 2 :(得分:2)

我最近遇到了同样的问题,暂时的解决方案是:

JFrame frame = ...;
frame.setExtendedState(JFrame.NORMAL);
frame.setAlwaysOnTop(true);
frame.requestFocus();
frame.setAlwaysOnTop(false);

答案 3 :(得分:0)

建议:在创建Frame的GUI组件中,连续2次调用:

frameJustCreated.requestFocus();
this.requestFocus();

第一个将新JFrame的窗口置于顶部,第二个窗口保留用户在顶部键入的窗口。

答案 4 :(得分:0)

如果要在事件中调用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);

答案 5 :(得分:0)

JInternalFrame toFront()调用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();
        }
    }

此修复程序位于moveToFront中,以检查孩子是否有焦点(如果有),然后临时请求将焦点放在内部框架上。内部框架移到最前面之后,然后要求将焦点重新放回到先前聚焦的组件上。这将确保生成适当的事件。

参考 https://bugs.openjdk.java.net/browse/JDK-4309079