简体   繁体   中英

JFrame expands when exported to Jar

Good day, I am building some basic snake game to learn more about Threading and Graphics in java. And in my eclipse project everything code-wise works not perfect but fine enough for my likings. Now I tried to export that project from eclipse to a runnable.jar file and somehow suddenly the frame is a different size than i assigned it and everthing is suddenly bigger than it should be which also messes with the rectangle that i set as a "border" for the playing field and so forth. I'm exporting as Runnable JAR File with the option "Package required libraries into generated jar". Anybody has an idea as to why that is and what i can do to either fix it or optimize my program to account for these things? Here's my code for everything that the frame is being used in:

import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Grid extends Canvas{

    private JFrame _container;
    private int _size;

    private int[] food;

    private boolean running;
    private boolean alive;

    private Snake s;
    private Rectangle _border;

    private int score;
    private int highscore;

    private BufferStrategy bs;

    public Grid() {
        super();

        _container = new JFrame("Snake Final");
        _container.setSize(622,656);
        _container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        _container.setVisible(true);

        setSize(600, 600);
        setVisible(true);

        _container.add(this);

        createBufferStrategy(2);
        bs = getBufferStrategy();

        food = new int[2];
        highscore = 0;

        init();
    }

    private void init() {
        _size = 30;
        _border = new Rectangle(0,0,getWidth(),getHeight());
        s = new Snake(_size, _border, this);

        setKeyListener();
        running = true;

        generateFood();

        run();

    }

    public void run() {
        running = true;
        while(running) {
            s.update();
            if(s.checkFood(food)) {
                generateFood();
            }
            draw();

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {}
        }
    }

    public void gameOver() {
        alive = false;
        if(score > highscore) {
            highscore = score;
        }
        Graphics g = this.getGraphics();
        g.setColor(Color.black);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.white);

//      g.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
//      g.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);


    }

    private void setKeyListener() {
        this.addKeyListener(new KeyListener() {

            @Override
            public void keyPressed(KeyEvent arg0) {

                if(arg0.getKeyCode() == KeyEvent.VK_W) {
                    if(running) {
                        if(s.getYDir() == 0) {
                            s.changeDirection(0, -1);
                        }
                    }
                }
                else if(arg0.getKeyCode() == KeyEvent.VK_S) {
                    if(running) {
                        if(s.getYDir() == 0) {
                            s.changeDirection(0, 1);
                        }
                    }
                }
                else if(arg0.getKeyCode() == KeyEvent.VK_A) {
                    if(running) {
                        if(s.getXDir() == 0) {
                            s.changeDirection(-1, 0);
                        }
                    }
                }
                else if(arg0.getKeyCode() == KeyEvent.VK_D) {
                    if(running) {
                        if(s.getXDir() == 0) {
                            s.changeDirection(1, 0);
                        }
                    }
                }
                else if(arg0.getKeyCode() == KeyEvent.VK_ENTER) {
                    alive = true;
                    s.setPosition(4 * _size, 4 * _size);
                    s.changeDirection(1, 0);
                }
            }

            @Override
            public void keyReleased(KeyEvent arg0) {}

            @Override
            public void keyTyped(KeyEvent arg0) {}
        });
    }

    private void generateFood() {       
        int gridParts = (getWidth()/_size) - 4;
        for(int i = 0; i < food.length; i++) {
            food[i] = ((int) (Math.random() * (gridParts)) * _size) + 2 * _size;
        }
    }

    private void draw() {
        Graphics bg = bs.getDrawGraphics();
        bg.clearRect(0, 0, getWidth(), getHeight());
        if(alive) {

            Graphics2D bg2d = (Graphics2D) bg;

            bg2d.setStroke(new BasicStroke(_size*4));
            bg2d.drawRect(0,0,getWidth(),getHeight());

            s.show(bg2d);
//          bg2d.fillRect(food[0] * _size, food[1] * _size, _size, _size);

            score = s.getSize();

            bg.setColor(Color.white);
            bg.setFont(new Font("SansSerif", Font.PLAIN, 20));
            bg.drawString(String.valueOf(score), 56, 35);

            bg2d.setColor(Color.RED);
            bg2d.fillRect((food[0] + 5), (food[1] + 5), _size - 10, _size - 10);

            bg2d.dispose();
        }
        else {
            bg.setColor(Color.black);
            bg.fillRect(0, 0, getWidth(), getHeight());

            bg.setColor(Color.white);
            bg.setFont(new Font("SansSerif", Font.PLAIN, 20));
            bg.drawString("Game Over", getWidth() / 2 - 55, getHeight() / 2 - 50);
            bg.drawString("Score: " + String.valueOf(score), getWidth() / 2 - 55, getHeight() / 2 - 20);
            bg.drawString("Highscore: " + String.valueOf(highscore), getWidth() / 2 - 55, getHeight() / 2 + 10);
            bg.drawString("Press Enter to restart", getWidth() / 2 - 55, getHeight() / 2 +40);
        }
        bs.show();
        bg.dispose();
    }

}

And sorry it's kind of really messy code but as the old saying goes why refactor it if it actually works kinda alright maybe

    _container = new JFrame("Snake Final");
    _container.setSize(622,656);
    _container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    _container.setVisible(true);

    setSize(600, 600);
    setVisible(true);

    _container.add(this);

You should not be hardcoding the size of a component. The size of your panel is ignored because Swing was designed to be used with layout managers. The default BorderLayout will set the size of you canvas based on the space available in the frame.

Instead you give a suggestion to the layout manager. The code should be something like:

    _container = new JFrame("Snake Final");
    _container.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //setSize(600, 600);
    //setVisible(true); // not needed components are visible by default
    setPreferredSize( new Dimension(600, 600) );
    _container.add(this);

    //_container.setSize(622,656);
    _container.pack();
    _container.setVisible(true);

So the component is added to the frame before the pack() and the frame is made visible. Then the size of the frame will be determined properly by the pack() method. It will include the preferred size of the canvas and will allow for the decorations of the frame (border and title bar).

Don't know if this will fix your problem with the creation of the Jar file (maybe there is some property that override the packed size?), but this is the better design approach for a Swing frame.

I just had a similar issue, with everything becoming 125% bigger when exported to Jar.

I added this line

System.setProperty("sun.java2d.uiScale", "1");

to my main method, and it solved the issue. More on changing DPI scaling can be found in this question.

(The property is not supported in JDK 8, so you need to run it on JDK 9 or higher. I use 14 and it works fine. Remember to change the CLASSPATH in your environment variables.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM