10

我正在尝试在未装饰的 alwaysOnTop 框架中创建一种工具栏。因此,我希望我的框架位于我的主框架之上,而不是位于其他程序的框架之上。我试过这段代码:

public class Test {
    private static JFrame mainFrame;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mainFrame = new JFrame("test");
                mainFrame.setSize(800,600);
                mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                mainFrame.setVisible(true);

                A a = new A();
            }
        });
    }

    public static class A extends JDialog {

        public A() {
            super(mainFrame);
            setAlwaysOnTop(true);
            setFocusable(false);
            setSize(80,60);
            setVisible(true);
        }
    }
}

但是尽管使用了 JDialog 和精确的所有者,框架仍然在其他应用程序之上(至少对于 Ubuntu。也许结果与其他操作系统不同?)

编辑:好的,我为我的对话框尝试了这段代码:

public static class A extends JDialog {

    public A(String name) {
        super(mainFrame, name);
        setAlwaysOnTop(true);
        setFocusable(false);
        setSize(80, 60);
        setVisible(true);

        mainFrame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowActivated(WindowEvent e) {
                A.this.setAlwaysOnTop(true);
            }

            @Override
            public void windowDeactivated(WindowEvent e) {
                // A.this.setAlwaysOnTop(false);
                A.this.toBack();
            }
        });
    }
}

现在的问题是,当主窗口失去焦点时,对话框会夺回焦点,我不明白为什么。例如,我运行我的应用程序,我尝试切换到 Firefox,Firefox 出现并覆盖了 mainFrame,但 A 对话框获得焦点并停留在屏幕中。现在,如果我再次选择 Firefox,对话框最终会正确消失。你能解释一下为什么对话框得到焦点吗?

谢谢

4

2 回答 2

4

只有当父窗口被激活时,您才应该使您的窗口始终位于顶部。像这样的东西:

public class Test {
    private static JFrame mainFrame;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mainFrame = new JFrame("test");
                mainFrame.setSize(800,600);
                mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                mainFrame.setVisible(true);

                final A a = new A();
                mainFrame.addWindowListener(new WindowAdapter() {
                    /**
                     * {@inheritDoc}
                     */
                    @Override
                    public void windowDeactivated(WindowEvent e) {
                        a.setAlwaysOnTop(false);
                    }

                    /**
                     * {@inheritDoc}
                     */
                    @Override
                    public void windowActivated(WindowEvent e) {
                        a.setAlwaysOnTop(true);
                    }
                });
            }
        });
    }

    public static class A extends JDialog {

        public A() {
            super(mainFrame);
            setAlwaysOnTop(true);
            setFocusable(false);
            setSize(80,60);
            setVisible(true);
        }
    }
}
于 2014-06-23T09:04:51.293 回答
4

好的,我找到了一个解决方案(不知道它是否是解决方案,但它正在工作,所以......)

我发现了 setFocusableWindowState(),它非常适合工具栏。顺便说一句,我不知道我之前的 setFocusable(false) 是否有任何效果。

下一个问题是这段代码的焦点变得非常奇怪:如果我从 MyApp 切换到 Firefox,会发生以下情况:

focus : MyApp -> Firefox
execution of MyDialog.toFront()
focus : Firefox -> MyDialog
MyDialog not focusable !
focus : MyDialog -> MyApp !!!

结果:什么都没有改变!

所以我终于得到了窍门:就在 MyDialog.toFront() 之后,您将焦点交还给前任所有者。我发现这样做没有错误的唯一方法是:mainFrame.toBack()

最终代码:

public class Test {
    private static JFrame mainFrame;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mainFrame = new JFrame("test");
                mainFrame.setSize(800,600);
                mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                mainFrame.setVisible(true);

                A a = new A();
            }
        });
    }

    public static class A extends JDialog {

        public A() {
            super(mainFrame);
            setAlwaysOnTop(true);
            setFocusableWindowState(false);
            setSize(80,60);
            setVisible(true);

            mainFrame.addWindowListener(new WindowAdapter() {
                @Override
                public void windowActivated(WindowEvent e) {
                    A.this.setAlwaysOnTop(true);
                    A.this.toFront();
                }
                @Override
                public void windowDeactivated(WindowEvent e) {
                    A.this.setAlwaysOnTop(false);
                }
            });
        }
    }
}
于 2014-06-24T14:15:43.740 回答