如何从 Eclipse 导出为可运行的 JAR



编辑:更新的代码和问题

我添加了 main() 方法,如 aswers 中所述,但我仍然无法导出它。我正在以 Java Applet 的身份运行我的程序,显然我需要使用 Java 应用程序独立运行它,但是当我将运行配置更改为应用程序时,我收到以下错误:

Exception in thread "main" java.lang.NullPointerException
at acm.graphics.GImage.determineSize(GImage.java:564)
at acm.graphics.GImage.setImage(GImage.java:173)
at acm.graphics.GImage.<init>(GImage.java:115)
at acm.graphics.GImage.<init>(GImage.java:54)
at Pong.createTexture(Pong.java:160)
at Pong.run(Pong.java:81)
at Pong.main(Pong.java:55)

我需要将我的项目从 Eclipse 导出为独立的可运行 JAR,但是当我导出 -> java -> JAR 文件时,我没有看到任何可供选择的类,并且我卡在这个(屏幕)窗口中。我的项目中只有一个类。

这不再相关,但我会把它留在这里以保留编辑历史记录


import java.awt.Color;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.util.Random;
import acm.graphics.GImage;
import acm.graphics.GLabel;
import acm.graphics.GObject;
import acm.graphics.GOval;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
/*      TO DO LIST
 *  ------------------
 *  Corner Bounce
 * 
 *  
 *  
 */
