单击关闭X按钮无法关闭框架

时间:2014-03-05 13:53:36

标签: java swing awt frame

我已通过此link1 link2获得答案,但没有帮助。

因为

frame.setVisible(false);

给出了以下异常,

Exception in thread "main" java.lang.NullPointerException
    at Simulation.drawOcean(Simulation.java:72)
    at Simulation.main(Simulation.java:191)

应用程序有2个以下的java文件。

模拟类启动GUI。

使用默认命令行参数运行Simulation.java后,尽管有限的while循环,Frame仍未关闭。 在模拟完成后,我无法通过单击关闭按钮(右上角 - 红色)来关闭框架。

我是否需要为Frame设置一些属性?

请帮帮我!!!

/* Simulation.java */

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.util.Random;
/* DO NOT CHANGE THIS FILE (except as noted). */

/* (You may wish to make temporary changes or insert println() statements)  */
/* while testing your code. When you're finished testing and debugging,   */
/* though, make sure your code works with the original version of this file */




/**
 * The Simulation class is a program that runs and animates a simulation of 
 * Sharks and Fish.
 * 
 * The Simulation program takes up to four parameters. The first two specify
 * the width and height of the ocean. The third parameter specifies the value 
 * of starveTIme. For example, if you run
 * 
 *          java Simulation 25 25 1
 *  
 * then Simulation will animate a 25x25 ocean with a starveTime of 1. If you 
 * run "java Simulation" with no parameters, by default Simulation will animate
 * a 50x25 ocean with a starveTime of 3. With some choices of parameters,
 * the ocean quickly dies out;  with others;, it teems forever.
 *  
 * @author mohet01
 *
 */
public class Simulation {

    /**
     * The constant cellSize determines the size of each cell on the screen
     * during animation.  (You may change this if you wish).
     */
    private static final int cellSize = 4;


    /**
     * Default parameters. (You may change this of you wish).
     */

    private static int  i = 50;                           //Default ocean width
    private static int  j = 25;                          //Default ocean height
    private static int starveTime = 3;          //Default shark starvation time


    /**
     * drawOcean() adds cell contents as part of graphics
     */

    private static void drawOcean(Graphics graphics, Ocean ocean){
        if(ocean != null){
            int width = ocean.width();
            int height = ocean.height();

            for(int row = 0; row < height; row++){
                for(int col = 0; col < width; col++){
                    int contents = ocean.cellContents(row, col);
                    if(contents == Ocean.SHARK){
                        //Draw a red Shark
                        graphics.setColor(Color.red);
                        graphics.fillRect(row*cellSize, col*cellSize, cellSize, cellSize);
                    }else if(contents == Ocean.FISH){
                        // Draw a green fish
                        graphics.setColor(Color.green);                
                        graphics.fillRect(row * cellSize, col * cellSize, cellSize, cellSize);
                    }else{
                        //Clear the rectangle
                        graphics.clearRect(row, col, cellSize, cellSize);
                    }
                }
            }
        }
    }


    /**
     * main() reads the parameters and performs the simulation and animation. 
     * @param args
     * @throws InterruptedException 
     */

