Question

Am getting a java.lang.NullPointerException on an array I have initialized and I can't quite figure it out what am doing wrong. The error is occuring at line 371.

Below is the code of the parent class followed by the class initializng the letterArray ArrayList:

package wordsearch;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Line2D;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;

/**
 *  Main class of Puzzle Program
 * @author mungaialex
 *
 */
public class WordSearchPuzzle extends JFrame {

    private static final long serialVersionUID = 1L;

    /** No. Of Columns in Wordlist*/
    private static final int WORDLISTCOLS = 1;

    static JButton[][] grid; //names the grid of buttons
    GridLayout myGridLayout = new GridLayout(1,2,3,3);

    /**Array to hold wordList*/
    ArrayList<String> wordList;

    JButton btnCheck, btnClear;

    /** Panel to hold Components to the left*/
    JPanel leftSidePanel;
    /** Panel to hold components to the right*/
    JPanel rightSidePanel;
    /**Panel to hold word List*/
    JPanel wordListPanel;
    /**Panel to hold grid buttons*/
    JPanel gridPanel;
    /**Panel to hold clear button and check button*/
    JPanel buttonsPanel;
    /**Panel to hold output textarea*/
    JPanel bottomPanel;

    private JLabel[] wordListComponents;

    @SuppressWarnings("rawtypes")
    List puzzleLines;

    //Grid Size
    private final int ROWS = 20;
    private final int COLS = 20;

    /** Output Area of system*/
    private JTextArea txtOutput;
    /**Scrollpane for Output area*/
    private JScrollPane scptxtOutput;

    private Object[] theWords;
    public String wordFromChars = new String();
    /** the matrix of the letters */
    private char[][] letterArray = null;

    /**
     * Constructor for WordSearchPuzzle
     * @param wordListFile File Containing words to Search for
     * @param wordSearhPuzzleFile File Containing the puzzle
     */
    public WordSearchPuzzle(String wordSearchFile,String wordsListFile) throws IOException {
        FileIO io = new FileIO(wordSearchFile,wordsListFile,grid);

        wordList = io.loadWordList();
        theWords = wordList.toArray();

        addComponentsToPane();
        buildWordListPanel();
        buildBottomPanel();

        io.loadPuzleFromFile();

        //Override System.out
        PrintStream stream = new PrintStream(System.out) {
            @Override
            public void print(String s) {
                txtOutput.append(s + "\n");
                txtOutput.setCaretPosition(txtOutput.getText().length());               
            }
        };
        System.setOut(stream);
        System.out.print("MESSAGES");
    }

    /**
     * Constructor two
     */

    public WordSearchPuzzle() {
    }

    /**
     * Gets the whole word of buttons clicked
     * @return
     *      Returns whole Word
     */
    public String getSelectedWord() {
        return wordFromChars;
    }

    /**
     * Adds word lists to Panel on the left
     */
    private void buildWordListPanel() {

        leftSidePanel.setBackground(Color.WHITE);

        // Build the word list
        wordListComponents = new JLabel[wordList.size()];

        wordListPanel = new JPanel(new GridLayout(25, 1));
        wordListPanel.setBackground(Color.white);

        //Loop  through list of words
        for (int i = 0; i < this.wordList.size(); i++) {

            String word = this.wordList.get(i).toUpperCase();
            wordListComponents[i] = new JLabel(word);
            wordListComponents[i].setForeground(Color.BLUE);
            wordListComponents[i].setHorizontalAlignment(SwingConstants.LEFT);
            wordListPanel.add(wordListComponents[i]);

        }

        leftSidePanel.add(wordListPanel,BorderLayout.WEST);
    }

    /**
     * Adds an output area to the bottom of 
     */
    private void buildBottomPanel() {

        bottomPanel = new JPanel();
        bottomPanel.setLayout(new BorderLayout());

        txtOutput = new JTextArea();
        txtOutput.setEditable(false);
        txtOutput.setRows(5);

        scptxtOutput = new JScrollPane(txtOutput);

        bottomPanel.add(txtOutput,BorderLayout.CENTER);
        bottomPanel.add(scptxtOutput,BorderLayout.SOUTH);
        rightSidePanel.add(bottomPanel,BorderLayout.CENTER);
    }

    /**
     * Initialize Components
     */

