这是我的代码:
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test{
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run() {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame();
JPanel jp = new JPanel();
jp.setMinimumSize(new Dimension(200, 200));
jp.setPreferredSize(new Dimension(200, 200));
//frame.getContentPane().setMinimumSize(new Dimension(200, 200));
//frame.getContentPane().setPreferredSize(new Dimension(200, 200));
frame.getContentPane().add(jp);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
});
}
}
它的行为与我想要的完全一致。用户可以调整JFrame
的大小,但它总是足够大,可容纳200px x 200px JPanel
。但是当我删除时:
JFrame.setDefaultLookAndFeelDecorated(true);
用户可以将JFrame
调整为任意大小。
为什么默认外观装饰会影响调整大小?如何在没有setDefaultLookAndFeelDecorated(true)
的情况下让它工作?我知道我可以手动设置最小尺寸的框架(JFrame#setMinimumSize(new Dimension dim)
),如果没有更智能的解决方案,我会的。
我在Windows 7上使用jdk 1.7。
答案 0 :(得分:4)
This曾经是一个错误,该页面说的是:
setSize()
并检查新尺寸是否小于所需paint(Graphics g)
内JFrame
检查高度和宽度,并“重新创建”框架为新的最小尺寸setMinimumSize(...)
的调用,这是必需的,因为JFrame不强制执行最小尺寸
以下是显示人员代码的片段:
import java.awt.Dimension;
import javax.swing.*;
public class JavaApplication118 {
private final Dimension m_dim = new Dimension(200, 150);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new JavaApplication118().createAndShowUI();
}
});
}
private void createAndShowUI() {
// JFrame.setDefaultLookAndFeelDecorated(true);
final JFrame frame = new JFrame("Test") {
@Override
public Dimension getMinimumSize() {
return m_dim;
}
};
frame.setMinimumSize(m_dim);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initComponents(frame);
// frame.setResizable(false);
frame.pack();
frame.setVisible(true);
}
private void initComponents(JFrame frame) {
JPanel jp = new JPanel();
jp.setMinimumSize(new Dimension(200, 200));
jp.setPreferredSize(new Dimension(400, 400));//for testing
frame.getContentPane().add(jp);
}
}
修改强>
该代码段覆盖getMinimumSize()
虽然在调用setMinimumSize(..)
后这似乎是多余的,但我保留了它,因为我找到了该代码段(我确实删除了getPreferredSize()
方法JFrame
1}}其中包含的代码段。)
答案 1 :(得分:2)
为什么默认外观装饰会影响调整大小?
因为在拖动时窗口大小完全由LAF完全控制:由(f.i.)MetalRootPaneUI安装的mouseHandler不会在LayoutManager返回的min下面调整窗口大小。如果不设置框架的minimumSize,您仍然可以以编程方式减小其大小。
唯一的方法(不幸的是)强制执行窗口的最小尺寸总是是手动设置它。不幸的是,因为这意味着要跟踪最小值的动态变化,并在适当的时候进行更新。
要播放的片段(取消/注释defaultDecoration和帧最小设置)
JFrame.setDefaultLookAndFeelDecorated(true);
JPanel panel = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
Dimension m = getMinimumSize();
// visualize the min
g.drawRect(0, 0, m.width - 1, m.height -1);
}
};
// BEWARE: for demonstration only, NEVER do in production code
panel.setMinimumSize(new Dimension(400, 400));
panel.setPreferredSize(panel.getMinimumSize());
final JXFrame frame = new JXFrame("", true);
Action action = new AbstractAction("resize") {
@Override
public void actionPerformed(ActionEvent e) {
frame.setSize(300, 300);
LOG.info("succeeded? " + frame.getSize());
}
};
panel.add(new JButton(action));
frame.add(panel);
frame.pack();
// set minimum is required to enforce the minimum
frame.setMinimumSize(frame.getMinimumSize());
<强>更新强>
查看Window源代码,结果表明你可以通过覆盖isMinimumSizeSet并在无条件下返回true来获得最小大小的自动魔法动态尊重:
final JXFrame frame = new JXFrame("", true) {
@Override
public boolean isMinimumSizeSet() {
return true;
}
};
...
// no longer needed
// frame.setMinimumSize(frame.getMinimumSize());
没有测试副作用,但