    public static void main(String[] args) throws InterruptedException {
        Ocean sea;

        /**
         * Read the input parameters
         */

        if(args.length >0){
            try{
                i = Integer.parseInt(args[0]);
            }catch(NumberFormatException e){
                System.out.println("First argument to Simulation is not a number.");
            }
        }


        if(args.length > 1){
            try{
                j = Integer.parseInt(args[1]);
            }catch(NumberFormatException e){
                System.out.println("Second argument to Simulation is not a number");
            }
        }

        if(args.length > 2){
            try{
                starveTime = Integer.parseInt(args[2]);
            }catch(NumberFormatException e){
                System.out.println("Third argument to Simulation is not a number");
            }
        }



        /**
         * Create a window on your screen
         */

        Frame frame = new Frame("Sharks and Fish");
        frame.setSize(i*cellSize + 10, j*cellSize + 30);
        frame.setVisible(true);

        /**
         * Create a "Canvas" we can draw upon; attach it to the window 
         */

        Canvas canvas = new Canvas();
        canvas.setBackground(Color.white);
        canvas.setSize(i*cellSize, j*cellSize);
        frame.add(canvas);
        Graphics graphics = canvas.getGraphics();

        /**
         * Create the initial ocean.
         */

        sea = new Ocean(i, j, starveTime);

        /**
         * Visit each cell (in a roundabout order); randomnly place a fish, shark,
         * or nothing in each.
         */

        Random random = new Random(0);
        int x = 0;
        int y = 0;
        for(int row = 0;row < j; row++){
            //This will visit every x-coordinate once.
            x = (x + 78887) %j; 

            if((x & 8) == 0){
                for(int col = 0; col < i; col++){
                    //This will visit every y coordinate once.
                    y = (y+78887)%i;

                    if((y & 8) == 0){
                        int r = random.nextInt();

                        if(r < 0){
                            //50% of cells start with fish
                            //x - width, y - height
                            sea.addFish(x, y);
                        }else if(r > 1500000000){
                            //~15% of cells start with sharks
                            sea.addShark(x, y);
                        }
                    }
                }
            }
        }



        /**
         * Perform timesteps forever
         */
        int timeLeft = 20;
        while (timeLeft > 0) {                           
            // Wait one second (1000 milliseconds)
              Thread.sleep(1000);                
           // Draw the current ocean
              drawOcean(graphics, sea);                       
              //  For fun, you might wish to change the delay in the next line.
              //  If you make it too short, though, the graphics won't work properly.
              // Simulate a timestep
              sea = sea.timeStep();
              timeLeft--;

            }


    }

}

/* Ocean.java */

/**
 * The Ocean class defines an object that models an ocean full of sharks and
 * fish. Descriptions of the methods you must implements appear below. They
 * include a constructor of the form
 * 
 * public Ocean(int i, int j, int starveTime);
 * 
 * that creates an empty ocean having width i and height j, in which sharks
 * starve after starveTime timesteps.
 * 
 * See the README file accompanying this project for additional details.
 * 
 * @author mohet01
 * 
 */

public class Ocean {

    /**
     * Do not rename these constants. WARNING: if you change the numbers, you
     * will need to recompile Test4.java. Failure to do so will give you a very
     * hard-to-find bug.
     */

    public final static int EMPTY = 1;
    public final static int SHARK = 2;
    public final static int FISH = 3;


    /**
     * Define any variables associated with an Ocean object here. These
     * variables MUST be private.
     * 
     */

    private final static int UNKNOWN = -1; // for unknown return type
    private int width;
    private int height;
    private int[][] oceanMatrix;
    //TODO space optimization on below matrix
    private int[][] sharkHungerLevelMatrix;  
    private int starveTime;



    /**
     * The following methods are required for Part I.
     * 
     */

    /**
     * Constructor that creates an empty ocean having width i and
     * height j, in which sharks starve until after starveTime timesteps.
     * 
     * @param width(i)
     *            is the width of the ocean.
     * @param height(j)
     *            is the height of the ocean.
     * @param starveTime
     *            is the number of timeSteps sharks survive without food.
     */

    public Ocean(int i, int j, int starveTime) {
        this.width = i;
        this.height = j;
        this.oceanMatrix = new int[j][i];
        this.sharkHungerLevelMatrix = new int[j][i];
        this.starveTime = starveTime;
        for (int row = 0; row < j; row++) {
            for (int col = 0; col < i; col++) {
                oceanMatrix[row][col] = EMPTY;
            }
        }
        for (int row = 0; row < j; row++) {
            for (int col = 0; col < i; col++) {
                sharkHungerLevelMatrix[row][col] = EMPTY;
            }
        }
    }

    /**
     * width() returns the width of an ocean Object.
     * 
     * @return the width of the ocean.
     * 
     */

    public int width() {
        return this.width;
    }

    /**
     * height() returns the height of an Ocean object.
     * 
     * @return the height of the Ocean.
     */

    public int height() {
        return this.height;
    }

    /**
     * starveTime() returns the number of timesteps sharks survive without food.
     * 
     * @return the number of timesteps sharks survive without food.
     */

    public int starveTime() {
        return starveTime;
    }

    /**
     * addFish() places a fish in cell (x,y) if the cell is empty. If the cell
     * is already occupied, leave the cell as it is.
     * 
     * @param x
     *            is the x-coordinate of the cell to place a fish in.
     * @param y
     *            is the y-coordinate of the cell to place a fish in.
     */

    public void addFish(int x, int y) {
        if (oceanMatrix[x][y] == EMPTY) {
            oceanMatrix[x][y] = FISH;
        }
    }

    /**
     * addShark() (with two parameters) places a newborn shark in cell (x, y) if
     * the cell is empty. A "newborn" shark is equivalent to a shark that has
     * just eaten. If the cell is already occupied, leave the cell as it is.
     * 
     * @param x
     *            is the x-coordinate of the cell to place a shark in.
     * @param y
     *            is the y-coordinate of the cell to place a shark in.
     */
    public void addShark(int x, int y) {
        if (oceanMatrix[x][y] == EMPTY) {
            oceanMatrix[x][y] = SHARK;
        }
    }

    /**
     * cellContents() returns EMPTY is cell (x,y) is empty, FISH if it contains
     * a fish, and SHARK if it contains a shark.
     * 
     * @param x
     *            is the x-coordinate of the cell whose contents are queried.
     * @param y
     *            is the y-coordinate of the cell whose contents are queried.
     */
    public int cellContents(int x, int y) {
        return oceanMatrix[x][y];

    }

    /**
     * isFish() checks for the existence of fish in that cell.
     * @param x 
     *              is the x-coordinate of the cell whose contents are queried.
     * @param y 
     *              is the y-coordinate of the cell whose contents are queried.
     * @return the boolean value
     */
    private boolean isFish(int x, int y){
        return (this.oceanMatrix[x][y] == Ocean.FISH);
    }

    /**
     * isShark() checks for the existence of shark in that cell.
     * @param x 
     *              is the x-coordinate of the cell whose contents are queried.
     * @param y 
     *              is the y-coordinate of the cell whose contents are queried.
     * @return the boolean value
     */
    private boolean isShark(int x, int y){
        return (this.oceanMatrix[x][y] == Ocean.SHARK);
    }

    /**
     * isSharkStarving() checks the hunger level of shark, if reached to starveTime level
     * @param x
     *              is the x-coordinate of the cell whose contents are queried.
     * @param y 
     *              is the y-coordinate of the cell whose contents are queried.
     * @return the boolean value
     */
    private boolean isSharkStarving(int x, int y){
        return (this.sharkHungerLevelMatrix[x][y] == (this.starveTime+1));  
    }


    /**
     * checkFish() checks the existence of atleast one fish 
     * surrounding shark cell
     * @param x
     *          is the x-coordinate of the cell whose contents are queried.
     * @param y
     *          is the y-coordinate of the cell whose contents are queried.
     * @return returns true on atleast one fish exist otherwise false
     * 
     */
    private boolean checkFish(int x, int y){
        for(int i = x-1;i <= x+1; i++){
            for(int j = y-1; j <= y+1; j++){
                if(this.isFish(mod(i,this.height), mod(j,this.width))){     
                    return true;

                }
            }
        }
        return false;
    }

    /**
     * countShark() counts the number of sharks surrounding queried cell
     * @param x
     *          is the x-coordinate of the cell whose contents are queried.
     * @param y
     *          is the y-coordinate of the cell whose contents are queried.
     * @return returns number of sharks surrounding fish cell
     */

    private int countShark(int x, int y){
        int neighbourSharkCount = 0;
        for(int i = x-1;i <= x+1; i++){
            for(int j = y-1; j <= y+1; j++){
                if(this.isShark(mod(i,this.height), mod(j,this.width))){
                    neighbourSharkCount++;
                }
            } // end inner for loop
        }//end outer for loop
        return neighbourSharkCount;
    }

    /**
     * countFish() counts the number of fish surrounding queried cell
     * @param x
     *          is the x-coordinate of the cell whose contents are queried.
     * @param y
     *          is the y-coordinate of the cell whose contents are queried.
     * @return returns number of sharks surrounding queried cell
     */

    private int countFish(int x, int y){
        int neighbourFishCount = 0;
        for(int i = x-1;i <= x+1; i++){
            for(int j = y-1; j <= y+1; j++){
                if(this.isFish(mod(i,this.height), mod(j,this.width))){
                    neighbourFishCount++;
                }
            } // end inner for loop
        }//end outer for loop
        return neighbourFishCount;
    }


    /**
     * mod() performs the modulo operation using euclidean divison
     * 
     * @param n
     *            is the numerator
     * @param d
     *            is the denominator
     * @return the remainder
     */

    private int mod(int n, int d) {
        if (n >= 0)
            return n % d;
        else
            return d + ~(~n % d);
    }

    /**
     * timeStep() performs a simulation timestep as described in README.
     * 
     * @return an ocean representing the elapse of one timestep.
     */
    public Ocean timeStep() {

        Ocean sea = new Ocean(width, height, starveTime);

        for (int row = 0; row < this.height; row++) {
            for (int col = 0; col < this.width; col++) {

                        switch(this.oceanMatrix[row][col]){

                        case Ocean.SHARK: 
                            boolean gotTheFish = false;
                            //Check all the 8 neighbors of a Shark Cell for fish
                            if(this.checkFish(row,col)){
                                gotTheFish = true;
                            }

                            //Updating Shark Cell
                            if(gotTheFish){
                                /*
                                 * 1) If a cell contains a shark, and any of its neighbors is a fish, then the
                                 * shark eats during the time step, and it remains in the cell at the end of the
                                 * time step.  (We may have multiple sharks sharing the same fish.  This is fine;
                                 * they all get enough to eat.)
                                 */
                                sea.oceanMatrix[row][col] = Ocean.SHARK; // for next time step
                            }else{
                                /*
                                 * 2) If a cell contains a shark, and none of its neighbors is a fish, it gets
                                 * hungrier during the time step.  If this time step is the (starveTime + 1)th
                                 * time step the shark has gone through without eating, then the shark dies
                                 * (disappears).  Otherwise, it remains in the cell.
                                 */
                                this.sharkHungerLevelMatrix[row][col]++;
                                if(this.isSharkStarving(row,col)){
                                    this.oceanMatrix[row][col] = Ocean.EMPTY; // for this time step
                                    this.sharkHungerLevelMatrix[row][col] = Ocean.EMPTY; // for this time step
                                }

                                sea.sharkHungerLevelMatrix[row][col] = this.sharkHungerLevelMatrix[row][col]; // for next time step
                                sea.oceanMatrix[row][col] = this.oceanMatrix[row][col]; // for next time step
                            }


                            break;

                        case Ocean.FISH:
                            int neighbourSharkCount=0;

                            //Check all the 8 neighbors of a Fish cell to count for sharks
                            neighbourSharkCount=countShark(row,col);

                            //Updating fish cell for current & next  time step
                            if(neighbourSharkCount ==1){
                                /*
                                 * 4) If a cell contains a fish, and one of its neighbors is a shark, then the
                                 * fish is eaten by a shark, and therefore disappears.
                                 */
                                this.oceanMatrix[row][col] = Ocean.EMPTY; //fish disappears this time step
                            }
                            else if(neighbourSharkCount  > 1){
                                /*
                                 * 5) If a cell contains a fish, and two or more of its neighbors are sharks, then
                                 * a new shark is born in that cell. Sharks are well-fed at birth; _after_ they
                                 * are born, they can survive an additional starveTime time steps without eating.
                                 */
                                sea.oceanMatrix[row][col] = Ocean.SHARK; // new shark for next time step
                            }
                            else if(neighbourSharkCount  < 1){
                                /*
                                 * 3) If a cell contains a fish, and all of its neighbors are either empty or are
                                 * other fish, then the fish stays where it is.
                                 */
                                sea.oceanMatrix[row][col] = FISH; //for next time step
                            }
                            break; 

                        case Ocean.EMPTY:
                            int fishCount=0;
                            int sharkCount=0;

                            //Check all the 8 neighbors of an Empty cell to count sharks and Fish
                            fishCount = this.countFish(row,col);
                            sharkCount = this.countShark(row, col);

                            //Update Empty Cell for current & next time step.

                            /* (no need to handle this case)
                             * 6) If a cell is empty, and fewer than two of its neighbors are fish, then the
                             * cell remains empty.
                             */

                            if((fishCount >= 2) && (sharkCount <=1)){
                                /*
                                 * 7) If a cell is empty, at least two of its neighbors are fish, and at most one
                                 * of its neighbors is a shark, then a new fish is born in that cell.
                                 */
                                this.oceanMatrix[row][col] = FISH;// for current time step 
                                sea.oceanMatrix[row][col] = FISH; //for next time step
                            }else if((fishCount >= 2) && (sharkCount >= 2)){
                                /*
                                 * 8) If a cell is empty, at least two of its neighbors are fish, and at least two
                                 * of its neighbors are sharks, then a new shark is born in that cell. (The new
                                 * shark is well-fed at birth, even though it hasn’t eaten a fish yet.)
                                 */
                                sea.oceanMatrix[row][col] = Ocean.SHARK; // for next time step
                            }
                            break;
                        }
            }//end inner for loop
        }//end outer for loop
        return sea;
    }

