简体   繁体   English

JFrame.setExtendedState(MAXIMIZED_BOTH)是否与未修饰的框架一起使用?

[英]Does JFrame.setExtendedState(MAXIMIZED_BOTH) work with undecorated frames?

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);" 如果你注释掉“frame.setUndecorated(true);” it seems to work correctly. 它似乎工作正常。

The Javadoc seems to imply this should work. Javadoc似乎暗示这应该有效。 Is this a bug in Java? 这是Java中的错误吗? Is it limited to a specific release, or version of Windows? 它仅限于特定版本或Windows版本吗? Is there a workaround? 有解决方法吗?

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 SetWindowPlacement and under some conditions altering MINMAXINFO to get the right window size. 编辑:下载OpenJDK并挖掘本机代码后,我发现Java正在调用win32函数SetWindowPlacement,并在某些条件下更改MINMAXINFO以获得正确的窗口大小。 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. 我发现调用JFrame.setMaximizedBounds()提供了用于改变win32 MINMAXINFO结构的边界。 So by altering my action performed and using the window size suggested by camickr as my MaximizedBounds, I get a bit closer: 因此,通过改变我执行的动作并使用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);

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. 要在最大化框架时手动设置框架的边界。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM