【问题标题】:Size of JFrame odd after pack()pack() 后 JFrame 奇数的大小
【发布时间】:2014-09-30 01:08:13
【问题描述】:

我有这段代码:

frame.setTitle("SideScroller");
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
Dimension dim = new Dimension(1000, 500);
frame.setContentPane(gamePanel);               //gamePanel is an extended JPanel
gamePanel.setPreferredSize(dim);
frame.pack();  

在我运行这段代码并用部分 50x50p 填充 gamePanel 后,应该完全填充 gamePanelframe,屏幕的右侧和底部有一些空的像素行。

frame.getSize();    //gives us: 1016 x 539
frame.getInsets();  //gives: Top: 31 | Left: 8 | Bottom: 8 | Right: 8  

结果图片:


如您所见,JFrame 中仍有一些空房间。

填写gamePanel的代码:

//Fill the panel with landscape
//One part : 50x50 px
//Panel : 1000x500 px
//Width : 20 prts
//Height : 10 prts
@Override
public void paint(Graphics g){
    super.paint(g);
    for(int i = 0; i < 20; i++){
        for(int j = 0; j < 10; j++){
            //Decide which landscape-img should be used
            switch(levelOne[j][i]){
                case 0:g.drawImage(new ImageIcon("resources\\landscape-img\\air.png")
                                    .getImage(), 50 * i, 50 * j, null);
                    break;
                case 1:g.drawImage(new ImageIcon("resources\\landscape-img\\ground.png")
                                    .getImage(), 50 * i, 50 * j, null);
                    break;              
            }
        }
    }
    g.dispose();
}

我不明白为什么frame 没有填满。希望有人可以帮助我!

【问题讨论】:

  • 似乎问题出在那些 JFrame 插图上。您设置的首选大小与您返回的大小值之间的差异正是插图的内容。所以也许你需要创建一个值为 0 的 Insets 并调用 JFrame.setInsets?
  • @ControlAltDel 正在尝试,感谢您的建议。
  • 我还发现,有时 UI 表现得像这样,它可以帮助开始倒退......而不是使用您的面板调用 setContentPane,如何将其添加到预先存在的contentPane(具有正确的布局),看看它的样子?
  • @ControlAltDel 好像没有setInsets()...?
  • @ControlAltDel 我不太明白你的第二个建议。你的意思是我应该用 1000x500 的图片创建一张图片并将其放在 contentPane 中,还是其他什么?

标签: java swing jframe


【解决方案1】:

一些提示可以帮助您解决问题。

1) 如果您需要您的游戏面板具有首选尺寸,则只需像这样覆盖 getPreferredSize()

public class GamePanel extends JPanel {
    ...
    @Override
    public Dimension getPreferredSize() {
        return isPreferredSizeSet() 
             ? super.getPreferredSize() : new Dimension(1000, 500);
    }
    ...
}

另见Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?

2) 请注意,您不应覆盖 paint() 方法,而应覆盖 paintComponent()。见A Closer Look at the Paint Mechanism

public class GamePanel extends JPanel {
    ...
    @Override
    protected void paintComponent(Graphics g) {
       // Your implementation here
    }
    ...
}

3) 正如已经建议的那样,只需将您的 gamePanel 直接添加到框架的内容窗格中:

frame.getContentPane().add(gamePanel);

这样您将利用其默认布局管理器:BorderLayout 使您的面板填满整个中心区域。

4) 最后,虽然您可以完美地使用 Swing 来制作游戏,但它并不是最好的 API,因为它是为桌面应用程序设计的。您可能需要考虑使用一些用于游戏开发的库,例如

【讨论】:

  • 我并不真正理解您的第一点的语法,Eclipse 似乎也不理解。你能解释一下为什么你使用voidreturn 吗?问号呢?
  • 找到问号here
  • 这正是问号的意思。关于“无效”,它实际上是一个错误(我的错),它应该是“维度”。我会尽快修复它。 @ikhebgeenaccount
【解决方案2】:

找到答案here。我打电话给frame.setResizable(false)之后我打电话给frame.pack(),显然这搞砸了frame。你必须在pack()(或`setVisible(true))之前调用它之前

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-26
    相关资源
    最近更新 更多