Java – click the close x button to close the frame

I have got the answer through link1 and link2, but it doesn't help

because

frame.setVisible(false);

The following exceptions are given,

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

The application has less than 2 java files

Simulation class starts GUI

Run simulation. After using the default command line parameters After Java, the frame will not close despite the limited while loop After the simulation is complete, I cannot close the frame by clicking the close button (upper right corner – red)

Do I need to set some properties for the frame?

Please help me!!!

/* 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);
                    }else{
                        //Clear the rectangle
                        graphics.clearRect(row,col,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 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.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.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,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;

    }
}

Solution

Although this is not a swing program, you can replace JFrame with frame to take advantage of exit_ ON_ CLOSE.

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

The AWT method is to add a windowlistener

frame.addWindowListener(new WindowAdapter() {

    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }
});
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>