JFrame导出到Jar时会展开

问题描述 投票:0回答:1

早上好,我正在构建一些基本的蛇游戏,以了解有关Java中的线程和图形的更多信息。在我的日食项目中,所有代码方面的工作都不完美,但足以满足我的喜好。现在,我尝试将项目从eclipse导出到可运行的.jar文件中,不知何故,框架的大小与我为其指定的大小不同,并且所有内容突然都大于其应有的大小,这也弄乱了我设置为“边框”的矩形”等等。我正在使用选项“将所需的库打包到生成的jar中”导出为可运行的JAR文件。任何人都知道为什么会这样,以及我可以做什么来解决它或优化程序以解决这些问题?这是框架使用的所有代码:

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

}

对不起,它的代码确实很凌乱,但正如老话所说,如果它可以正常工作,为什么要重构它,也许还可以

java executable-jar
1个回答
0
投票
    _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);

您不应该对组件的大小进行硬编码。面板的大小将被忽略,因为Swing旨在与布局管理器一起使用。默认的BorderLayout将根据框架中可用的空间来设置画布的大小。

相反,您会向布局管理器提出建议。该代码应类似于:

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

因此将组件添加到pack()之前的框架中,并使该框架可见。然后,将通过pack()方法正确确定帧的大小。它将包括画布的首选大小,并将允许装饰框架(边框和标题栏)。

不知道这是否能解决创建Jar文件时遇到的问题(也许有一些属性可以覆盖打包的大小?),但这是对Swing框架更好的设计方法。

© www.soinside.com 2019 - 2024. All rights reserved.