JFrame将22像素偏移量(java.awt.Insets)添加到Frame的顶部 [英] JFrame adding 22 pixel offset (java.awt.Insets) to top of the Frame

查看:49
本文介绍了JFrame将22像素偏移量(java.awt.Insets)添加到Frame的顶部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个简单的Break Out风格游戏.主要游戏扩展了JFrame,我将一个JPanel添加到框架中.

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

随着闪烁,我已经更新了代码以使用BufferStrategy.从开始,渲染的图形偏移了22px.

这意味着积木不在屏幕顶部!

代码如下:

 包BreakOut;导入javax.swing.*;导入java.awt.*;导入java.awt.event.KeyEvent;导入java.awt.event.KeyListener;导入java.awt.image.BufferStrategy;公共类Game扩展了JPanel实现KeyListener {GameStateManager gsm = new GameStateManager();BufferStrategy策略;公共游戏(){//将菜单状态添加到GameStateManagergsm.add(new MenuState(gsm));createFrame();而(真){gsm.update();//repaint();使成为();尝试{Thread.sleep(10);}catch(InterruptedException e){}}}公共无效createFrame(){JFrame frame =新的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);策略= frame.getBufferStrategy();frame.setVisible(true);System.out.println(frame.getInsets());}公共无效render(){图形g = strategy.getDrawGraphics();超级油漆(克);gsm.render(g);g.dispose();strategy.show();}公共无效keyPressed(KeyEvent k){开关(gsm.getState()){情况MAIN_MENU:if(k.getKeyCode()== KeyEvent.VK_ENTER){//将PlayState添加到堆栈中并更新枚举值gsm.add(new PlayState(gsm,this));}休息;案例播放:if(k.getKeyCode()== KeyEvent.VK_P){//将PlayState添加到堆栈中并更新枚举值gsm.add(new PauseState(gsm));}休息;案例暂停:if(k.getKeyCode()== KeyEvent.VK_P){gsm.pop();}休息;案例GAME_OVER:if(k.getKeyCode()== KeyEvent.VK_ENTER){gsm.pop();}休息;}//将输入发送到GameStateManagergsm.keyPressed(k.getKeyCode());}公共无效keyReleased(KeyEvent k){gsm.keyReleased(k.getKeyCode());}公共无效keyTyped(KeyEvent k){gsm.keyTyped(k.getKeyCode());}公共静态void main(String [] args){新游戏();} 

}

当我输出System.out.println(frame.getInsets());时我知道了

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

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

任何帮助将不胜感激:)

解决方案

从您所看到的事物的外观来看,框架具有边框和装饰,这些都包含在框架的边界内(它们不会添加到外部).正在使用MacOS,顶部的22pixels是窗口标题.

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

如果您覆盖 Canvas getPreferredSize 方法,则可以在框架上使用 pack ,它将围绕此框架包装窗口,因此物理框架会比内容大,但是内容将是您希望的大小

您还需要将主循环/游戏循环移动到单独的线程,因为这有阻塞事件调度线程的风险,这可能会导致问题无止境(例如永远不会发生键事件)

I'm creating a simple Break Out style game. The main game extends JFrame and I'm adding a JPanel to the frame.

When I was using paint() to draw the game graphics the items sat within the window as expected (i.e by their x, y coordinates).

I've updated the code to use BufferStrategy as I was getting flickering. Since the, the graphics that are rendered are offset by 22px.

This means the Bricks are off the top of the screen!

The code is as follows:

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();

}

}

When I output System.out.println(frame.getInsets()); I get

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

I'm obviously doing something wrong but can't figure out why adding BufferStrategy would create the JPanel to be offset by 22px

Any help would be appreciated :)

解决方案

Frames have borders and decorations, which is included within the bounds of the frame (they don't get added to the outside), from the looks of things you're using MacOS and the 22pixels to the top is the window title.

Best solution is, don't use the frame as the render surface, instead, use the Game class. This will mean it will need to extend from java.awt.Canvas instead of javax.swing.JPanel and you will need to create the BufferStrategy from it

If you override the Canvas's getPreferredSize method, you can use pack on the frame it will pack the window around this, so the physical frame will be larger then the content, but the content will be the size you would prefer

You will also want to move you main/game loop to separate thread, as this is current in the risk of blocking the Event Dispatching Thread, which could cause you no end of issues (like never getting a key event)

这篇关于JFrame将22像素偏移量(java.awt.Insets)添加到Frame的顶部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