【问题标题】:How to make a JDialog not always on top of parent如何使 JDialog 不总是在父级之上
【发布时间】:2014-03-07 20:10:14
【问题描述】:

我有一个生成两个 JDialog 的 JFrame。三个窗口中的每一个都需要可聚焦(并且是我目前编写的方式),但是 JFrame 不会出现在对话框的顶部。当您单击任一对话框时,它们会彼此重叠弹出(如预期的那样),但 JFrame 只是拒绝出现在前面。

我需要它们保留 JDialogs(而不是 JFrames 本身),因为大多数当前行为都是可取的(即,当另一个窗口/应用程序阻塞任何或所有窗口时,如果您选择任何一个窗口,它们都会出现到前面(而三个 JFrame 会导致只有选定的一个出现)。

我的 JDialogs 构造函数是这样的:

SubDialog(JFrame parent /*, a handful, ofOther arguments */){
    super(parent, ModalityType.MODELESS); //not even the modeless helped
    setAlwaysOnTop(false); //not even the not always on top helped
    setUndecorated(true); //maybe this has something to do with it (unlikely, just fyi)?

    //some simple variable assignments

}

我什至尝试在我的 JFrame 中添加 setAlwaysOnTop(true)。没有骰子。我越来越绝望,甚至尝试了以下数字之一:

MyJFrame(String title){
    super(title);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    addWindowFocusListener(new WindowAdapter(){
        public void windowGainedFocus(WindowEvent e){
            final Window w = e.getWindow();

            //PLEASE come to the front
            w.toFront();

            //even MOAR desperation
            SwingUtilities.invokeLater(new Runnable(){
                public void run(){
                    w.toFront(); //STILL no dice.
                }
            });
        }
    });
}

想法?我什么都没有。

【问题讨论】:

  • 我认为您的意思是“ModalityType.MODELESS”,而不是“ModilityType.MODELESS”?另外,尝试调用 setModal(false);
  • 糟糕。好眼力。拼写固定。设置 ModalityType.MODELESS 与调用 setModal(false) 相同。实际上,调用 setModal(false) 实际上会将模态类型更改为 MODELESS。反正我还是试过了,以防万一。没有骰子。

标签: java swing jdialog modality


【解决方案1】:

如何让 JDialog 不总是在父级之上

如本问答所述:setModal issue with 2 Jdialogs within a Jframe:

此行为取决于本机窗口系统如何处理焦点窗口和活动窗口。话虽如此,如果您调用例如toFront(),它将尝试将窗口放在堆栈的顶部,但是某些平台不允许拥有其他窗口的窗口出现在其子窗口的顶部。当您调用 toBack() 方法时也会发生同样的情况。有关详细信息,请参阅 javadocs。

例如,在 Windows 7 上,父对话框变为焦点,但其子对话框仍显示(未聚焦)在顶部。如上所述,由窗口系统决定如何处理此问题。

【讨论】:

  • 换句话说,“它不能[干净地]完成”。我害怕那个。
  • @captainroxors 不幸的是你是对的。只是一种解决方法是创建 没有 父级的 MODELESS 对话框。然后你可以把框架放在前面。
【解决方案2】:

这很容易实现,见以下代码:

    JFrame frame = new JFrame();
    frame.setBounds(0,0,400,200);
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

// Special attention to this line, do not use same JFrame, create a dummy JFrame
// If you want to save memory you can also use new JDialog((JFrame)null)
    JDialog jd = new JDialog(new JFrame());
    jd.setModalityType(Dialog.ModalityType.MODELESS);
    jd.setBounds(0,0,100, 100);
    jd.setVisible(true);

【讨论】:

  • 嗯,是的,这使得对话框和框架可以相互叠加,但现在它们不再相关。创建该虚拟 JFrame 相当于不将父框架传递给构造函数。这破坏了我提到的原始行为“即,当另一个窗口/应用程序阻塞任何或所有窗口时,如果您选择任何 [我的应用程序] 窗口,它们都会出现在前面”(强调添加)。那时我还不如拥有三个独立的 JFrame。
  • 让我重新定义你的问题。因此,如果 A 是 JFrame,B 和 C 是 JDialog 与父 A,而 D 是另一个 JFrame。您想要的是:1)如果在 B 和 C 上方时选择了 A,那么 B 和 C 必须在下方,2)如果 D 处于活动状态并且单击 A,则 B 和 C 必须弹出?我想知道你为什么想要这样的行为?
  • 而不是想到 JFrame D(我假设您的意思是驻留在同一个 JVM 中),我的意思是运行一个完全不同的应用程序,例如Photoshop、Firefox、Windows Explorer(甚至与我的 Java 应用程序无关)。所以是的,我绝对希望 B & C 在选择 A 时出现(即整个应用程序出现在所有其他应用程序之前),并且由于选择了 A,我希望它会出现在 B & C 之上。这有意义吗?很抱歉没有清楚地表达我的意图。
猜你喜欢
  • 2012-04-19
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 2011-08-10
  • 1970-01-01
相关资源
最近更新 更多