带有最大化按钮的Java模态窗口

10

如何创建一个既有模态又有最大化按钮的窗口?
那么是否可以创建一个带有最大化按钮的模态 JFrame,或者创建一个 JDialog 呢?

3个回答

12

在大多数外观主题中,模态窗口(例如JDialog)没有最大化按钮,因为它们根本不应该被最大化(或最小化)。

可能会有一些技巧可以添加一个最大化按钮,但这与JDialog的设计意图完全违背。 如果你需要一个最大化按钮,最好的解决方案是使用JWindow或者JFrame而不是JDialog。这些窗口支持最大化和最小化。


警告:无论如何都不应该这样做。

JDialog中实现这个技巧的方法:

setUndecorated(true);
getRootPane().setWindowDecorationStyle(JRootPane.FRAME);

那么没有任何“合法”的方法可以做到这一点吗?:S - user
@János Harsányi,不,正如我所说,它们不应该有最大化按钮。 - Colin Hebert
就像我之前所说的,我不建议在任何情况下使用它。 - Colin Hebert
3
使用它的危险性是什么? - arxakoulini

2

解决方案1:在Windows上测试通过

我使用了JFrame来创建模态窗口。

JFrame mainWindow = new JFrame;
mainWindow.setVisible(true);
JFrame modalWindow = new JFrame();
// The next two sentences gives modalWindow modal beahaviour
mainWindow.setEnabled(false);
mainWindow.setFocusable(false);
modalWindow.setVisible(true);
解决方案二:适用于Ubuntu

我添加了一个WindowFocusListener监听器。

addWindowFocusListener(new java.awt.event.WindowFocusListener() {
    public void windowGainedFocus(java.awt.event.WindowEvent evt) {}
    public void windowLostFocus(java.awt.event.WindowEvent evt) {
        formWindowLostFocus(evt);}

private void formWindowLostFocus(java.awt.event.WindowEvent evt) {
    this.requestFocus();
    this.toFront();}

3
方案2是“超级模态”,无论是Java、本地还是其他类型的窗口都不能被选中。请小心! - sillo01

1

这里是一个备选/稍微详细的答案。

尝试你是否错过了最大化按钮? (以前在这里)。这是一个由Santhosh Kumar Tekturi从现已停止运营的JRoller网站归档的博客文章和代码的Github存储库。

它是一个完整的实用类,使一个Frame模仿一个Dialog,类似于其他答案。它涉及向Frame添加WindowListener,以使该Frame保持在其所有者的顶部并使其所有者Frame被禁用(警告:在windowClosed方法中,它应该是frame.removeWindowListener(this);),以及向所有者添加WindowListener,以使该Frame保持在其上方并删除侦听器。它还使用自己的EventQueue来处理事件。请注意,这是一篇旧帖子,因此如代码中所述,可能有更新的API可以更好地处理此代码。

这里是核心函数。请查看链接获取其余部分。注意:存储库中的代码与文章中的代码不同;我认为存储库更加完善。

// show the given frame as modal to the specified owner.
// NOTE: this method returns only after the modal frame is closed.
public static void showAsModal(final Frame frame, final Frame owner){
    frame.addWindowListener(new WindowAdapter(){
        public void windowOpened(WindowEvent e){
            owner.setEnabled(false);
        }

        public void windowClosing(WindowEvent e) {
            owner.setEnabled(true);
        }

        public void windowClosed(WindowEvent e){
            frame.removeWindowListener(this); // originally called on owner
        }
    });

    owner.addWindowListener(new WindowAdapter(){
        public void windowActivated(WindowEvent e){
            if(frame.isShowing()){
                frame.setExtendedState(JFrame.NORMAL);
                frame.toFront();
            }else
                owner.removeWindowListener(this);
        }
    });

    owner.toFront();
    frame.setVisible(true);
    try{
        new EventPump(frame).start();
    } catch(Throwable throwable){
        throw new RuntimeException(throwable);
    }
}

@KarlRichter 感谢您告知,我已更新链接并添加了更多详细信息,包括最相关的代码。 - Pixel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接