    public  void addComponentsToPane() {

        //      buttonsPanel = new JPanel(new BorderLayout(3,5)); //Panel to hold Buttons
        buttonsPanel = new JPanel(new GridLayout(3,1));

        leftSidePanel = new JPanel(new BorderLayout());

        rightSidePanel = new JPanel(new BorderLayout());

        btnCheck = new JButton("Check Word");
        btnCheck.setActionCommand("Check");
        btnCheck.addActionListener(new ButtonClickListener());

        btnClear = new JButton("Clear Selection");
        btnClear.setActionCommand("Clear");
        btnClear.addActionListener(new ButtonClickListener());

        buttonsPanel.add(btnClear);//,BorderLayout.PAGE_START);
        buttonsPanel.add(btnCheck);//,BorderLayout.PAGE_END);

        leftSidePanel.add(buttonsPanel,BorderLayout.SOUTH);
        this.getContentPane().add(leftSidePanel,BorderLayout.LINE_START);

        gridPanel = new JPanel();
        gridPanel.setLayout(myGridLayout);

        myGridLayout.setRows(20);
        myGridLayout.setColumns(20);

        grid = new JButton[ROWS][COLS]; //allocate the size of grid
        //theBoard = new char[ROWS][COLS];

        for(int Row = 0; Row < grid.length; Row++){
            for(int Column = 0; Column < grid[Row].length; Column++){

                grid[Row][Column] = new JButton();//Row + 1 +", " + (Column + 1));

                grid[Row][Column].setActionCommand(Row + "," + Column);

                grid[Row][Column].setActionCommand("gridButton");

                grid[Row][Column].addActionListener(new ButtonClickListener());

                gridPanel.add(grid[Row][Column]);
            }
        }

        rightSidePanel.add(gridPanel,BorderLayout.NORTH);
        this.getContentPane().add(rightSidePanel, BorderLayout.CENTER);
    }

