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

2022-01-24 00:00:00 screen dimension java swing jframe

最初(见我之前的问题Java 如何使 JFrames 以最大化窗口开始") 我想创建一个以最大化开始的窗口.这段代码完成了这个:

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

然而,如果这个窗口被还原下来,它就变成了一个几乎不存在的栏.为了解决这个问题,我使用 setSize() 设置了窗口的大小.这可行,但存在另一个问题,窗口仍然可以调整大小.

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

public static void main(String[] args) {尺寸 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) {尺寸 screenSize = Toolkit.getDefaultToolkit().getScreenSize();JFrame frame = new JFrame("Jedia");frame.setExtendedState(JFrame.MAXIMIZED_BOTH);frame.setSize(screenSize);frame.setVisible(true);//第一个可见 = trueframe.setResizable(false);//那么可调整大小 = falseframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}

这样,框架将开始最大化,最大化按钮将显示为灰色,阻止用户使用它.(我真的不知道你为什么要这样做.我想最大化状态只有在窗口变得可见时才真正应用,如果你之前让它不可调整大小,它就不会应用.)

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

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

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

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

Originally (See my previous question "Java how to make JFrames start off as a maximised window") I wanted to make a window which starts out maximised. This code accomplishes this:

public static void main(String[] args)  {

JFrame frame = new JFrame();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);

}

However, if this window is restored down it becomes a practically non-existent bar. To solve this I set a size for the window using setSize(). This works but presents another problem, the window can still be resized.

To solve this problem I set setResizable(false); and this is my code so far:

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

}

However, now the window starts out at its specified size (rather than maximised) and cannot be restored up.

So, my question is, how can I either make the window start out maximised, give it a size for when it is restored down and make resizing it impossible? Or make a window that starts out maximised and cannot be restored down?

解决方案

There is a simple fix that works almost all the time: make your frame not resizable after having set visible. So only modifies your code this way:

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

}

This way, the frame will start maximized and the maximize button will be greyed out, preventing user to use it. (I don't really know why you have to do this. I suppose the maximized state is really applied only when the window becomes visible, and if you make it unresizable before, it will not apply.)

It works almost all the time because on Windows 7 at least you can make the window goes out of the maximized state by clicking the title bar and dragging it. But it will be at the size you have set it earlier. Problem is that your user will not be able to maximize it again, and I haven't found the way with listeners to make the window back to maximized state. ( Edit: @David Kroukamp shows in the last part of his answer that it is possible to force the maximized state by using a ComponentListener. Therefore you don't have to use setResizable(false) This way you still have a problem with Windows 7 because the dragging action is not catched by this event for whatever reason but users will be able to use the maximized button to put it back where it should be.)

Now, there is almost never a reason to do this kind of things. Users don't really like when you prevent them to manipulate their windows (maximized windows can not be moved, for example, and that can be annoying when you have multiple screens). An exception is if you are making a game, which is typically full-screen. But then you wouldn't want a JFrame because you don't want all the decoration, but a Window.

If your problem is that the default window size is very small, it's normal. You have to put something in your frame first (some controls, buttons, what you want in your application), using layouts (that's important) then call the method pack() on your frame. It will chose a nice default size for your window.

Finally, a last word. I've put my example code in a main method as a shortcut, but you should always do Swing stuff in the Swing EDT by using SwingUtils.invokeLater().

相关文章