什么覆盖了我的首选尺寸? (JPanel的)

时间:2013-01-04 04:01:20

标签: java swing jpanel layout-manager jcomponent

所以我对GUI很陌生,并且遇到了这样的问题:无论我将首选大小设置为(通过setPreferredSize(new Dimension(width, height))),它都会在宽度和高度上添加10。我在想,为什么会这样?是的我明白这是“首选尺寸”,但肯定有办法防止这种情况发生。我可以通过在传递给方法之前从宽度和高度减去10来解决它,但我想知道发生了什么。

我的(相关)代码:

主要方法:

 public static void main(String[] args)
 {
    final App app = new App(500, 500);

    JFrame frame = new JFrame("Block Stacker 3000");
    frame.getContentPane().add(app);
    frame.pack();
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    System.out.println(app.getSize());
    app.start();
 }

App构造函数(扩展JPanel):

  public App(int width, int height)
  { 
     this.width = width;
     this.height = height;

     System.out.println(width + " " + height);

     setPreferredSize(new Dimension(width , height));

     setBackground(Color.CYAN);
  }

运行时,输出以下内容:

500 500
java.awt.Dimension[width=510,height=510]

另外,我尝试过使用setMinimumSize()setMaximumSize(),但两者都没有真正影响。

3 个答案:

答案 0 :(得分:3)

JPanel的大小将由处理其容器中组件的布局管理器决定。 JFrame有一个默认的布局管理器,所以即使你没有设置它也有一个。一些布局管理人员注意首选尺寸,有些则没有,有些人更注重最小/最大尺寸。

您可以设置“空布局管理器”,也称为“绝对定位”,并自行控制所有尺寸,但我认为您不会尝试这样做(因为您设置的是“首选”尺寸)。设计UI所需要做的是弄清楚你希望事物具有的相对大小和位置,以及当窗口大小发生变化时你想要发生什么。确定哪些布局管理器进入哪个容器面板以及包含它们的容器面板等等。

我不会消除frame.pack();它本质上告诉布局管理器做它的东西,你通常希望布局管理器能够按照你想要的方式设置它们...... < / p>

答案 1 :(得分:2)

我复制/粘贴了您的代码并获得了以下输出:

500 500
java.awt.Dimension[width=510,height=530]

但是,我找到了框架的截图:

enter image description here

如果您下载图片并检查文件属性,您将看到它是502像素宽(由于窗口1像素细边框)和531像素高(由于窗口标题栏31像素高度),检查在gimp的图像中,我发现青色区域实际上是 500x500 像素宽。

更新:将setResizable(false)句子移至frame.setVisible(true);之后的行:

    JFrame frame = new JFrame("Block Stacker 3000");
    frame.getContentPane().add(app);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
    frame.setResizable(false);

之后,它会打印出来:

500 500
java.awt.Dimension[width=500,height=500]

答案 2 :(得分:0)

在调用pack()之后,您必须致电setResizable(false) ,因为当窗口可调整大小时,布局管理器将为(潜在)滚动条留出10px的余量。

public static void main(String[] args) {
    final App app = new App(500, 500);

    JFrame frame = new JFrame("Block Stacker 3000");
    frame.getContentPane().add(app);
    frame.setResizable(false);
    frame.pack();

    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);

    System.out.println(app.getSize());
    app.start();
 }