    /**
     * The following method is required for Part II.
     * 
     * 
     */
    /**
     * addShark() (with three parameters) places a shark in cell (x, y) if the
     * cell is empty. The shark's hunger is represented by the third parameter.
     * If the cell is already occupied, leave the cell as it is, You will need
     * this method to help convert run-length encodings to Oceans.
     * 
     * @param x
     *            is the x-coordinate of the cell to place a shark in.
     * @param y
     *            is the y-coordinate of the cell to place a shark in.
     * @param feeding
     *            is an integer that indicates the shark's hunger. You may
     *            encode it any way you want; for instance, "feeding" may be the
     *            last timestep the shark was fed, or the amount of time that
     *            has passed since the shark was last fed, or the amount of time
     *            left before the shark will starve. It's upto you, but be
     *            consistent.
     */

    public void addShark(int x, int y, int feeding) {
        this.oceanMatrix[x][y] = Ocean.SHARK;
        this.sharkHungerLevelMatrix[x][y] = feeding;
    }

    /**
     * The following method is required for Part III.
     */

    /**
     * sharkFeeding() returns an integer that indicates the hunger of the shark
     * in cell (x, y), using the same "feeding" representation as the parameter
     * to addShark() described above. If cell (x, y) does not contain a shark,
     * then its return value is undefined--that is, anything you want. Normally,
     * this method should not be called if cell (x, y) does not contain a shark.
     * You will need this method to help convert Oceans to run-length encodings.
     * 
     * @param x
     *            is the x-coordinate of the cell whose contents are queried.
     * @param y
     *            is the y-coordinate of the cell whose contents are queried.
     * 
     */
    public int sharkFeeding(int x, int y) {
        if(this.isShark(x, y)){
            return this.sharkHungerLevelMatrix[x][y];
        }
        return Ocean.UNKNOWN;

    }
}

2 个答案:

答案 0 :(得分:6)

虽然这不是不是 Swing程序,但您可以将JFrame替换为Frame以利用EXIT_ON_CLOSE

JFrame frame = new JFrame("Sharks and Fish");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

AWT方法是添加WindowListener

frame.addWindowListener(new WindowAdapter() {

    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
});

答案 1 :(得分:1)

你试过吗?

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);