我的GUI中的原点是大约25/26像素

时间:2014-07-21 05:31:53

标签: java swing graphics jframe paint

我的GUI上的原点(0,0)向上移动了大约25/26像素。所以我的GUI的左上角似乎代表0,25或0,26。我正在使用双缓冲来绘制内容。基本上,每当我尝试在0,0​​的缓冲区中绘制内容时,它就会出现在屏幕外。

例如,下面是我尝试生成的棋盘图案的屏幕截图,从0,0开始。虽然水平看起来很好,但请注意顶部的切碎棋盘。高度为480,可以被32整除,因此棋盘图案应该完美填充。

image

这是我的代码(剪下不相关的部分):

public class Dekari_gameGUI extends JFrame implements KeyListener {
// Resources
private final String imagePath = "Resources/Images/";
private final String spriteSheetPath = imagePath + "Sprite Sheets/";
private final String soundPath = "Resources/Sounds/";
private final String dataPath = "Resources/Data/";
private BufferedImage[][] sprites;
private Timer playerMovementTimer = new Timer();
//Game variables
private int pX = 0, pY = 0;
private short pDir = -1, pLastDir = 0, pAniStage = 0, counter = 0;
//Graphics and paint variables
private Graphics buffer;
private Image offscreen;
private Dimension dim;
//Internal variables, used for loops and placeholders
private int a, b, c, d;

/*
  ____                _                   _             
 / ___|___  _ __  ___| |_ _ __ _   _  ___| |_ ___  _ __ 
| |   / _ \| '_ \/ __| __| '__| | | |/ __| __/ _ \| '__|
| |__| (_) | | | \__ \ |_| |  | |_| | (__| || (_) | |   
 \____\___/|_| |_|___/\__|_|   \__,_|\___|\__\___/|_|   
 */
public Dekari_gameGUI() {
    // Declaring GUI setup
    setResizable(false);
    setTitle("Dekari RPG Indev v1.0");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pack();
    setSize(640, 480);
    setBackground(Color.GREEN);
    setLocationRelativeTo(null); //Centers the window

    splitSpriteSheets(); //Sets up resources

    dim = getSize();
    offscreen = createImage(dim.width, dim.height);
    buffer = offscreen.getGraphics();

    *snip*

    setVisible(true);
}

*snip*

/*
 ____       _       _   
|  _ \ __ _(_)_ __ | |_ 
| |_) / _` | | '_ \| __|
|  __/ (_| | | | | | |_ 
|_|   \__,_|_|_| |_|\__|
 */
public void paint(Graphics g) {
    //Clears the buffer
    buffer.clearRect(0, 0, dim.width, dim.width);
    //Drawing images to the buffer
    buffer.setColor(Color.BLACK);
    boolean paint = true;
    //This is my checkerboard drawing function
    for (a = 0; a < getWidth() / 32; a++) {
        for (b = 0; b < getHeight() / 32; b++) {
            if (paint) {
                paint = false;
                buffer.fillRect(a * 32, b * 32, 32, 32);
            } else {
                paint = true;
            }
        }
    }
    if (pDir == -1) //If the player is not moving
        //Draws player in an idle stance facing last moved direction
        buffer.drawImage(sprites[0][4 * pLastDir], pX - 24, pY - 32, this);
    else //If the player is moving
        //Draws player in a movement state facing the current direction
        buffer.drawImage(sprites[0][pAniStage + (4 * pLastDir)], pX - 24, pY - 32, this);

    //Drawing the buffer to the frame
    g.drawImage(offscreen, 0, 0, this);
}

public void update(Graphics g) {
    paint(g);
}
}

1 个答案:

答案 0 :(得分:7)

不,不是。你直接绘制到框架,框架的边框装饰画在框架边界内。欢迎来到为什么你不应该直接在顶层容器上涂漆的美妙世界。

相反,将自定义绘画移动到另一个组件,例如JPanel,并将其直接添加到框架中。这将被布置在这样的位置,以便定位在框架边框装饰

通过覆盖面板的getPreferredSize方法并返回适当的值,您可以使用JFrame#pack来打包&#34;打包&#34;框架使其满足内容的首选尺寸要求。这将确保内容符合其首选尺寸,窗口装饰环绕它。

另外请记住,默认情况下,Swing组件是双缓冲的,因此您不必重新发明轮子,除非您特别需要这样做...

有关详细信息,请查看How can I set in the midst?How to get the EXACT middle of a screen, even when re-sized以及Why is overriding paint in a top-level container so bad?Why not to draw directly inside JFrame了解详情