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

时间:2013-02-14 19:19:57

标签: java swing jframe screen dimension

最初(参见我之前的问题“Java how to make JFrames start off as a maximised window”)我想创建一个最大化的窗口。 此代码实现了这一点:

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);

}

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

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

4 个答案:

答案 0 :(得分:3)

有一个简单的修复程序几乎一直有效:在设置可见之后,使框架无法调整。所以只能这样修改你的代码:

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);

}

这样,框架将开始最大化,并且最大化按钮将变为灰色,从而阻止用户使用它。 (我真的不知道为什么你必须这样做。我认为最大化的状态实际上只有在窗口变得可见时才会应用,如果你之前让它不可调整,它将不适用。)

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

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

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

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

答案 1 :(得分:1)

有时,您必须小心设置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);
        }   
    });
}

答案 2 :(得分:0)

你在运行什么环境?我在Win7下用JDK1.6 / JDK1.7尝试了这个,它按预期工作(窗口开始最大化,最小化到任务栏)。

答案 3 :(得分:0)

我有一种可能有用的黑客攻击。 试试这个代码(它对我有用):

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])”的字符串。