JFrame将22像素偏移(java.awt.Insets)添加到Frame的顶部

时间:2015-01-24 12:17:47

标签: java swing jframe jpanel awt

我正在制作一款简单的Break Out风格游戏。主游戏扩展了JFrame,我在框架中添加了JPanel。

当我使用paint()绘制游戏图形时,项目按预期位于窗口内(即通过x,y坐标)。

我已经更新了代码以使用BufferStrategy,因为我正在闪烁。由于,渲染的图形偏移22px。

这意味着砖块不在屏幕的顶部!

代码如下:

package BreakOut;

import javax.swing.*;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;


public class Game extends JPanel implements KeyListener{

GameStateManager gsm = new GameStateManager();
BufferStrategy strategy;

public Game() {

    //add menu state to GameStateManager
    gsm.add(new MenuState(gsm));
    createFrame();


    while(true)
    {
        gsm.update();
        //repaint();
        render();
        try{
            Thread.sleep(10);
        }
        catch(InterruptedException e)
        {

        }
    }
}


public void createFrame()
{
    JFrame frame = new JFrame("Mini Tennis");
    frame.setLayout(new BorderLayout());
    this.setPreferredSize(new Dimension(400,400));
    frame.add(this);        
    frame.pack();       
    frame.setBackground(Color.BLACK);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    addKeyListener(this);
    this.setFocusable(true);
    frame.createBufferStrategy(2);
    strategy = frame.getBufferStrategy();
    frame.setVisible(true);
    System.out.println(frame.getInsets());
}


public void render()
{
    Graphics g = strategy.getDrawGraphics();
    super.paint(g);
    gsm.render(g);
    g.dispose();
    strategy.show();
}


public void keyPressed(KeyEvent k) {
    switch(gsm.getState())
    {
        case MAIN_MENU:
        if(k.getKeyCode()==KeyEvent.VK_ENTER)
        {
            //add the PlayState to the Stack and update enum value
            gsm.add(new PlayState(gsm, this));
        }
        break;
        case PLAYING:
            if(k.getKeyCode()==KeyEvent.VK_P)
            {
                //add the PlayState to the Stack and update enum value
                gsm.add(new PauseState(gsm));
            }
            break;
        case PAUSE:
            if(k.getKeyCode()==KeyEvent.VK_P)
            {                   
                gsm.pop();
            }
            break;
        case GAME_OVER:
            if(k.getKeyCode()==KeyEvent.VK_ENTER)
            {                   
                gsm.pop();
            }
            break;
    }
    //send input to GameStateManager
    gsm.keyPressed(k.getKeyCode()); 
}

public void keyReleased(KeyEvent k) {
    gsm.keyReleased(k.getKeyCode());        
}

public void keyTyped(KeyEvent k) {
    gsm.keyTyped(k.getKeyCode());   
}


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

}

}

当我输出System.out.println(frame.getInsets());我得到了

java.awt.Insets[top=22,left=0,bottom=0,right=0]

我显然做错了但是无法弄清楚为什么添加BufferStrategy会使JPanel偏移22px

任何帮助将不胜感激:)

1 个答案:

答案 0 :(得分:1)

框架有边框和装饰,它包含在框架的边界内(它们不会被添加到外部),从你使用MacOS的东西看起来,22像素到顶部是窗口标题。

最佳解决方案是,不要将框架用作渲染表面,而是使用Game类。这意味着它需要从java.awt.Canvas而不是javax.swing.JPanel延伸,您需要从中创建BufferStrategy

如果您覆盖Canvas的{​​{1}}方法,则可以在框架周围使用getPreferredSize,因此物理框架将大于内容,但内容将是您想要的尺寸

您还希望将主/游戏循环移动到单独的线程,因为这是阻止事件调度线程的风险,这可能导致您无法解决问题(例如从未获得关键事件)