Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
728 views
in Technique[技术] by (71.8m points)

java - The point of origin in my GUI is off by about 25/26 pixels

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.

image

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);
}
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...