我的图形用户界面的起点大约是25/26像素 [英] The point of origin in my GUI is off by about 25/26 pixels

查看:149
本文介绍了我的图形用户界面的起点大约是25/26像素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的GUI上的原点(0,0)上移约25/26像素。所以我的GUI的左上角似乎代表0,25或0.26。我使用双缓冲区来绘制事物。基本上,每当我尝试在0,0​​处绘制缓冲区中的内容时,它都会显示在屏幕外。



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



这里是我的代码(在不相关的部分中剪切):

pre $ public class Dekari_gameGUI扩展JFrame实现KeyListener {
//资源
private final String imagePath =资源/图片/;
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();
//游戏变量
private int pX = 0,pY = 0;
私人短pDir = -1,pLastDir = 0,pAniStage = 0,计数器= 0;
//图形和绘图变量
专用图形缓冲区;
私人Image offscreen;
私人维度昏暗;
//内部变量,用于循环和占位符
private int a,b,c,d;

/ *
____ _ _
/ ___ | ___ _ __ ___ | | _ _ _ _ _ _ ___ | | _ ___ _ __
| | / _ \ | '_ \ / __ | __ | __ | | | | / __ | __ / _ \ | __ |
| | __ | (_)| | | \__ \ | _ | | | | _ | | (__ | ||(_)| |
\ ____ \ ___ / | _ | | _ | ___ / \__ | _ | \ __,_ | \ ___ | \__\ ___ / | _ |
* /
public Dekari_gameGUI(){
//声明GUI设置
setResizable(false);
setTitle(Dekari RPG Indev v1。 0);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setSize(640,480);
setBackground(Color.GREEN);
setLocationRelativeTo(null ); //居中窗口

splitSpriteSheets(); //设置资源
$ b $ dim = getSize();
offscreen = createImage(dim.width, dim.height);
buffer = offscreen.getGraphics();

* snip *
$ b $ setVisible(true);
}

* snip *

/ *
____ _ _
| _ \ __ _(_)_ _ _ _ _ _ _ _ _ b $ b | | _) / _` | | '_ \ | __ |
| __ /(_ | | | | | | | _
| _ | \ __,_ | _ | _ | | _ | \__ |
* /
public void paint图形g){
//清除缓冲区
buffer.clearRect(0,0,dim.width,dim.width);
//将图像绘制到缓冲区
buffer .setColor(Color.BLACK);
boolean paint = true;
//这是我的棋盘绘图函数
(a = 0; a< getWidth()/ 32; a ++) (b = 0; b if(paint){
paint = false;
buffer.fillRect(a * 32,b * 32,32,32);
} else {
paint = true;
}
}
}
if(pDir == -1)//如果玩家没有移动
//在面对上次移动方向的空闲姿势中绘制玩家
buffer.drawImage(sprites [0] [4 * pLastDir],pX - 24,pY - 32,this);
else //如果玩家正在移动
//在运动状态界面中绘制玩家g当前方向
buffer.drawImage(sprites [0] [pAniStage +(4 * pLastDir)],pX - 24,pY - 32,this);

//将缓冲区绘制到框架
g.drawImage(offscreen,0,0,this);
}

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


解决方案

否不是。您可以直接在框架上绘画,在框架边界上绘制边框装饰。欢迎来到为什么你不应该直接绘制到顶层容器的奇妙世界。



相反,将自定义绘画移动到另一个组件,例如 JPanel 并将其直接添加到框架中。通过重写面板的 getPreferredSize ,可以将其放置在边框的边框中

方法并返回适当的值,您可以利用 JFrame#pack 来打包框架,使其符合内容的首选大小要求。这样可以确保内容的大小和窗口的装饰都围绕它。



另外请记住,Swing组件默认为双缓冲区,所以您不会有重新发明轮子,除非你有特别需要这样做...



有关更多信息,请参阅 如何获得精确的屏幕中间 - 甚至当重新调整大小时/ 13460914#13460914大小为什么重写顶层容器中的paint如此糟糕?为什么不直接绘制insid e JFrame 了解更多详情

My point of origin (0,0) on my GUI is moved up by about 25/26 pixels. So the very top-left corner of my GUI seems to represent 0,25 or 0,26. I am using a double buffer to draw in things. Basically, whenever I try to draw something in my buffer at 0,0, it appears off-screen.

For example, below is a screenshot of a checkerboard pattern I attempted to generate, starting from 0,0. Although it seems fine horizontally, notice the chopped checkerboard at the top. The height is 480, which is divisible by 32 keep in mind, so the checkerboard pattern should fill in perfectly.

And here is my code (Snipped in irrelevant parts):

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

解决方案

No it's not. You painting directly to the frame, which has it's border decorations painted WITHIN the frames boundaries. Welcome to the wonderful world of why you shouldn't paint directly to top level containers.

Instead, move you custom painting to another component, such as a JPanel and add this directly to the frame. This will be laid out in such away so as to positioned within the frames border decorations

By overriding the panel's getPreferredSize method and returning an appropriate value, you can utilise JFrame#pack to "pack" the frame so that it meets the preferred size requirements of the content. This will ensure that the content is at it's preferred size and the window decorations surround it.

Also remember, Swing components are double buffered by default, so you won't have to reinvent the wheel, unless you have a particular need to do so...

For more information, take a look at How can I set in the midst? and How to get the EXACT middle of a screen, even when re-sized and Why is overriding paint in a top-level container so bad? and Why not to draw directly inside JFrame for more details

这篇关于我的图形用户界面的起点大约是25/26像素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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