2014-01-28 2 views
0

Am get a java.lang.NullPointerException в массиве, который я инициализировал, и я не могу понять, что делаю неправильно. Ошибка встречающийся в строке 371.Wordsearch puzzle nullpointerexception on array

Ниже приведен код родительского класса с последующим классом initializng в 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; 
    } 
} 

Вот класс инициализации массива letterArray:

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); 
    } 

} 

Заранее спасибо.

+0

Пожалуйста, добавьте трассировку стека исключения. –

+0

Также вы можете позвонить, где находится линия 371? –

+0

Ладно, новичок в stackoverflow, не могли бы вы помочь мне в этом. Я знаю, как получить его от затмения. – mungaialex

ответ

4

Вот оно!

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

Вы только инициализируете одну ось. Когда вы передаете этот массив в init() и устанавливаете this.letterArray = letterArray;, letterArray также не полностью инициализирован.

Попробуйте добавить длину к обеим осям:

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

Очень приятное место. –

+0

Все еще получая NPE после добавления обеих осей Correectin, он работает сейчас. Спасибо за помощь! – mungaialex

+0

@mungaialex Нечетный ... Можете ли вы опубликовать трассировку стека? – Navin

0

первым вы будете обрабатывать NullPoinetrException, код

if(letterArray != null){ 
     for (int x = 0; x < letterArray.length; x++) 
     { 
     .......... 
      ............ 
     } 
}