    public static void main(String[] args)  {
        try {
            if (args.length !=2) { //Make sure we have both the puzzle file and word list file
                JOptionPane.showMessageDialog(null, "One or All Files are Missing");
            } else { //Files Found
                WordSearchPuzzle puzzle = new WordSearchPuzzle(args[0],args[1]);
                puzzle.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                puzzle.setSize(new Dimension(1215,740));

                //Display the window.
                puzzle.setLocationRelativeTo(null); // Center frame on screen
                puzzle.setResizable(false); //Set the form as not resizable
                puzzle.setVisible(true);    
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
    }

    public int solvePuzzle( ){
        int matches = 0;
        for( int r = 0; r < ROWS; r++ )
            for( int c = 0; c < COLS; c++ )
                for( int rd = -1; rd <= 1; rd++ )
                    for( int cd = -1; cd <= 1; cd++ )
                        if( rd != 0 || cd != 0 )
                            matches += solveDirection( r, c, rd, cd );
        return matches;
    }

    private int solveDirection( int baseRow, int baseCol, int rowDelta, int colDelta ){
        String charSequence = "";
        int numMatches = 0;
        int searchResult;

        FileIO io = new FileIO();

        charSequence += io.theBoard[ baseRow ][ baseCol ];
        for( int i = baseRow + rowDelta, j = baseCol + colDelta;
                i >= 0 && j >= 0 && i < ROWS && j < COLS;
                i += rowDelta, j += colDelta )
        {
            charSequence += io.theBoard[ i ][ j ];
            searchResult = prefixSearch( theWords, charSequence );
            if( searchResult == theWords.length )
                break;
            if( !((String)theWords[ searchResult ]).startsWith( charSequence ) )
                break;
            if( theWords[ searchResult ].equals( charSequence ) )
            {
                numMatches++;
                System.out.println( "Found " + charSequence + " at " +
                        baseRow + " " + baseCol + " to " +
                        i + " " + j );
            }
        }
        return numMatches;
    }

    private static int prefixSearch( Object [ ] a, String x ) {
        int idx = Arrays.binarySearch( a, x );
        if( idx < 0 )
            return -idx - 1;
        else
            return idx;
    }

    class ButtonClickListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {

            String command = ((JButton)e.getSource()).getActionCommand();
            if (command == "Clear") {
                //Enable the buttons that have been disabled and not form a whole word
                //JOptionPane.showMessageDialog(null, "Cooming Soon");

                for (String word : wordList) {
                    System.out.print(word);
                }

            } else if (command == "Check") {

                String selectedWord = getSelectedWord();

                if (!selectedWord.equals("")){

                    System.out.print("Selected word is " + getSelectedWord());
                    //First check if selected word exits in wordList

                    if (ifExists(selectedWord)) {
                        if(searchWord(selectedWord)){
                            JOptionPane.showMessageDialog(null, "Success");
                            wordFromChars = ""; //Reset the selected Word
                        }
                    } else {
                        JOptionPane.showMessageDialog(null, "[" + selectedWord + "] " +
                                "Does Not Belong to Word list");
                        wordFromChars = ""; //Reset the selected Word
                    }

                } else {

                    JOptionPane.showMessageDialog(null, "No Buttons on Grid have been clicked");

                }
            } else if (command == "gridButton") {
                getSelectedCharacter(e);
                ((JButton)e.getSource()).setEnabled(false);         
            }
        }

        /**
         * Gets the character of each button and concatenates each character to form a whole word
         * @param e     The button that received the Click Event
         * @return      Whole word 
         */
        private String getSelectedCharacter (ActionEvent e) {
            String character; 

            character = ((JButton) e.getSource()).getText();

            wordFromChars = wordFromChars + character;

            return wordFromChars;
        }       
    }
    /**
     * Checks if selected word is among in wordlist
     * @param selectedWord
     * @return      The word to search for
     */
    private boolean ifExists(String selectedWord) {
        if (wordList.contains(selectedWord)) {
            return true;
        }
        return false;
    }

    public boolean searchWord(String word) {
        if (!wordList.contains(word)) {
            return false;
        }
        //int index = wordList.indexOf(word);
        Line2D.Double line = new Line2D.Double();
        //System.out.print("LetterArray is " + letterArray.length);
        for (int x = 0; x < letterArray.length; x++) {
            for (int y = 0; y < letterArray[x].length; y++) {
                // save start point
                line.x1 = y; // (y + 1) * SCALE_INDEX_TO_XY;
                line.y1 = x; // (x + 1) * SCALE_INDEX_TO_XY;
                int pos = 0; // current letter position
                if (letterArray[x][y] == word.charAt(pos)) {
                    // first letter correct -> check next
                    pos++;
                    if (pos >= word.length()) {
                        // word is only one letter long
                        // double abit = SCALE_INDEX_TO_XY / 3;
                        line.x2 = y; // (y + 1) * SCALE_INDEX_TO_XY + abit;
                        line.y2 = x; // (x + 1) * SCALE_INDEX_TO_XY + abit;
                        return true;
                    }
                    // prove surrounding letters:
                    int[] dirX = { 1, 1, 0, -1, -1, -1, 0, 1 };
                    int[] dirY = { 0, -1, -1, -1, 0, 1, 1, 1 };

                    for (int d = 0; d < dirX.length; d++) {
                        int dx = dirX[d];
                        int dy = dirY[d];

                        int cx = x + dx;
                        int cy = y + dy;

                        pos = 1; // may be greater if already search in another
                        // direction from this point
                        if (insideArray(cx, cy)) {
                            if (letterArray[cx][cy] == word.charAt(pos)) {
                                // 2 letters correct
                                // -> we've got the direction
                                pos++;
                                cx += dx;
                                cy += dy;
                                while (pos < word.length() && insideArray(cx, cy)
                                        && letterArray[cx][cy] == word.charAt(pos)) {
                                    pos++;
                                    cx += dx;
                                    cy += dy;
                                }

                                if (pos == word.length()) {
                                    // correct end if found
                                    cx -= dx;
                                    cy -= dy;
                                    pos--;
                                }
                                if (insideArray(cx, cy) && letterArray[cx][cy] == word.charAt(pos)) {
                                    // we've got the end point
                                    line.x2 = cy; // (cy + 1) *
                                    // SCALE_INDEX_TO_XY;
                                    line.y2 = cx; // (cx + 1) *
                                    // SCALE_INDEX_TO_XY;
                                    /*
                                     * System.out.println(letterArray[x][y] +
                                     * " == " + word.charAt(0) + " (" + line.x1
                                     * + "," + line.y1 + ") ->" + " (" + line.x2
                                     * + "," + line.y2 + "); " + " [" + (line.x1
                                     * / SCALE_INDEX_TO_XY) + "," + (line.y1 /
                                     * SCALE_INDEX_TO_XY) + "] ->" + " [" +
                                     * (line.x2 / SCALE_INDEX_TO_XY) + "." +
                                     * (line.y2 / SCALE_INDEX_TO_XY) + "]; ");
                                     */

                                    //result[index] = line;
                                    // found
                                    return true;
                                }
                                // else: try next occurence
                            }
                        }

                    }

                }
            }
        }
        return false;
    }

    private boolean insideArray(int x, int y) {
        boolean insideX = (x >= 0 && x < letterArray.length);
        boolean insideY = (y >= 0 && y < letterArray[0].length);
        return (insideX && insideY);
    }

    public void init(char[][] letterArray) {
        try {
            for (int i = 0; i < letterArray.length; i++) {
                for (int j = 0; j < letterArray[i].length; j++) {
                    char ch = letterArray[i][j];
                    if (ch >= 'a' && ch <= 'z') {
                        letterArray[i][j] = Character.toUpperCase(ch);
                    }
                }
            }   
        } catch (Exception e){
            System.out.println(e.toString());
        }

        //System.out.println("It is " + letterArray.length);
        this.letterArray = letterArray;
    }
}

Here is class initializing the letterArray array:

package wordsearch;

import java.awt.Color;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.SwingConstants;

/**
 * Reads wordlist file and puzzle file
 * @author mungaialex
 *
 */

public class FileIO {

