I've been working on a version of Conway's Game of Life for about a week now.  It has loads of features like drawing onto the screen and saving/loading images. The problem is that ever since I added mouse support, it seems to start running pretty slowly.  I don't know if it is due to the mouse or if it's something else. I'm a pretty newbie coder so I'd really like some help in optimizing this.Just noting: I didn't include any imports due to the character limit.Main Classpublic class MainGame extends JFrame{        static int size = 721;    static JFrame frame = new JFrame(Game of Life);    static Life life = new Life(size);    Random r = new Random();    JLabel lblCellCount = new JLabel(Cell Count);    JLabel lblGeneration = new JLabel(Generation);    JSlider slider = new JSlider();    JButton play = new JButton(Pause);    JLabel lblSpeed = new JLabel(Speed: (10) ups);    public SaveLoad sl = new SaveLoad();    String[] patterns = sl.loadImages(new File(.\\Patterns\\));    final JFileChooser fc = new JFileChooser();    final DefaultComboBoxModel model;    final JComboBox<?> cmboPatterns;    Point start;    public void runGameLoop(){        life.running = true;        Thread loop = new Thread() {            public void run(){                gameLoop();            }        };        loop.start();    }    public void gameLoop(){        System.out.println(Started);        final int MAX_UPDATES_BEFORE_RENDER = 5;        double lastUpdateTime = System.nanoTime();        double lastRenderTime = System.nanoTime();        int lastSecondTime = (int) (lastUpdateTime / 1000000000);        while(life.running){            final double GAME_HERTZ = (double) slider.getValue();            final double TIME_BETWEEN_UPDATES = 1000000000 / GAME_HERTZ;            final double TARGET_FPS = (int) GAME_HERTZ;            final double TARGET_TIME_BETWEEN_RENDERS = 1000000000 / TARGET_FPS;            double now = System.nanoTime();            int updateCount = 0;            if (!life.paused){                while(now - lastUpdateTime > TIME_BETWEEN_UPDATES && updateCount < MAX_UPDATES_BEFORE_RENDER){                    // update activeCells here                    changeText(life.countCells());                    changeText(life.generation, true);                    life.checkCells();                    lastUpdateTime += TIME_BETWEEN_UPDATES;                    updateCount++;                }                if (now - lastUpdateTime > TIME_BETWEEN_UPDATES){                    lastUpdateTime = now - TIME_BETWEEN_UPDATES;                }                // render to screen here                life.fillCells(life.activeCells);                lastRenderTime = now;                int thisSecond = (int) (lastUpdateTime / 1000000000);                if (thisSecond > lastSecondTime){                    lastSecondTime = thisSecond;                }                while(now - lastRenderTime < TARGET_TIME_BETWEEN_RENDERS && now - lastUpdateTime < TIME_BETWEEN_UPDATES){                    Thread.yield();                    try{                        Thread.sleep(1);                    } catch(Exception e){                    }                    now = System.nanoTime();                }            }        }        // System.out.println(Generations  + generation);        //Thread.yield();    }    public static void main(String[] args){        try{            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());        } catch(Throwable e){            e.printStackTrace();        }        EventQueue.invokeLater(new Runnable() {            public void run(){                try{                    MainGame frame = new MainGame();                    frame.setVisible(true);                    frame.setResizable(false);                } catch(Exception e){                    e.printStackTrace();                }            }        });    }    public void changeText(int cells){        lblCellCount.setText(Live Cells:  + String.valueOf(cells));    }    public void changeText(int generation, boolean gen){        lblGeneration.setText(Generation:  + String.valueOf(generation));    }    @SuppressWarnings({rawtypes, unchecked})    public MainGame(){        pack();        setTitle(Game Of Life);        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        getContentPane().setLayout(null);        addMouseMotionListener(new MouseMotionListener() {            @Override            public void mouseDragged(MouseEvent e){                int xCell = (e.getX() - getInsets().left) / life.CELL_SIZE;                int yCell = (e.getY() - getInsets().top) / life.CELL_SIZE;                if (life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && xCell >= 0 && yCell >= 0 && !life.activeCells[xCell][yCell] && !SwingUtilities.isRightMouseButton(e)){                    //life.fillCell(xCell, yCell, 0 - r.nextInt(16777215));                    life.fillLine((int) (start.getX() - getInsets().left) / life.CELL_SIZE, (int) (start.getY() - getInsets().top) / life.CELL_SIZE, (int) (e.getPoint().getX() - getInsets().left) / life.CELL_SIZE, (int) (e.getPoint().getY() - getInsets().top) / life.CELL_SIZE, 0 - r.nextInt(16777215));                    start = e.getPoint();                    changeText(life.countCells());                } else if (!life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && xCell >= 0 && yCell >= 0 && !life.activeCells[xCell][yCell] && !SwingUtilities.isRightMouseButton(e)){                    //life.fillCell(xCell, yCell, -16777215);                    life.fillLine((int) (start.getX() - getInsets().left) / life.CELL_SIZE, (int) (start.getY() - getInsets().top) / life.CELL_SIZE, (int) (e.getPoint().getX() - getInsets().left) / life.CELL_SIZE, (int) (e.getPoint().getY() - getInsets().top) / life.CELL_SIZE, -16777215);                    start = e.getPoint();                    //System.out.println(main x  + (e.getPoint().getX() - getInsets().left) / life.CELL_SIZE +  main y  + (e.getPoint().getY() - getInsets().top) / life.CELL_SIZE);                    changeText(life.countCells());                } else if (life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && SwingUtilities.isRightMouseButton(e)){                    //life.emptyCell(xCell, yCell);                    life.emptyLine((int) (start.getX() - getInsets().left) / life.CELL_SIZE, (int) (start.getY() - getInsets().top) / life.CELL_SIZE, (int) (e.getPoint().getX() - getInsets().left) / life.CELL_SIZE, (int) (e.getPoint().getY() - getInsets().top) / life.CELL_SIZE);                    start = e.getPoint();                    changeText(life.countCells());                } else if (!life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && SwingUtilities.isRightMouseButton(e)){                    //life.emptyCell(xCell, yCell);                    life.emptyLine((int) (start.getX() - getInsets().left) / life.CELL_SIZE, (int) (start.getY() - getInsets().top) / life.CELL_SIZE, (int) (e.getPoint().getX() - getInsets().left) / life.CELL_SIZE, (int) (e.getPoint().getY() - getInsets().top) / life.CELL_SIZE);                    start = e.getPoint();                    changeText(life.countCells());                }            }            @Override            public void mouseMoved(MouseEvent e){            }        });        addMouseListener(new MouseListener() {            @Override            public void mouseClicked(MouseEvent e){            }            @Override            public void mouseEntered(MouseEvent e){            }            @Override            public void mouseExited(MouseEvent e){            }            @Override            public void mousePressed(MouseEvent e){                int xCell = (e.getX() - getInsets().left) / life.CELL_SIZE;                int yCell = (e.getY() - getInsets().top) / life.CELL_SIZE;                if (life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && !SwingUtilities.isRightMouseButton(e)){                    life.fillCell(xCell, yCell, 0 - r.nextInt(16777215));                    start = e.getPoint();                    changeText(life.countCells());                } else if (!life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && !SwingUtilities.isRightMouseButton(e)){                    life.fillCell(xCell, yCell, -16777215);                    start = e.getPoint();                    changeText(life.countCells());                } else if (life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && SwingUtilities.isRightMouseButton(e)){                    life.emptyCell(xCell, yCell);                    start = e.getPoint();                    changeText(life.countCells());                } else if (!life.colour && xCell < life.activeCells.length && yCell < life.activeCells.length && SwingUtilities.isRightMouseButton(e)){                    life.emptyCell(xCell, yCell);                    start = e.getPoint();                    changeText(life.countCells());                }            }            @Override            public void mouseReleased(MouseEvent e){            }        });        life.setBounds(0, 0, size, size);        getContentPane().add(life);        JPanel customisePanel = new JPanel();        customisePanel.setBounds(0, size, size, 35);        getContentPane().add(customisePanel);        customisePanel.setLayout(null);        final JButton stop = new JButton(Restart);        stop.setBounds(8, 8, 75, 23);        stop.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent e){                life.reset();                //life.generation = 0;                changeText(life.countCells());                changeText(0, true);            }        });        customisePanel.add(stop);        play.setBounds(90, 8, 75, 23);        play.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent arg0){                if (life.running){                    life.running = false;                    play.setText(Play);                    changeText(life.countCells());                } else{                    life.running = true;                    runGameLoop();                    play.setText(Pause);                }            }        });        customisePanel.add(play);        JButton clear = new JButton(Clear);        clear.setBounds(172, 8, 75, 23);        clear.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent e){                life.running = false;                life.generation = 0;                changeText(0, true);                play.setText(Play);                life.cls();                life.cls();                changeText(life.countCells());            }        });        customisePanel.add(clear);        JButton save = new JButton(Save...);        save.setBounds(254, 8, 75, 23);        save.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent e){                fc.setCurrentDirectory(new File(.\\Patterns\\));                life.running = false;                changeText(0, true);                play.setText(Play);                changeText(life.countCells());                int returnVal = fc.showSaveDialog(MainGame.this);                if (returnVal == JFileChooser.APPROVE_OPTION){                    File file = fc.getSelectedFile();                    fc.setCurrentDirectory(file);                    sl.saveImage(life.activeCells, size / life.CELL_SIZE, file);                }                cmboPatterns.removeAllItems();                patterns = sl.loadImages(new File(.\\Patterns\\));                orderStrings();                for (int i = 0; i < patterns.length; i++){                    model.addElement(patterns[i]);                }            }        });        customisePanel.add(save);        // add the colour checkbox        JCheckBox colour = new JCheckBox(Colourful);        colour.setBounds(size - 74, 8, 74, 23);        colour.addItemListener(new ItemListener() {            @Override            public void itemStateChanged(ItemEvent e){                if (e.getStateChange() == ItemEvent.SELECTED){                    life.colourCells();                } else{                    life.deColourCells();                }            }        });        customisePanel.add(colour);        orderStrings();        model = new DefaultComboBoxModel(patterns);        cmboPatterns = new JComboBox<Object>(model);        cmboPatterns.setBounds(size - colour.getWidth() - 210, 9, 120, 22);        cmboPatterns.addActionListener(new ActionListener() {            @Override            public void actionPerformed(ActionEvent e){                for (int i = 0; i < patterns.length; i++){                    if (i == cmboPatterns.getSelectedIndex()){                        life.cls();                        try{                            Thread.sleep(1);                        } catch(InterruptedException e1){                            e1.printStackTrace();                        }                        life.cls();                        life.generation = 0;                        changeText(life.generation, true);                        life.fillCells(sl.loadImage(patterns[i], life.activeCells, size / life.CELL_SIZE));                    }                }            }        });        customisePanel.add(cmboPatterns);        lblCellCount.setBounds(size - colour.getWidth() - 80, 12, 100, 14);        customisePanel.add(lblCellCount);        lblGeneration.setBounds(336, 12, 100, 14);        lblGeneration.addMouseListener(new MouseListener() {            @Override            public void mouseClicked(MouseEvent arg0){            }            @Override            public void mouseEntered(MouseEvent arg0){            }            @Override            public void mouseExited(MouseEvent arg0){            }            @Override            public void mousePressed(MouseEvent arg0){                life.generation = 0;                changeText(0, true);            }            @Override            public void mouseReleased(MouseEvent arg0){            }        });        customisePanel.add(lblGeneration);        JPanel panel = new JPanel();        panel.setLayout(null);        panel.setBounds(0, size + customisePanel.getHeight(), size, 46);        getContentPane().add(panel);        slider.setSnapToTicks(true);        slider.setPaintTicks(true);        slider.setValue(10);        slider.setMinimum(1);        slider.setMaximum(50);        slider.setBounds(0, 0, size, 28);        slider.addChangeListener(new ChangeListener() {            @Override            public void stateChanged(ChangeEvent arg0){                lblSpeed.setText(Speed: ( + String.valueOf(((JSlider) arg0.getSource()).getValue()) + ) ups);                slider.repaint();            }        });        panel.add(slider);        lblSpeed.setHorizontalAlignment(SwingConstants.CENTER);        lblSpeed.setBounds(size / 2 - (80 / 2), 26, 80, 14);        panel.add(lblSpeed);        setBounds(0, 0, size + getInsets().left * 2 - 2, size + panel.getHeight() + customisePanel.getHeight() + 30);        // start the game        runGameLoop();    }    /*     * File.toString() returns a weird filepath so this changes that     * to something i can easily understand and manipulate.     */    public void orderStrings(){        for (int i = 0; i < patterns.length; i++){            if (patterns[i].length() > 2){                if (patterns[i].substring(patterns[i].length() - 4).equals(.png)){                    patterns[i] = patterns[i].substring(0, patterns[i].length() - 4);                }                if (patterns[i].substring(0, 11).equals(.\\Patterns\\)) patterns[i] = patterns[i].substring(11);            }        }    }}Class that handles the actual game panelpublic class Life extends JPanel{    //idk why this is here, eclipse puts it in automatically    private static final long serialVersionUID = 1L;    private BufferedImage canvas;    private Random r = new Random();    private boolean[][] tempArray;    boolean[][] activeCells;    public final int CELL_SIZE = 8;    public int generation = 0;    public int cellCount = 0;    public boolean colour = false;    public boolean running = false;    public boolean paused = false;    /*     * Life Constructor, creates the main image that gets put onto the JPanel     */    public Life(int size){        canvas = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);        fillCanvas(Color.WHITE);        activeCells = new boolean[canvas.getWidth() / CELL_SIZE][canvas.getHeight() / CELL_SIZE];        tempArray = new boolean[canvas.getWidth() / CELL_SIZE][canvas.getHeight() / CELL_SIZE];        activeCells = randArray(activeCells);        //drawGrid(CELL_SIZE, CELL_SIZE);        fillCells(activeCells);        //printArray(activeCells);    }    /*     * Resets the game with a full set of random data     */    public void reset(){        //fillCanvas(Color.WHITE);        activeCells = randArray(activeCells);        generation = 0;        //drawGrid(CELL_SIZE, CELL_SIZE);        fillCells(activeCells);    }    /*     * Uses a temporary version of the activeCells array (tempCells)     * and updates it by checking through the neighbours method.     */    public void checkCells(){        int size = activeCells.length;        boolean[][] tempCells = new boolean[size][size];        for (int i = 0; i < size; i++){            for (int j = 0; j < size; j++){                tempCells[i][j] = activeCells[i][j];            }        }        for (int row = 0; row < activeCells.length; row++){            for (int col = 0; col < activeCells[row].length; col++){                int n = neighbours(row, col);                if (n > 3 || n < 2) tempCells[row][col] = false;                else if (n == 3) tempCells[row][col] = true;                else tempCells[row][col] = activeCells[row][col];            }        }        activeCells = tempCells;        generation++;    }    /*     * Loops through a 3x3 grid around the selected cell (row, col)     * and returns the amount of true cells (no. of neighbours)     */    public int neighbours(int row, int col){        int count = 0;        for (int i = row - 1; i <= row + 1; i++){            for (int j = col - 1; j <= col + 1; j++){                try{                    if (activeCells[i][j] == true && (i != row || j != col)){                        count++;                    }                } catch(ArrayIndexOutOfBoundsException f){                    continue;                }            }        }        return count;    }    /*     * Returns the number of true values in activeCells     */    public int countCells(){        int count = 0;        for (int i = 0; i < activeCells.length; i++){            for (int j = 0; j < activeCells[i].length; j++){                if (activeCells[i][j]) count++;            }        }        cellCount = count;        return count;    }    /*     * Loops through the given array and returns it filled with random data     */    public boolean[][] randArray(boolean[][] array){        for (int i = 0; i < array.length; i++){            for (int j = 0; j < array[i].length; j++){                if (r.nextInt(5) == 1) array[i][j] = true;                else array[i][j] = false;            }        }        return array;    }    /*     * Fills all cells on screen with data from array. Also checks whether to     * colour each cell or not.     */    public void fillCells(boolean[][] array){        for (int i = 0; i < array.length; i++){            for (int j = 0; j < array[i].length; j++){                if (colour && !tempArray[i][j] && array[i][j]) fillCell(i, j, 0 - r.nextInt(16777215));                else if (array[i][j] && !colour) fillCell(i, j, Color.BLACK.getRGB());                else if (!array[i][j]) emptyCell(i, j);                tempArray[i][j] = array[i][j];            }        }    }    //Interpolates between two points because just drawing onto the screen didn't update fast enough    public void fillLine(int x1, int y1, int x2, int y2, int colour){        double m;        if (x2 - x1 == 0){            if (y1 < y2){                for (int i = y1; i < y2; i++){                    fillCell(x2, i, colour);                }            } else{                for (int i = y2; i < y1; i++){                    fillCell(x2, i, colour);                    //System.out.println(xFilling point ( + x2 + ,  + i + ));                }            }        } else{            double dx = x1 - x2;            double dy = y1 - y2;            m = dy / dx;            double c = y1 - (m * x1);            if (x1 < x2 && m >= 1){                for (int i = y1; i < y2; i++){                    double x = (i - c) / m;                    fillCell((int) x, i, colour);                    //System.out.println(Filling point ( + (i) + ,  + (int) x + ). gradient:  + m);                }            } else if (x1 < x2 && m <= 1 && m >=-1){                for (int i = x1; i < x2; i++){                    double y = (i * m) + c;                    fillCell(i, (int) y, colour);                    //System.out.println(Filling point ( + (i) + ,  + (int) y + ). gradient:  + m);                }            } else{                for (int i = y2; i < y1; i++){                    double x = (i - c) / m;                    fillCell((int) x, i, colour);                    //System.out.println(yFilling point ( + (i) + ,  + (int) x + ). gradient:  + m);                }            }                if (y1 < y2 && m <= -1){                    for (int i = y1; i < y2; i++){                        double x = (i - c) / m;                        fillCell((int) x, i, colour);                        //System.out.println(yFilling point ( + (i) + ,  + (int) x + ). gradient:  + m);                    }                } else if (y2 < y1 && m >= 1){                    for (int i = y2; i < y1; i++){                        double x = (i - c) / m;                        fillCell((int) x, i, colour);                        //System.out.println(yFilling point ( + (i) + ,  + (int) x + ). gradient:  + m);                    }                } else{                    for (int i = x2; i < x1; i++){                        double y = (i * m) + c;                        fillCell(i, (int) y, colour);                        //System.out.println(pFilling point ( + (i) + ,  + (int) y + ). gradient:  + m);                    }                }            }        }    /*     * Colours all current active cells     */    public void colourCells(){        for (int i = 0; i < activeCells.length; i++){            for (int j = 0; j < activeCells[i].length; j++){                if (activeCells[i][j]) fillCell(i, j, 0 - r.nextInt(16777215));            }        }        colour = true;    }    /*     * Turns all current active cells black     *      * Could have put both colourCells and deColourCells together in one with a parameter     * but it would have ended up being the same if not more code anyway.     */    public void deColourCells(){        for (int i = 0; i < activeCells.length; i++){            for (int j = 0; j < activeCells[i].length; j++){                if (activeCells[i][j]) fillCell(i, j, -16777215);            }        }        colour = false;    }    /*     * Colours the cell at (x, y) white and makes the correspoding activeCells = false     */    public void emptyCell(int x, int y){        int colour = Color.WHITE.getRGB();        for (int i = 0; i < CELL_SIZE; i++){ //CELL_SIZE-1 for grid            for (int j = 0; j < CELL_SIZE; j++){ //same here                canvas.setRGB(x * CELL_SIZE + 1 + i, y * CELL_SIZE + 1 + j, colour);            }        }        activeCells[x][y] = false;        repaint();    }    /*     * Clears the screen by calling emtpyCell and making activeCells false;     * could probably remove the emptyCell part and just have it paint the     * whole screen white. This was for when i had a grid in aswell.     *      * edit: done     */    public void cls(){        for (int i = 0; i < activeCells.length; i++){            for (int j = 0; j < activeCells[i].length; j++){                activeCells[i][j] = false;                //emptyCell(i, j);            }        }        fillCanvas(Color.WHITE);    }    /*     * Fills the set cell with the set colour     */    public void fillCell(int x, int y, int rgb){        //System.out.println(Color.BLACK.getRGB());        //int colour = Color.BLACK.getRGB();        for (int i = 0; i < CELL_SIZE; i++){ //CELL_SIZE-1 for grid            for (int j = 0; j < CELL_SIZE; j++){ //same here                canvas.setRGB(x * CELL_SIZE + 1 + i, y * CELL_SIZE + 1 + j, rgb);            }        }        activeCells[x][y] = true;        repaint();    }    /*     * Draws a grid onto the screen with the given cell width and height     */    public void drawGrid(int height, int width){        int colour = Color.BLACK.getRGB();        for (int i = 0; i < canvas.getWidth(); i++){            for (int j = 0; j < canvas.getHeight(); j++){                if (j % width == 0) canvas.setRGB(i, j, colour);                if (i % height == 0) canvas.setRGB(i, j, colour);            }        }        repaint();    }    /*     * Sets the size of the JPanel     */    public Dimension getPreferredSize(){        return new Dimension(canvas.getWidth(), canvas.getHeight());    }    /*     * Handles painting to the canvas     */    public void paintComponent(Graphics g){        super.paintComponents(g);        Graphics2D g2 = (Graphics2D) g;        g2.drawImage(canvas, null, null);    }    /*     * Fills the entire canvas with the given colour     */    public void fillCanvas(Color c){        int colour = c.getRGB();        for (int x = 0; x < canvas.getWidth(); x++){            for (int y = 0; y < canvas.getHeight(); y++){                canvas.setRGB(x, y, colour);            }        }        repaint();    }    /*     * Prints the array to the console, for debugging.     */    public void printArray(boolean[][] array){        for (int i = 0; i < array.length; i++){            for (int j = 0; j < array[i].length; j++){                if (array[i][j] == true) System.out.print(1 );                if (array[i][j] == false) System.out.print(0 );            }            System.out.println();        }    }    public void emptyLine(int x1, int y1, int x2, int y2){        double m;        if (x2 - x1 == 0){            if (y1 < y2){                for (int i = y1; i < y2; i++){                    emptyCell(x2, i);                }            } else{                for (int i = y2; i < y1; i++){                    emptyCell(x2, i);                    //System.out.println(Filling point ( + x2 + ,  + i + ));                }            }        } else{            double dx = x1 - x2;            double dy = y1 - y2;            m = dy / dx;            double c = y1 - (m * x1);            if (x1 < x2 && m >= 1){                for (int i = y1; i < y2; i++){                    double x = (i - c) / m;                    emptyCell((int) x, i);                    //System.out.println(yFilling point ( + (i) + ,  + (int) x + ). gradient:  + m);                }            } else if (x1 < x2 && m <= 1 && m >=-1){                for (int i = x1; i < x2; i++){                    double y = (i * m) + c;                    emptyCell(i, (int) y);                    //System.out.println(Filling point ( + (i) + ,  + (int) y + ). gradient:  + m);                }            } else{                for (int i = y2; i < y1; i++){                    double x = (i - c) / m;                    emptyCell((int) x, i);                    //System.out.println(yFilling point ( + (i) + ,  + (int) x + ). gradient:  + m);                }            }                if (y1 < y2 && m <= -1){                    for (int i = y1; i < y2; i++){                        double x = (i - c) / m;                        emptyCell((int) x, i);                        //System.out.println(yFilling point ( + (i) + ,  + (int) x + ). gradient:  + m);                    }                } else if (y2 < y1 && m >= 1){                    for (int i = y2; i < y1; i++){                        double x = (i - c) / m;                        emptyCell((int) x, i);                        //System.out.println(yFilling point ( + (i) + ,  + (int) x + ). gradient:  + m);                    }                } else{                    for (int i = x2; i < x1; i++){                        double y = (i * m) + c;                        emptyCell(i, (int) y);                        //System.out.println(pFilling point ( + (i) + ,  + (int) y + ). gradient:  + m);                    }                }            }    }}Class for handling Saving and loadingpublic class SaveLoad{    private BufferedImage canvas;    private File f;    /*     * Saves the current activeCells array to a png by first     * creating a BufferedImage of the data and then writing     * it to file.     */    public void saveImage(boolean[][] array, int size, File file){        canvas = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);        for (int i = 0; i < size; i++){            for (int j = 0; j < size; j++){                if (array[i][j]) canvas.setRGB(i, j, Color.BLACK.getRGB());                else canvas.setRGB(i, j, Color.WHITE.getRGB());            }        }        try{            File outputFile = new File(file.toString() + .png);            ImageIO.write(canvas, png, outputFile);            System.out.println(file.toString() + .png Save Successfully!);        } catch(IOException e){            System.out.println(Something went wrong...);        }    }    /*     * Returns all pngs found in the current directory in the     * format of an array of Strings     */    public String[] loadImages(File dir){        String[] files;        File[] all = dir.listFiles();        int pngs = 0;        for (int i = 0; i < all.length; i++){            if (all[i].toString().indexOf(.png) != -1){                pngs++;            }        }        files = new String[pngs];        pngs = 0;        for (int i = 0; i < all.length; i++){            if (all[i].toString().indexOf(.png) != -1){                files[pngs] = all[i].toString();                pngs++;            }        }        return files;    }    /*     * Converts a png into a 2d array of booleans which can then     * be used to fill cells on the screen.     */    public boolean[][] loadImage(String file, boolean[][] array, int size){        f = new File(.\\Patterns\\ + file + .png);        try{            canvas = ImageIO.read(f);        } catch(IOException e){            // TODO Auto-generated catch block            e.printStackTrace();        }        for (int i = 0; i < size; i++){            for (int j = 0; j < size; j++){                if (canvas.getRGB(i, j) == Color.BLACK.getRGB()) array[i][j] = true;            }        }        return array;    }}Sorry for including all of my code, but it's because I don't really know where the problem lies, and it could be all over.
Game Of Life optimization in Java
java;optimization;beginner;game of life