繁体   English   中英

是否可以将 JFrame 放在前面而不是焦点?

[英]Is it possible to bring JFrame to front but NOT focus?

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

是否有可能以某种方式将窗口放在前面(foo.setAlwaysOnTop(true) 会更好)但没有焦点?

有些人在打字时不时地将视线从屏幕上移开看他们的键盘,我敢肯定,如果这个窗口总是能捕捉到键盘焦点,人们会非常生气,因为这会导致他们失去很多每次弹出时都会被忽视。

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

提前致谢!

更新

正如乔纳斯所说, foo.setFocusableWindowState(false); 如果在渲染窗口后调用似乎可以工作(仅在 Gnome 上测试)。

这不起作用:

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

但是,这确实

foo.setFocusableWindowState(false);
foo.setVisible(true);
Thread.sleep(1000);
foo.setFocusableWindowState(true);

我必须看看是否有一个我可以捕捉/监听的事件允许我做foo.setFocusableWindowStatue(true); 在适当的时候。

我认为我的问题解决了。

这可能有效:

foo.setFocusableWindowState(false);

从 Java 1.7 开始,您可以调用

frame.setAutoRequestFocus(false);

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

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

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

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

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

第一个将新 JFrame 的窗口带到顶部,第二个将用户正在键入的窗口保持在顶部。

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 中检查孩子是否有焦点,如果有,则暂时请求将焦点放在内部框架上。 在内部框架将 ed 移到前面后,然后请求将焦点返回到先前聚焦的组件上。 这将确保生成适当的事件。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM