JFrame.setExtendedState(MAXIMIZED_BOTH)是否与未修饰的帧一起使用? [英] Does JFrame.setExtendedState(MAXIMIZED_BOTH) work with undecorated frames?

查看:417
本文介绍了JFrame.setExtendedState(MAXIMIZED_BOTH)是否与未修饰的帧一起使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下Swing代码在我的机器或同事机器(所有Windows XP和Java 6)上无法正常工作:

The following Swing code doesn't work correctly on my machine or my co-workers machines (all 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);
    }
}

它最大化窗口,但没有考虑到Windows任务栏(它填满了屏幕)。如果你注释掉frame.setUndecorated(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.

Javadoc似乎暗示这应该有效。这是Java中的错误吗?它仅限于特定版本或Windows版本吗?有解决方法吗?

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?

我见过几个解决方法,但它们似乎不完整。我不能成为第一个用Java编写我自己的框架装饰的人。

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.

编辑:下载OpenJDK并挖掘本机代码,我发现Java正在调用win32函数 SetWindowPlacement 并在某些条件下改变 MINMAXINFO 以获得正确的窗口大小。我认为我看到的是没有标题或边框的窗口的默认窗口行为(虽然我无法在任何地方找到记录)。我发现调用JFrame.setMaximizedBounds()提供了用于改变win32 MINMAXINFO结构的边界。因此,通过改变我执行的操作并使用camickr建议的窗口大小作为我的MaximizedBounds,我会更接近:

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. 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:

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.

我正在添加一些win32标签,希望得到一位认识到这个问题的C ++程序员。

I'm adding some win32 tags in hopes of getting a C++ programmer who recognizes this problem.

解决方案:我显然无法回答我自己的问题,所以我只想把我的解决方案放在这里。我不得不使用Sun类,我没有在Windows以外的任何平台上测试它,但到目前为止,这似乎适用于多个显示器和多个任务栏配置:

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:

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.

这篇关于JFrame.setExtendedState(MAXIMIZED_BOTH)是否与未修饰的帧一起使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