最初(请参阅我之前的问题"Java如何使JFrames从最大化窗口开始"),我想创建一个从最大化开始的窗口。这个代码实现了这一点:
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
但是,如果这个窗口被恢复,它实际上就变成了一个不存在的酒吧。为了解决这个问题,我使用setSize()为窗口设置了一个大小。这是有效的,但带来了另一个问题,窗口仍然可以调整大小。
为了解决这个问题,我设置了setResizable(false);到目前为止,这是我的代码:
public static void main(String[] args) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
JFrame frame = new JFrame("Jedia");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setSize(screenSize);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
然而,现在窗口以指定的大小(而不是最大化)开始,无法恢复。
所以,我的问题是,我如何才能使窗口开始时最大化,给它一个恢复时的大小,并使其无法调整大小?或者创建一个开始时最大化且无法向下恢复的窗口?
有一个几乎一直有效的简单修复方法:在设置为可见后,使帧不可调整大小。所以只能通过这种方式修改代码:
public static void main(String[] args) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
JFrame frame = new JFrame("Jedia");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setSize(screenSize);
frame.setVisible(true); // FIRST visible = true
frame.setResizable(false); // THEN resizable = false
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
这样,帧将开始最大化,最大化按钮将变灰,从而阻止用户使用它
它几乎一直工作,因为在Windows7上,至少你可以通过点击标题栏并拖动它来使窗口脱离最大化状态。但它将是你之前设置的大小。问题是,您的用户将无法再次最大化它,而且我还没有找到让监听器将窗口恢复到最大化状态的方法。(编辑:@David Kroukamp在其答案的最后部分显示,使用ComponentListener可以强制达到最大化状态。因此,您不必使用setResizable(false)
。这样,Windows 7仍然存在问题,因为无论出于何种原因,拖动操作都不会被此事件捕获,但用户可以使用最大化按钮将其放回原来的位置应该是。)
现在,几乎从来没有理由做这种事情。用户真的不喜欢你阻止他们操作他们的窗口(例如,最大化的窗口不能移动,当你有多个屏幕时,这可能会很烦人)。一个例外是,如果你正在制作一款通常是全屏的游戏。但是你不会想要一个JFrame,因为你不想要所有的装饰,而是想要一个Window。
如果您的问题是默认窗口大小非常小,这是正常的。你必须先在你的框架中放置一些东西(一些控件、按钮、你在应用程序中想要的东西),使用布局(这很重要),然后在框架上调用方法pack()
。它会为您的窗口选择一个不错的默认大小。
最后,最后一句话。我已经将示例代码放在main
方法中作为快捷方式,但您应该始终使用SwingUtils.invokeLater()
在Swing EDT中执行Swing操作。
有时,您必须小心设置JFrame参数的顺序。
此外,您应该在事件调度线程上使用Swing组件。
试试这个,看看它是否有帮助。
public static void main(String[] args) {
final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Jedia");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(screenSize);
frame.setResizable(false);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
}
});
}
您运行的环境是什么?我在Win7下的JDK1.6/JDK1.7中尝试过这一点,它按预期工作(窗口开始最大化,最小化到任务栏)。
我有一个可能有效的破解方法。试试这个代码(它对我有效):
public static void main(String[] args) {
final JFrame frame = new JFrame("Jedia");
frame.setMinimumSize(new Dimension(600, 400));
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
frame.addComponentListener(new ComponentListener(){
@Override
public void componentHidden(ComponentEvent e) {
// TODO Auto-generated method stub
}
@Override
public void componentMoved(ComponentEvent e) {
// TODO Auto-generated method stub
}
@Override
public void componentResized(ComponentEvent e) {
if (!e.paramString().startsWith("COMPONENT_RESIZED (-8,-8"))
frame.setSize(new Dimension(600, 400));
}
@Override
public void componentShown(ComponentEvent e) {
// TODO Auto-generated method stub
}
});
}
当还原操作发生时,e.paramString()
返回一个看起来像"COMPONENT_RESIZED(-8,-8,[screensize])"的字符串。