0

I'm trying to code a project that deals with a dumb downed version of an excel sheet. One of the commands I am allowing from the user is assigning a value into specific cells in the format of = . i.e A3 = 72.3%. Once it assigns the value to the cell, it then prints out the entire spreadsheet with the updated changes.

I created different classes to represent different types of cells. Value Cell is a cell that will contain any double value, Percent Cell is a cell that will contain any percentage value, Text Cell is a cell that will contain text.

While I was trying to run my program, I tried assigning a percentage value to a cell. (A2 = 7.25%) When the program prints out the entire spreadsheet with the newly assigned A2 percentage cell, it's supposed to truncate the decimal from the percentage and just display 7%. However, I keep getting this error message

Exception in thread "main" java.lang.NullPointerException
    at PercentCell.abbreviatedCellText(PercentCell.java:18)
    at Spreadsheet.getGridText(Spreadsheet.java:127)
    at Spreadsheet.processCommand(Spreadsheet.java:73)
    at TextExcel.main(TextExcel.java:20)

This is part of my code that assigns specific cell types depending on what the user inputs:

//assignment command   
      } else if (command.contains("=")) {
         int eqIndex = command.indexOf("=");
         if (!command.substring(eqIndex - 1, eqIndex).equals(" ") || !command.substring(eqIndex + 1, eqIndex + 2).equals(" ")) {
            return "Formatting Error: please include a space before and after the ="; //error message
         } else {
            String[] input = command.split(" ", 3);
            SpreadsheetLocation cell = new SpreadsheetLocation(input[0]);
            int col = cell.getCol();
            int row = cell.getRow();
            if (col > COLUMNS || row > ROWS) {
               return "Error: cell outside of spreadsheet"; //error message
            }
            //assigning a textcell
            if (input[2].contains("\"")) {
               String inputValue = input[2].substring(1, input[2].length() - 1);
               TextCell textCell = new TextCell(inputValue);
               spreadsheet[row][col] = textCell;
            //assigning a percent cell 
            } else if (input[2].contains("%")) {
               PercentCell percentCell = new PercentCell(input[2]);
               spreadsheet[row][col] = percentCell;

The percent cell extends super class, Real Cell:

public class RealCell implements Cell {
   private String fullText;

   public RealCell(String input) {
      this.fullText = input;
   }

   //method that returns the display of the abbreviated cell 
   public String abbreviatedCellText() {
      if (fullText.length() > 10) {
         return fullText.substring(0, CELLWIDTH);
      } else {
      String output = fullText;
      while(output.length() < CELLWIDTH) {
         output += " ";
      }
         return output;
      }
   }

   //method that returns the actual value in a real cell 
   public String fullCellText() {
      return fullText;
   } 

   //method that parses the user input into a double
   public double getDoubleValue() {
      return Double.parseDouble(fullText);   
   } 
}

Here is now the problem part of my code, the Percent Cell class:

public class PercentCell extends RealCell {
   private String fullText;

   public PercentCell(String input) {
      super(input);
   }

   //method that returns the display of the abbreviated cell, truncating the decimal  
   public String abbreviatedCellText() {
      String value = fullText;
      if (value.contains(".")) {
         int decIndex = fullText.indexOf(".");
         value = value.substring(0, decIndex) + "%";
      }  
      if (value.length() > 10) {
         return value.substring(0, CELLWIDTH);
      } else {
      String output = value;
      while(output.length() < CELLWIDTH) {
         output += " ";
      }
         return output;
      }
   }

   //method that parses the user input into a double and returns the percent value into a decimal
   public double getDoubleValue() {
      double decimal = Double.parseDouble(fullText.substring(0, fullText.length() - 1));
      return decimal/100;   
   }
}

How could I fix this error? If any clarifications regarding my code are needed (because this is not my entire project) please let me know!

  • I believe that you should use a debugger on PercentCell.abbreviatedCellText() in order to find the null value. You could just use a boatload of print statements in there instead, but a debugger might be easier. – NomadMaker May 22 '20 at 05:06
  • According to the stack trace you posted, line 18 of file `PercentCell.java` is throwing `NullPointerException`. Which line is line 18 in file `PercentCell.java` ? – Abra May 22 '20 at 05:29
  • @Abra line 18 is "if (value.contains(".")) {" – Kiley Kearns May 22 '20 at 05:34

1 Answers1

0
     public class PercentCell extends RealCell {

     public PercentCell(String input) {
          super(input);
       }

       //method that returns the display of the abbreviated cell, truncating the decimal  
       public String abbreviatedCellText() {
          String value = super.fullCellText();
          if (value.contains(".")) {
             int decIndex = value.indexOf(".");
             value = value.substring(0, decIndex) + "%";
          }  
          if (value.length() > 10) {
             return value.substring(0, CELLWIDTH);
          } else {
          String output = value;
          while(output.length() < CELLWIDTH) {
             output += " ";
          }
             return output;
          }
   }

You used fullText field without giving value and fullText value was always null I think that was the problem, but let me know please if it helps!

  • Since Percent cell is a sub class of RealCell, don't I not have to create a new Real Cell within my Percent Cell class? In my RealCell class I gave fullText value using the constructor. So fullText should be whatever the user inputs after the = (ex. if user commanded A2 = 7.89, fullText will be 7.89) Did I misunderstand your suggestion? – Kiley Kearns May 22 '20 at 05:20
  • I did a small change , you are right about the part that you used RealCell constructor to give fullText a value but that was for RealCell fullText attribute, and you were using PercentCell fullText attribute which was never used and was null. I think this can help at least i tried but let me know . Thank you – Arjanit Isufi May 22 '20 at 05:30
  • Oh, thank you so much for the clarification! Could I also fix this problem by making the String fullText a protected field instead of a private? Or would I have to keep using super.fullCellText() when I want to use the fullText? – Kiley Kearns May 22 '20 at 05:40
  • You can but is always better to use methods and keep attributes private, that's why getters and setters are almost every time needed. I hope i helped you ! – Arjanit Isufi May 22 '20 at 05:46