在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:
改编自此处。
正如评论中提到的,JFrame实际上是由NetBeans RCP创建和初始化的,所以我不能覆盖它(正如这里提出的那样)作为Java bug 4737788的解决方法(我正在尝试为其创建一个解决方法)。变通办法是可行的,但我想避免(黑客)恢复&最大化以更新帧。
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);
}
}
编辑:哦,没有看到你不能覆盖框架创建,并且已经找到了这个解决方案。在这种情况下,我会用Netbeans检查/归档一个错误,如何覆盖JFrame的创建。
以下是我针对该错误的解决方法。在Jide OSS中移植Utils,我相信不使用私有的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);
}
}