Java 框架和画布的增长大于指定值

Java 框架和画布的增长大于指定值,java,jframe,awt,jpanel,Java,Jframe,Awt,Jpanel,我不知道为什么我会有一个特别大的窗口,这让我在游戏窗口里跑篮球来适应我的精灵。构造器应该使所有的子组件彼此适合,但是看起来画布或框架中有一些额外的填充。我很难弄清楚罪魁祸首是什么。我的框架尺寸不应大于800x600(操作系统装饰不包括在内,谈论容器) 正如您所看到的,边界比我指定的要大 班级: public class GameFrame { private JFrame frame; private JPanel panel; private Canvas canvas; private Bu

我不知道为什么我会有一个特别大的窗口,这让我在游戏窗口里跑篮球来适应我的精灵。构造器应该使所有的子组件彼此适合,但是看起来画布或框架中有一些额外的填充。我很难弄清楚罪魁祸首是什么。我的框架尺寸不应大于800x600(操作系统装饰不包括在内,谈论容器)

正如您所看到的,边界比我指定的要大

班级:

public class GameFrame {
private JFrame frame;
private JPanel panel;
private Canvas canvas;
private BufferStrategy bufferStrategy;
private Graphics2D g;
private int width;
private int height;

public GameFrame(Color bgColor) {
    this.width = GameEngine.GAMEDIMENSION[0]; // 800
    this.height = GameEngine.GAMEDIMENSION[1]; // 600
    this.frame = new JFrame();
    this.panel = (JPanel) frame.getContentPane();
    this.panel.setPreferredSize(new Dimension(width, height));
    this.panel.setLayout(null);
    this.panel.setBackground(bgColor);
    this.canvas = new Canvas();
    this.canvas.setBounds(0, 0, width, height);
    this.canvas.setIgnoreRepaint(true);
    this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    this.frame.pack();
    this.frame.setResizable(false);
    this.frame.setVisible(true);
    this.panel.add(canvas);
    this.canvas.createBufferStrategy(2);
    this.bufferStrategy = canvas.getBufferStrategy();
    this.g = (Graphics2D) bufferStrategy.getDrawGraphics();
    this.canvas.requestFocus();

}
主要问题:

public static void main(String[] args) {
    GameFrame gf = new GameFrame(Color.black);
    System.out.println("Panel: " + gf.panel.getBounds());
    System.out.println("Frame: " + gf.frame.getBounds());
    System.out.println("Canvas:" + gf.frame.getBounds());

    for (int R = 0; R < 255; R++) {
        for (int B = 0; B < 255; B++) {
            for (int G = 0; G < 255; G++) {
                gf.g.setColor(Color.black);
                gf.g.fillRect(0, 0, gf.width, gf.height);
                gf.g.setColor(new Color(R, B, G));
                gf.g.fillRect(0, 0, gf.width, gf.height);
                gf.bufferStrategy.show();
            }
        }
    }

}
publicstaticvoidmain(字符串[]args){
游戏框架gf=新游戏框架(颜色为黑色);
System.out.println(“Panel:+gf.Panel.getBounds());
System.out.println(“Frame:+gf.Frame.getBounds());
System.out.println(“Canvas:+gf.frame.getBounds());
对于(int R=0;R<255;R++){
对于(int B=0;B<255;B++){
对于(int G=0;G<255;G++){
gf.g.setColor(颜色为黑色);
gf.g.fillRect(0,0,gf.width,gf.height);
gf.g.setColor(新颜色(R,B,g));
gf.g.fillRect(0,0,gf.width,gf.height);
gf.bufferStrategy.show();
}
}
}
}
大体上,我尝试循环方块只是为了看到效果。

交换
pack
setresizeable
调用,以便
pack
是第二个调用

在下面的示例中,它将在面板上写入
200x200
,如果您交换呼叫,它将写入
210x210

这是一个众所周知的“问题”


1-我建议不要使用
null
布局。2-尝试交换
setResiable
setVisible
语句,使帧首先可见。要添加到这一点,请执行
setLocationByPlatform(true)
,以便更好地查看帧。为什么要使用缓冲策略?这是AWT的策略。Swing是双缓冲的。说到这一点,我有点偏执,我正在确保我的游戏中启用了缓冲。谢谢您的建议。@syb0rg您也可以使用
frame.setLocationRelativeTo(null)使其在屏幕上居中;)谢谢,现在至少面板大小正确了。问题是框架和画布仍然太大。特别是一个问题,因为我是在画布的缓冲区上绘制的,从技术上讲,我可以对其进行编码,这样我就不会在可见面板之外绘制,但我想知道为什么会发生这种情况。框架的大小将是内容窗格加上窗口边框的首选大小。你不能,安全地计算这个,所以我会忽略它,并担心,集中精力获得游戏区域的大小,你想要它。
public static void main(String[] args) {
    GameFrame gf = new GameFrame(Color.black);
    System.out.println("Panel: " + gf.panel.getBounds());
    System.out.println("Frame: " + gf.frame.getBounds());
    System.out.println("Canvas:" + gf.frame.getBounds());

    for (int R = 0; R < 255; R++) {
        for (int B = 0; B < 255; B++) {
            for (int G = 0; G < 255; G++) {
                gf.g.setColor(Color.black);
                gf.g.fillRect(0, 0, gf.width, gf.height);
                gf.g.setColor(new Color(R, B, G));
                gf.g.fillRect(0, 0, gf.width, gf.height);
                gf.bufferStrategy.show();
            }
        }
    }

}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestResizeFrame {

    public static void main(String[] args) {
        new TestResizeFrame();
    }

    public TestResizeFrame() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                // Will appear as 200x200, swap them and it will appear as 210x210
                frame.setResizable(false);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g); 
            FontMetrics fm = g.getFontMetrics();
            g.drawString(getWidth() + "x" + getHeight(), 0, fm.getAscent());
        }

    }

}