新 window 出现在 parent 和 child JFrame/JDialog 之间

New window appears sandwiched between parent and child JFrame/JDialog

来自其他进程的新 windows 在焦点 JDialog child 后面但在 JDialog parent 前面打开。我希望新的 windows 出现在 child 的前面。 None 其中 windows 被声明为始终在最前面。

图片

实际订单

JDialog (App 1 - always on top)
JFrame (App 2 non modal dialog child of app 2 main)
JDialog (App 3) <=== new window should appear on top of app 2
JFrame (App 2 - main window)

预期顺序

JDialog (App 1 - always on top)
JDialog (App 3) <=== new window should appear on top of app 2
JFrame (App 2 non modal dialog child of app 2 main)
JFrame (App 2 - main window)

此问题仅在

时发生

如果在下面的示例中 window 稍微向右打开(更改为 newWindow.setBounds(**370**, 20, 0, 200)),这样它就不会出现在总在最前面的 window 后面在 child.

前面

明确地说,这个问题发生在三个独立的应用程序之间,但是为了简单起见,我在下面将其重新创建为单个 Java 应用程序。

public class Combined {
    public static void main(String[] args) throws Exception {

        JFrame aot = new JFrame("App 1 - always on top");
        aot.setAlwaysOnTop(true);
        aot.setBounds(50, 50, 300, 40);
        aot.setVisible(true);

        JFrame frame = new JFrame("App 2 - main window");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setBounds(100, 100, 300, 200);
        frame.setVisible(true);

        JDialog child = new JDialog(frame, "App 2 - non-modal child dialog (child)");
        child.setBounds(150, 150, 300, 200);
        child.setVisible(true);

        Thread.sleep(1000);
        JFrame newWindow = new JFrame("App 3");
        newWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        newWindow.setBounds(200, 20, 300, 200);
        // newWindow.setBounds(370, 20, 300, 200);

        newWindow.setVisible(true);
    }
}

是否有任何选项可以应用于 JDialog child 以允许 Windows 出现在其上方。背景是我正在开发"app 2"应用程序,所有其他部分和Redhat Linux安装都由其他third-parties管理,因此不能轻易更改。

尝试使用 strict/smart window 管理器选项,但行为没有区别

gconftool-2 --set /schemas/apps/metacity/general/focus_new_windows --type string smart
gconftool-2 --set /schemas/apps/metacity/general/focus_new_windows --type string strict

Hacky 解决方案

代码

newWindow.setVisible(true);
newWindow.setVisible(false);
newWindow.setVisible(true);

总而言之,这个 Linux windows 管理特定问题没有很好的解决方案。所有可以做的就是从您的应用程序中消除永远在线 windows。无论如何,这是最佳实践,但在处理遗留代码库时很困难。

绝望的唯一其他解决方案是执行 setVisible() 舞蹈。

newWindow.setVisible(true);
newWindow.setVisible(false);
newWindow.setVisible(true);