    String _puzzleFile, _wordListFile;
    /**ArrayList to hold words*/
    ArrayList<String> wordList;
    /** No. Of Columns in Wordlist*/
    private static final int WORDLISTCOLS = 1;
    List puzzleLines;
    JButton[][] _grid;

    char theBoard[][];

    private final int _rows = 20;
    private final int _columns = 20;

    WordSearchPuzzle pz = new WordSearchPuzzle();
    /**
     * Default Constructor
     * @param puzzleFile
     * @param wordListFile
     */

    public FileIO(String puzzleFile, String wordListFile,JButton grid[][]){
        _puzzleFile = new String(puzzleFile);
        _wordListFile = new String(wordListFile);
        _grid = pz.grid;
    }

    public FileIO() {
    }

    /**
     * Reads word in the wordlist file and adds them to an array
     * @param wordListFilename
     *      File Containing Words to Search For
     * @throws IOException
     */

    protected ArrayList<String> loadWordList()throws IOException {
        int row = 0;

        wordList = new ArrayList<String>();
        BufferedReader reader = new BufferedReader(new FileReader(_wordListFile));

        String line = reader.readLine();
        while (line != null) {
            StringTokenizer tokenizer = new StringTokenizer(line, " ");
            if (tokenizer.countTokens() != WORDLISTCOLS) {
                JOptionPane.showMessageDialog(null, "Error: only one word per line allowed in the word list",
                        "WordSearch Puzzle: Invalid Format", row);//, JOptionPane.OK_CANCEL_OPTION);
                //"Error: only one word per line allowed in the word list");
            }
            String tok = tokenizer.nextToken();
            wordList.add(tok.toUpperCase());
            line = reader.readLine();
            row++;
        }
        reader.close();
        return wordList;
    }
    /**
     * Reads the puzzle file line by by line
     * @param wordSearchFilename
     *      The file containing the puzzle
     * @throws IOException
     */
    protected void loadPuzleFromFile() throws IOException {
        int row = 0;
        BufferedReader reader = new BufferedReader(new FileReader(_puzzleFile));
        StringBuffer sb = new StringBuffer();
        String line = reader.readLine();

        puzzleLines = new ArrayList<String>();

        while (line != null) {
            StringTokenizer tokenizer = new StringTokenizer(line, " ");
            int col = 0;

            sb.append(line);
            sb.append('\n');

            while (tokenizer.hasMoreTokens()) {
                String tok = tokenizer.nextToken();

                WordSearchPuzzle.grid[row][col].setText(tok);

                pz.grid[row][col].setForeground(Color.BLACK);

                pz.grid[row][col].setHorizontalAlignment(SwingConstants.CENTER);

                puzzleLines.add(tok);
                col++;
            }
            line = reader.readLine();
            row++;

            theBoard = new char[_rows][_columns];
            Iterator itr = puzzleLines.iterator();

            for( int r = 0; r < _rows; r++ )
            {
                String theLine = (String) itr.next( );
                theBoard[ r ] = theLine.toUpperCase().toCharArray( );
            }
        }

        String[] search = sb.toString().split("\n");

        initLetterArray(search);

        reader.close();
    }

    protected void initLetterArray(String[] letterLines) {
        char[][] array = new char[letterLines.length][];
        System.out.print("Letter Lines are " +letterLines.length );
        for (int i = 0; i < letterLines.length; i++) {
            letterLines[i] = letterLines[i].replace(" ", "").toUpperCase();
            array[i] = letterLines[i].toCharArray();
        }
        System.out.print("Array inatoshana ivi " + array.length);
        pz.init(array); 
    }

}

Thanks in advance.

Was it helpful?

Solution

Here it is!

char[][] array = new char[letterLines.length][];

You are only initializing one axis. When you pass this array to init() and set this.letterArray = letterArray;, the letterArray is also not fully initialized.

Try adding a length to both axes:

char[][] array = new char[letterLines.length][LENGTH];

OTHER TIPS

first you will handle the NullPoinetrException , the code is

if( letterArray != null){
        for (int x = 0; x < letterArray.length; x++)
        {
         ..........
          ............
         }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top