3

我正在创建一个带有 JPanel 的表单,用于一些图形和一些用于控制事物的按钮。出于某种原因,我必须将 JPanel 指定为比我想要放入其中的实际图形小 10 px 和高 30 px。是什么导致了这个问题?

这是代码:

public class Window {
 public Sheepness sheepness;

 public ButtonPanel buttonPanel;
 public PaintPanel paintPanel;
 public JFrame frame;

 public Window(Sheepness sheepness) {
  this.sheepness = sheepness;

  frame = new JFrame("Sheepness simulation");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  //frame.setSize(width, height);

  BorderLayout frameLayout = new BorderLayout();
  JPanel background = new JPanel(frameLayout);
  background.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

  buttonPanel = new ButtonPanel(this);
  background.add(BorderLayout.SOUTH, buttonPanel.buttonBox);

  paintPanel = new PaintPanel(this);
  paintPanel.setPreferredSize(new Dimension(320, 240));
  background.add(BorderLayout.CENTER, paintPanel);

  frame.getContentPane().add(background);
  frame.pack();
  frame.setResizable(false);
  frame.setVisible(true);
 }
}

public class PaintPanel extends JPanel {
 public Window window;

 public PaintPanel(Window window) {
  this.window = window;
 }

 @Override
 public void paintComponent(Graphics g) {
  g.setColor(Color.blue);
  g.fillRect(0, 0, 320, 240);
 }
}

首选大小为 320 x 240 的屏幕截图:

找不到源图片 http://www.cmbi.ru.nl/~estens/Sheepness/Sheepness_simulation_border.png

您可以看到 320 x 240 fillRect 并没有完全填满 JPanel,还保留了 10 px 宽和 30 px 高的边框。

首选大小为 310 x 210 的屏幕截图:

找不到源图片 http://www.cmbi.ru.nl/~estens/Sheepness/Sheepness_simulation_noBorder.png

现在它完全适合 320 x 240 fillRect!

有任何想法吗?

4

4 回答 4

4

不同的布局管理器使用不同的规则来计算实际托管控件的大小,即您不能指望面板只有在您调用“setPreferredSize()”时才具有特定的大小。

请随意查看所有目标布局管理器的 javadoc,以获取有关每种特定情况下使用的算法的更多详细信息。

另请注意,您可以避免使用布局管理器并通过“setBounds()”方法绝对定义所有尺寸。

于 2009-10-20T11:36:08.523 回答
2

信不信由你,但尝试颠倒 pack() 和 setResizeable() 的顺序

    ...
    frame.setResizable(false);
    frame.pack();  // should be called after any changes
    frame.setVisible(true);

编辑:使用此检查

    frame.pack();
    frame.setResizable(false);
    System.out.println(paintPanel.getSize());
    frame.setVisible(true);
    System.out.println(paintPanel.getSize());

    frame.setResizable(false);
    frame.pack();
    System.out.println(paintPanel.getSize());
    frame.setVisible(true);
    System.out.println(paintPanel.getSize());

但如果大小不重要,您可以使用填充实际区域

@Override
public void paintComponent(Graphics g) {
    g.setColor(Color.blue);
    g.fillRect(0, 0, getWidth(), getHeight());
}

[]]

于 2009-10-20T13:36:56.323 回答
1

这是一个基于您的代码的独立测试用例:

导入 java.awt.*;
导入 javax.swing.*;

公共类测试{

 公共油漆面板油漆面板;
 公共 JFrame 框架;

 公共测试(){
  frame = new JFrame("绵羊度模拟");
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  //frame.setSize(宽度,高度);

  BorderLayout frameLayout = new BorderLayout();
  JPanel 背景 = 新 JPanel(frameLayout);
  background.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

  油漆面板 = 新油漆面板(这个);
  paintPanel.setPreferredSize(new Dimension(320, 240));
  背景.add(BorderLayout.CENTER,paintPanel);

  frame.getContentPane().add(背景);
  框架.pack();
  frame.setResizable(false);
  frame.setVisible(true);
 }

  公共静态类 PaintPanel 扩展 JPanel {
    公共测试窗口;

   公共 PaintPanel(测试窗口){
    this.window = 窗口;
   }

   @覆盖
   公共无效paintComponent(图形g){
    g.setColor(Color.blue);
    g.fillRect(0, 0, 320, 240);
   }
  }

  公共静态无效主要(字符串[]参数){
    SwingUtilities.invokeLater(new Runnable() {
      公共无效运行(){
        新测试();
      }
    });
  }
}

当我在 Linux 上的 IcedTea JVM 上运行它时,我看到了这个.

您的问题是由于按钮容器迫使窗口变宽,或者可能是由于您正在使用的 Java 版本中的 Swing 错误。

我的建议是不要打扰内置的布局类,而是使用 MigLayout。

于 2009-10-20T11:33:22.600 回答
0

我猜你把截图上的标签弄错了。

如果您指定

g.fillRect(0, 0, 310, 210); 

在 PaintPanel 和

paintPanel.setPreferredSize(new Dimension(320, 240));

在窗口中。你得到了第一个屏幕截图显示的内容。这是有道理的,因为矩形的宽度减少了 10 像素,高度减少了 30 像素。

如果您为两者设置相同的(宽度/高度;310、210),则蓝色矩形显然会“填充”PaintPanel。

于 2009-10-20T11:31:59.333 回答