Java如何使JFrame最大化但不可调整大小



最初(请参阅我之前的问题"Java如何使JFrames从最大化窗口开始"),我想创建一个从最大化开始的窗口。这个代码实现了这一点:

public static void main(String[] args)  {
JFrame frame = new JFrame();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}

但是,如果这个窗口被恢复,它实际上就变成了一个不存在的酒吧。为了解决这个问题,我使用setSize()为窗口设置了一个大小。这是有效的,但带来了另一个问题,窗口仍然可以调整大小。

为了解决这个问题,我设置了setResizable(false);到目前为止,这是我的代码:

public static void main(String[] args) {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    JFrame frame = new JFrame("Jedia");
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setSize(screenSize);
    frame.setResizable(false);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

然而,现在窗口以指定的大小(而不是最大化)开始,无法恢复。

所以,我的问题是,我如何才能使窗口开始时最大化,给它一个恢复时的大小,并使其无法调整大小?或者创建一个开始时最大化且无法向下恢复的窗口?

有一个几乎一直有效的简单修复方法:在设置为可见后,使帧不可调整大小。所以只能通过这种方式修改代码:

public static void main(String[] args) {
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    JFrame frame = new JFrame("Jedia");
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setSize(screenSize);
    frame.setVisible(true);    // FIRST visible = true
    frame.setResizable(false); // THEN  resizable = false
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

这样,帧将开始最大化,最大化按钮将变灰,从而阻止用户使用它

它几乎一直工作,因为在Windows7上,至少你可以通过点击标题栏并拖动它来使窗口脱离最大化状态。但它将是你之前设置的大小。问题是,您的用户将无法再次最大化它,而且我还没有找到让监听器将窗口恢复到最大化状态的方法。(编辑:@David Kroukamp在其答案的最后部分显示,使用ComponentListener可以强制达到最大化状态。因此,您不必使用setResizable(false)。这样,Windows 7仍然存在问题,因为无论出于何种原因,拖动操作都不会被此事件捕获,但用户可以使用最大化按钮将其放回原来的位置应该是。)

现在,几乎从来没有理由做这种事情。用户真的不喜欢你阻止他们操作他们的窗口(例如,最大化的窗口不能移动,当你有多个屏幕时,这可能会很烦人)。一个例外是,如果你正在制作一款通常是全屏的游戏。但是你不会想要一个JFrame,因为你不想要所有的装饰,而是想要一个Window。

如果您的问题是默认窗口大小非常小,这是正常的。你必须先在你的框架中放置一些东西(一些控件、按钮、你在应用程序中想要的东西),使用布局(这很重要),然后在框架上调用方法pack()。它会为您的窗口选择一个不错的默认大小。

最后,最后一句话。我已经将示例代码放在main方法中作为快捷方式,但您应该始终使用SwingUtils.invokeLater()在Swing EDT中执行Swing操作。

有时,您必须小心设置JFrame参数的顺序。

此外,您应该在事件调度线程上使用Swing组件。

试试这个,看看它是否有帮助。

public static void main(String[] args) {        
    final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame("Jedia");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(screenSize);
            frame.setResizable(false);
            frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
            frame.setVisible(true);
        }   
    });
}

您运行的环境是什么?我在Win7下的JDK1.6/JDK1.7中尝试过这一点,它按预期工作(窗口开始最大化,最小化到任务栏)。

我有一个可能有效的破解方法。试试这个代码(它对我有效):

public static void main(String[] args) {
    final JFrame frame = new JFrame("Jedia");
    frame.setMinimumSize(new Dimension(600, 400));
    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    frame.setVisible(true);
    frame.addComponentListener(new ComponentListener(){
        @Override
        public void componentHidden(ComponentEvent e) {
            // TODO Auto-generated method stub
        }
        @Override
        public void componentMoved(ComponentEvent e) {
            // TODO Auto-generated method stub
        }
        @Override
        public void componentResized(ComponentEvent e) {
            if (!e.paramString().startsWith("COMPONENT_RESIZED (-8,-8"))
            frame.setSize(new Dimension(600, 400));
        }
        @Override
        public void componentShown(ComponentEvent e) {
            // TODO Auto-generated method stub
        }
    }); 
}

当还原操作发生时,e.paramString()返回一个看起来像"COMPONENT_RESIZED(-8,-8,[screensize])"的字符串。

最新更新