@SuppressWarnings("serial")
public class Pong extends GraphicsProgram {
public double mouseY;
private static final double PAUSE = 1000 / 96.0;
private Random rand = new Random();
private boolean AI_GODMODE = false;
// ball
public double startX;
public double startY;
private static final double BALL_SIZE = 20;
private static final double SPEED = 5;
private double ballHorizontalSpeed = SPEED * 1.5;
private double ballVerticalSpeed = SPEED;
// paddle
private static int HEIGHT = 150;
private static int WIDTH = 15;
private static int COUNTER = 0;
private static int AI_SPEED = 10; // AI difficulty 1-20
// label
public int AI_SCORE = 0;
public int PLAYER_SCORE = 0;
public int TOTAL_GAMES = 0;
private float TRANSPARENCY = 0.0f;
// counters
private static final int PADDING = 10;
private static final int MODIFIER = 3;
public static void main(String[] args) {
    Pong p = new Pong();
    p.run();
}
public void run() {
    addMouseListeners();
    // counters setup
    GLabel counter = new GLabel(String.valueOf(COUNTER));
    GLabel aiScore = new GLabel(String.valueOf(AI_SCORE));
    GLabel average = new GLabel(String.valueOf("Avg: 0"));
    GLabel playerScore = new GLabel(String.valueOf(COUNTER));
    Color labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
    Color scoreC = new Color(0, 0.0f, 0.0f, 0.1f);
    counter.setFont("Impact-600");
    aiScore.setFont("Impact-100");
    average.setFont("Impact-50");
    playerScore.setFont("Impact-100");
    counter.setColor(labelC);
    aiScore.setColor(scoreC);
    playerScore.setColor(scoreC);
    average.setColor(scoreC);
    counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
            getHeight() / 2 + counter.getHeight() / 3.2);
    counter.sendToFront();
    // make objects
    GImage paddleLeftTexture = createTexture("texture.png", WIDTH + 1,
            HEIGHT + 1);
    GImage paddleRightTexture = createTexture("texture2.png", WIDTH + 1,
            HEIGHT + 1);
    GImage ballTexture = createTexture("ballTexture.png", (int) BALL_SIZE,
            (int) BALL_SIZE);
    GImage greenFlash = createTexture("greenFlash.png", 100, 300);
    GImage blueFlash = createTexture("blueFlash.png", 100, 300);
    GOval ball = makeBall();
    GRect paddleLeft = makePaddle();
    GRect paddleRight = makePaddle();
    greenFlash.setLocation(-200, 0);
    blueFlash.setLocation(-200, 0);
    // generate GUI
    drawGraphics(ball, paddleLeftTexture, paddleRightTexture, ballTexture,
            greenFlash, blueFlash, counter, paddleLeft, paddleRight,
            aiScore, playerScore, average);
    // game start
    bounce(labelC, aiScore, playerScore, counter, ball, paddleLeft,
            paddleRight, paddleLeftTexture, paddleRightTexture,
            ballTexture, greenFlash, blueFlash, average);
}
public void bounce(Color labelC, GLabel aiScore, GLabel playerScore,
        GLabel counter, GOval ball, GRect paddleLeft, GRect paddleRight,
        GImage paddleLeftTexture, GImage paddleRightTexture,
        GImage ballTexture, GImage greenFlash, GImage blueFlash,
        GLabel average) {
    preGameSetup(ball, paddleRight, paddleRightTexture, counter);
    updateAiScore(aiScore);
    updatePlayerScore(playerScore);
    updateAverage(average);
    while (true) {
        moveBall(ballHorizontalSpeed, ballVerticalSpeed, ball, ballTexture);
        movePlayerPaddle(paddleLeft, paddleLeftTexture);
        moveAiPaddle(ball, paddleRight, paddleRightTexture);
        detectHit(ball, paddleRight, paddleLeft, counter, labelC);
        if (TRANSPARENCY >= 0.0f) {
            TRANSPARENCY -= TRANSPARENCY / 100f;
        }
        labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
        counter.setColor(labelC);
        if (detectBallOffScreen(ball)) {
            ballOffScreen(ball, ballTexture, aiScore, playerScore,
                    greenFlash, blueFlash, average);
            COUNTER = 0;
            bounce(labelC, aiScore, playerScore, counter, ball, paddleLeft,
                    paddleRight, paddleLeftTexture, paddleRightTexture,
                    ballTexture, greenFlash, blueFlash, average);
        }
        pause(PAUSE);
    }
}
public static GRect makePaddle() {
    GRect result = new GRect(0, 0, WIDTH, HEIGHT);
    result.setFilled(true);
    result.setColor(Color.BLACK);
    return result;
}
public static GOval makeBall() {
    GOval result = new GOval(150, 100, BALL_SIZE, BALL_SIZE);
    result.setFilled(true);
    result.setColor(Color.WHITE);
    return result;
}
private GImage createTexture(String importedImage, int width, int height) {
    Image importResult = getImage(getCodeBase(), importedImage);
    GImage textureResult = new GImage(importResult);
    textureResult.setSize(width, height);
    return textureResult;
}
public void mouseMoved(MouseEvent e) {
    mouseY = e.getY();
}
private boolean ballHitBottom(GOval ball) {
    double bottomY = ball.getY() + ball.getHeight();
    return bottomY >= getHeight();
}
private boolean ballHitTop(GOval ball) {
    double topY = ball.getY();
    return topY <= 0;
}
private boolean ballHitPaddleRight(GOval ball, GRect paddle) {
    double rightX = ball.getX() + ball.getWidth();
    double rightY = ball.getY() + ball.getHeight() / 2;
    double paddlePosX = paddle.getX();
    double paddlePosY = paddle.getY();
    if (rightX >= paddlePosX && rightY >= paddlePosY
            && rightY <= paddlePosY + paddle.getHeight())
        return true;
    else
        return false;
}
private boolean detectBallOffScreen(GOval ball) {
    if (ball.getX() < 2 * WIDTH - BALL_SIZE
            || ball.getX() > getWidth() - 2 * WIDTH)
        return true;
    else
        return false;
}
private boolean ballHitPaddleLeft(GOval ball, GRect paddle) {
    double leftX = ball.getX();
    double leftY = ball.getY();
    double paddlePosX = paddle.getX() + WIDTH;
    double paddlePosY = paddle.getY();
    if (leftX <= paddlePosX && leftY >= paddlePosY
            && leftY <= paddlePosY + paddle.getHeight())
        return true;
    else
        return false;
}
/*
 * private boolean ballHitPaddleBorder(GOval ball, GRect paddle) { ; if
 * (ball.getX() > paddle.getX() - BALL_SIZE && ball.getX() < paddle.getX() +
 * WIDTH && ball.getY() > paddle.getY() && ball.getY() < paddle.getY() +
 * ballVerticalSpeed) return true; else if (ball.getX() > paddle.getX() -
 * BALL_SIZE && ball.getX() < paddle.getX() + WIDTH && ball.getY() >
 * paddle.getY() + HEIGHT && ball.getY() < paddle.getY() + HEIGHT -
 * ballVerticalSpeed) return true; else return false; }
 */
