更新JFrame最大化边界,同时保持最大化

时间:2012-02-08 08:29:36

标签: java swing netbeans jframe fullscreen

在JFrame最大化的同时调用setMaximizedBounds()后,是否可以更新JFrame的最大边界(可见)?

// I do not have access to / cannot change the following lines
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 
// frame fills the whole screen at this point

// My code:
frame.setMaximizedBounds(newBounds);

我目前正在执行以下操作来更新JFrame的位置和大小:

frame.setExtendedState(JFrame.NORMAL);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH); 

但是这会导致窗口在视觉上恢复,然后再次最大化,但是具有正确的最大边界。

我尝试了frame.doLayout()frame.getContentPane().doLayout(),但框架没有更新到新边界。

编辑 SSCCE:

改编自here

正如评论中所提到的,JFrame实际上是由NetBeans RCP创建和初始化的,因此我无法覆盖它(如here所述)作为Java bug 4737788的解决方法(我正在尝试创建)解决方法)。解决方法有效,但我想避免(hack)恢复&最大化以更新框架。

import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import sun.java2d.SunGraphicsEnvironment;


public class MaximizedBoundsTest {

    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("Fix Maximized Bounds") {

            @Override
            public void actionPerformed(ActionEvent e) {
                // Workaround for http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4737788
                // to take Windows taskbar into account
                GraphicsConfiguration config = frame.getGraphicsConfiguration();
                Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice());
                frame.setMaximizedBounds(usableBounds);

                // Hack to update frame size & location (is there a better way to do this?)
                frame.setExtendedState(Frame.NORMAL);
                frame.setExtendedState(Frame.MAXIMIZED_BOTH);
            }
        }));
        frame.setExtendedState(Frame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.setVisible(true);
    }
}

1 个答案:

答案 0 :(得分:3)

编辑:哦,没有看到你无法覆盖框架创建并且已经找到了这个解决方案。在这种情况下,我会检查/提交Netbeans的错误,如何覆盖JFrame的创建。

这是我对该bug的解决方法。 Jide OSS中的PortingUtils我认为不使用私有API,但你可以在那里使用你自己的边界计算。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;


public class TestUndecoratedFrame {

    public static void main(String[] args) {
        final JFrame frame = new JFrame() {
            @Override
            public synchronized void setExtendedState(int state) {
                // undecorated covers task bar - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4737788
                if (isUndecorated()
                        && (state & MAXIMIZED_BOTH) == MAXIMIZED_BOTH) {
                    super.setMaximizedBounds(com.jidesoft.utils.PortingUtils.getScreenBounds(this, true));
                }
                super.setExtendedState(state);
            }
        };
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.setUndecorated(true);
        frame.getContentPane().add(new JButton(new AbstractAction("Toggle maximize") {
            @Override
            public void actionPerformed(ActionEvent e) {
                int state = frame.getExtendedState();
                if((state & JFrame.MAXIMIZED_BOTH) == JFrame.MAXIMIZED_BOTH) {
                    frame.setExtendedState(JFrame.NORMAL);
                }
                else {
                    frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
                }
            }
        }), BorderLayout.PAGE_END);
        frame.setVisible(true);
    }
}