java JFrame.setExtendedState(MAXIMIZED_BOTH) 是否适用于未修饰的框架?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7403584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does JFrame.setExtendedState(MAXIMIZED_BOTH) work with undecorated frames?
提问by Bryan Young
The following Swing code doesn't work correctly on my machine or my co-workers machines (all Windows XP & Java 6):
以下 Swing 代码在我的机器或我的同事机器(所有 Windows XP 和 Java 6)上无法正常工作:
public class Test {
public static void main(String[] args) {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setLayout(new FlowLayout());
frame.add(new JButton(new AbstractAction("Maximize") {
@Override
public void actionPerformed(ActionEvent e) {
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH);
}
}));
frame.setUndecorated(true);
frame.setVisible(true);
}
}
It maximizes the window, but does not take into consideration the windows task bar (it fills the screen). If you comment out "frame.setUndecorated(true);" it seems to work correctly.
它最大化窗口,但不考虑窗口任务栏(它填满屏幕)。如果你注释掉“frame.setUndecorated(true);” 它似乎工作正常。
The Javadoc seems to imply this should work. Is this a bug in Java? Is it limited to a specific release, or version of Windows? Is there a workaround?
Javadoc 似乎暗示这应该有效。这是Java中的错误吗?它是否仅限于特定版本或 Windows 版本?有解决方法吗?
I've seen a few workarounds, but they seem incomplete. I can't be the first person to code my own frame decorations in Java.
我已经看到了一些解决方法,但它们似乎不完整。我不可能是第一个用 Java 编写我自己的框架装饰的人。
EDIT:After downloading the OpenJDK and digging through the native code, I found that Java is calling the win32 function SetWindowPlacementand under some conditions altering MINMAXINFOto get the right window size. I think what I was seeing was the default windows behavior for a window with no title or border (although I can't find that documented anywhere). I've found that calling JFrame.setMaximizedBounds() provides the bounds used to alter the win32 MINMAXINFO structure. So by altering my action performed and using the window size suggested by camickr as my MaximizedBounds, I get a bit closer:
编辑:下载 OpenJDK 并挖掘本机代码后,我发现 Java 正在调用 win32 函数SetWindowPlacement并在某些情况下更改MINMAXINFO以获得正确的窗口大小。我认为我看到的是没有标题或边框的窗口的默认窗口行为(尽管我无法在任何地方找到记录)。我发现调用 JFrame.setMaximizedBounds() 提供了用于更改 win32 MINMAXINFO 结构的边界。因此,通过更改我执行的操作并使用 camickr 建议的窗口大小作为我的 MaximizedBounds,我更接近了:
GraphicsConfiguration graphicsConfiguration = frame.getGraphicsConfiguration();
frame.setMaximizedBounds(graphicsConfiguration.getBounds());
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH);
Now the maximize window no longer hides the menubar. But.. now I have another problem. I can't maximize from a secondary monitor. The frame just disappears.
现在最大化窗口不再隐藏菜单栏。但是......现在我有另一个问题。我无法从辅助显示器最大化。框架就消失了。
I'm adding some win32 tags in hopes of getting a C++ programmer who recognizes this problem.
我正在添加一些 win32 标签,希望能够让 C++ 程序员认识到这个问题。
SOLUTION:I apparently can't answer my own question yet, so I'll just put my solution here. I had to use a Sun class, and I haven't tested it on any platforms other than Windows, but so far this seems to be working well with multiple monitors, and multiple taskbar configurations:
解决方案:我显然还不能回答我自己的问题,所以我就把我的解决方案放在这里。我不得不使用 Sun 类,而且我还没有在 Windows 以外的任何平台上测试过它,但到目前为止,这似乎适用于多个显示器和多个任务栏配置:
GraphicsConfiguration config = frame.getGraphicsConfiguration();
Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice());
frame.setMaximizedBounds(new Rectangle(0, 0, usableBounds.width, usableBounds.height));
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH);
回答by camickr
Interesting. When I try it it seems to happen in two steps. First expands to fill the space above the task bar, then a split second later it covers the task bar. I have no idea why.
有趣的。当我尝试它时,它似乎分两步发生。首先扩展以填充任务栏上方的空间,然后一瞬间覆盖任务栏。我不知道为什么。
Anyway for a workaround you can use:
无论如何,您可以使用以下解决方法:
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
Rectangle bounds = env.getMaximumWindowBounds();
System.out.println("Screen Bounds: " + bounds );
to manually set the bounds of your frame when you want to maximize it.
当您想要最大化框架时,手动设置框架的边界。