private void preGameSetup(GObject ball, GObject paddleRight,
        GObject paddleRightTexture, GLabel counter) {
    startX = rand.nextInt((int) (getWidth() * 0.8))
            + (int) (0.1 * getWidth()); // zapobiega pojawieniu się piłki po
                                        // lewej stronie lewej paletki
    startY = rand.nextInt(getHeight());
    ball.setLocation(startX, startY);
    paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH, startY
            - HEIGHT / 2);
    paddleRight.setLocation(getWidth() - MODIFIER * WIDTH, startY - HEIGHT
            / 2);
    paddleRightTexture.sendToFront();
    counter.setLabel(String.valueOf(COUNTER));
    counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
            getHeight() / 2 + counter.getHeight() / 3.2);
    ballHorizontalSpeed = SPEED * 1.5;
    ballVerticalSpeed = SPEED;
}
private void updateAiScore(GLabel aiScore) {
    aiScore.setLabel(String.valueOf(AI_SCORE));
    aiScore.setLocation(getWidth() - aiScore.getWidth() - MODIFIER * WIDTH
            - PADDING, getHeight() - PADDING);
}
private void updatePlayerScore(GLabel playerScore) {
    playerScore.setLabel(String.valueOf(PLAYER_SCORE));
    playerScore.setLocation(MODIFIER * WIDTH + PADDING, getHeight()
            - PADDING);
}
private void updateScore(GLabel counter, Color labelC) {
    counter.setLabel(String.valueOf(COUNTER));
    counter.setLocation(getWidth() / 2 - counter.getWidth() / 2,
            getHeight() / 2 + counter.getHeight() / 3.2);
    TRANSPARENCY = 0.1f;
    labelC = new Color(0, 0.0f, 0.0f, TRANSPARENCY);
    counter.setColor(labelC);
}
private void updateAverage(GLabel average) {
    if (TOTAL_GAMES == 0) {
        average.setLabel("Round: 1                 Avg: 0");
    } else {
        average.setLabel("Round: " + String.valueOf(TOTAL_GAMES + 1) + "                Avg: "
                + String.valueOf((int) ((AI_SCORE + PLAYER_SCORE) / TOTAL_GAMES)));}
        average.setLocation(getWidth() / 2 - average.getWidth() / 2,
                getHeight() - PADDING);

}
private void drawGraphics(GObject ball, GObject paddleLeftTexture,
        GObject paddleRightTexture, GObject ballTexture,
        GObject greenFlash, GObject blueFlash, GObject counter,
        GObject paddleLeft, GObject paddleRight, GObject aiScore,
        GObject playerScore, GLabel average) {
    add(ball);
    add(paddleLeftTexture);
    add(paddleRightTexture);
    add(ballTexture);
    add(greenFlash);
    add(blueFlash);
    add(counter);
    add(paddleLeft);
    add(paddleRight);
    add(aiScore);
    add(playerScore);
    add(average);
}
private void detectHit(GOval ball, GRect paddleRight, GRect paddleLeft,
        GLabel counter, Color labelC) {
    if (ballHitBottom(ball) && ballVerticalSpeed >= 0) {
        ballVerticalSpeed *= -1;
    }
    if (ballHitTop(ball) && ballVerticalSpeed <= 0) {
        ballVerticalSpeed *= -1;
    }
    if (ballHitPaddleRight(ball, paddleRight)) {
        ballHorizontalSpeed *= -1;
    }
    if (ballHitPaddleLeft(ball, paddleLeft)) {
        ballHorizontalSpeed *= -1;
        COUNTER++;
        updateScore(counter, labelC);
        boolean bool = rand.nextBoolean();
        if (bool)
            if (ballHorizontalSpeed > 0)
                ballHorizontalSpeed += 1;
            else
                ballHorizontalSpeed -= 1;
        else if (ballVerticalSpeed > 0)
            ballVerticalSpeed += 0.5;
        else
            ballVerticalSpeed -= 0.5;
    }
    /*
     * if(ballHitPaddleBorder(ball, paddleLeft)){ ballVerticalSpeed *= -1; }
     * 
     * if(ballHitPaddleBorder(ball, paddleRight)){ ballVerticalSpeed *= -1;
     * }
     */
}
private void ballOffScreen(GOval ball, GObject ballTexture, GLabel aiScore,
        GLabel playerScore, GObject greenFlash, GObject blueFlash,
        GLabel average) {
    if (ball.getX() < 2 * WIDTH - BALL_SIZE) { // left
        double pos = ball.getY() - greenFlash.getHeight() / 2;
        ballTexture.move(-ballTexture.getWidth() * 2, 0);
        AI_SCORE += COUNTER;
        TOTAL_GAMES++;
        updateAiScore(aiScore);
        updateAverage(average);
        for (int i = 20; i < 100; i += 5) {
            greenFlash.setLocation(-i, pos);
            pause(25);
        }
    } else { // right
        double pos = ball.getY() - blueFlash.getHeight() / 2;
        ballTexture.move(ballTexture.getWidth() * 2, 0);
        PLAYER_SCORE += COUNTER;
        TOTAL_GAMES++;
        updatePlayerScore(playerScore);
        updateAverage(average);
        for (int i = 20; i < 100; i += 5) {
            blueFlash.setLocation(getWidth() - blueFlash.getWidth() + i,
                    pos);
            pause(25);
        }
    }
}
private void moveBall(double ballHorizontalSpeed, double ballVerticalSpeed,
        GObject ball, GObject ballTexture) {
    ball.move(ballHorizontalSpeed, ballVerticalSpeed);
    ballTexture.setLocation(ball.getX(), ball.getY());
    ballTexture.sendToFront();
}
private void movePlayerPaddle(GObject paddleLeft, GObject paddleLeftTexture) {
    if (mouseY < getHeight() - HEIGHT) { // Player
        paddleLeft.setLocation(2 * WIDTH, mouseY);
        paddleLeftTexture.setLocation(2 * WIDTH, mouseY);
        paddleLeftTexture.sendToFront();
    } else {
        paddleLeft.setLocation(2 * WIDTH, getHeight() - HEIGHT);
        paddleLeftTexture.setLocation(2 * WIDTH, getHeight() - HEIGHT);
        paddleLeftTexture.sendToFront();
    }
}
private void moveAiPaddle(GOval ball, GRect paddleRight,
        GImage paddleRightTexture) {
    if (AI_GODMODE == true) { // modeSelector
        if (ball.getY() < getHeight() - HEIGHT / 2
                && ball.getY() > HEIGHT / 2) {
            paddleRight.setLocation(getWidth() - MODIFIER * WIDTH,
                    ball.getY() - HEIGHT / 2);
            paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
                    ball.getY() - HEIGHT / 2);
            paddleRightTexture.sendToFront();
        } else if (ball.getY() <= HEIGHT / 2) {
            paddleRight.setLocation(getWidth() - MODIFIER * WIDTH, 0);
            paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
                    -0);
            paddleRightTexture.sendToFront();
        } else {
            paddleRight.setLocation(getWidth() - MODIFIER * WIDTH,
                    getHeight() - HEIGHT);
            paddleRightTexture.setLocation(getWidth() - MODIFIER * WIDTH,
                    getHeight() - HEIGHT);
            paddleRightTexture.sendToFront();
        }
    } else { // end godMode if
        double targetY = ball.getY() + BALL_SIZE / 2;
        if (targetY < getHeight() - HEIGHT / 2 && targetY > HEIGHT / 2) {
            if (targetY < paddleRight.getY() + HEIGHT / 2) {
                paddleRight.move(0, -AI_SPEED);
                paddleRightTexture.move(0, -AI_SPEED);
            } else if (targetY > paddleRight.getY() + HEIGHT / 2) {
                paddleRight.move(0, AI_SPEED);
                paddleRightTexture.move(0, AI_SPEED);
            }
        } // end normalMode if
    } // end modeSelector if
} // end moveAiPaddle void
} // end class

从链接的图像来看,您的类 Pong 没有主方法。它根本无法导出为可运行的 jar 文件,因为您永远无法运行它。添加一个 main 方法,或导出到标准 java jar 文件(文件 -> Export -> Java -> JAR 文件)。如果没有主方法,句号,它使用后一种方法生成的 jar 文件将无法运行。您必须有一个 main 方法才能独立运行此代码,因为这是应用程序的入口点。

根据您的评论,您需要在 main 方法内创建一个 Pong 类的实例并调用其 run() 方法:

public static void main(String[] args) {
    Pong p = new Pong();
    p.run();
}

如果 Pong 类的 run 方法是静态的,则不需要实例,您可以这样做:

public static void main(String[] args) {
    Pong.run();
}

您应该将其导出为"可运行的JAR文件"而不是"JAR文件"。选择此选项后,您应该能够使用名为"启动配置:"的下拉菜单,然后您可以选择导出目的地。

我正在使用Eclipse Kepler。对于不同的版本,它可能不一样。

您的项目应包含带有 main 方法的类,以便您可以在"启动配置"下拉列表中看到您的项目。(日食开普勒)

最新更新