Hi,
I am desperately hoping that someone can help me as I have got myself in a big mess. I have only started learning Java.
Essentially I have an assignment that included 2 stages. The first stage required us to include all the elements in one class
(I was able to do this successfully), however i ran into trouble in the second stage where we needed to use 2 classes.
Please note: I have chopped and changed so many things to find a solution (changed things from private to public, and auto created numerous
getters), so it is very much a work in progress. Please go easy on me!!!
My error is:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "RainGauge.displayDetails()" because "this.rainGauge" is null
at StageB.displayDetailsWithConsole(StageB.java:184)
at StageB.menuFunctions(StageB.java:114)
at StageB.menuChoices(StageB.java:82)
at StageB.setup(StageB.java:73)
at StageB.<init>(StageB.java:40)
at StageB.main(StageB.java:286)
import java.util.Random; import java.util.Scanner; public class StageB { Scanner kb = new Scanner(System.in); Random randomNumber = new Random(); private char selection; private int currentNum; private int size; int startDayInput; int endDayInput; int thresholdInput; private int dailyRainfallInput; private String rainGaugeLocationInput; private float rainGaugeLatitudeInput; private float rainGaugeLongitudeInput; private int daysOfDataInput; private int rainGaugeIdGenerate; private int currentNumGaugesSelection; private int maxNumGaugesSelection; private RainGauge rainGauge; //rainGauge = new RainGauge(rainGaugeLocationInput, rainGaugeLatitudeInput, rainGaugeLongitudeInput, daysOfDataInput); private Object rG; public StageB() { setup(); rainGauge = new RainGauge(rainGaugeLocationInput, rainGaugeLatitudeInput, rainGaugeLongitudeInput, daysOfDataInput); } public void setup() { if (rainGauge == null) { System.out.println("Do you want to create a [n]ew Rain Gauge or [d]isplay an existing one?"); System.out.println("***Please enter the letter corresponding to your choice***"); this.selection = kb.nextLine().toLowerCase().charAt(0); if (selection == 'n') { rainGaugeIdGenerate = randomNumber.nextInt(10000); System.out.println("Enter the site/location of the new Rain Gauge"); rainGaugeLocationInput = kb.nextLine().toUpperCase(); System.out.println("Enter the latitude of the site/location (in decimal degrees, 6 decimal places)"); rainGaugeLatitudeInput = Float.parseFloat(kb.nextLine()); System.out.println("Enter the longitude of the site/location (in decimal degrees, 6 decimal places)"); rainGaugeLongitudeInput = Float.parseFloat(kb.nextLine()); System.out.println("How many days of data do you want to enter for " + rainGaugeLocationInput + " rain gauge?"); daysOfDataInput = Integer.parseInt(kb.nextLine()); System.out.println("SUCCESS - NEW RAIN GAUGE ENTERED"); } else if (selection == 'd') { rainGauge.displayDetails(); } else System.out.println("INVALID CHOICE, PLEASE TRY AGAIN"); } menuChoices(); } public void menuChoices() { userMenu(); do { this.selection = kb.nextLine().toLowerCase().charAt(0); menuFunctions(selection); } while (selection != ' '); System.out.println("ERROR"); this.selection = kb.nextLine().toLowerCase().charAt(0); menuFunctions(selection); // kb.close(); } public void userMenu() { System.out.println("***Meteorological Monitoring Australia - Rain Gauge Menu***"); System.out.println("==========================================================="); System.out.println("***Please enter the letter corresponding to your choice***"); System.out.println("Create/Update [R]ain Gauge"); System.out.println("[D]isplay Rain Gauge Details"); System.out.println("[A]dd Daily Rainfall Data"); System.out.println("[P]rint Daily Rainfall Data"); System.out.println("Display Rainfall [H]istogram"); System.out.println("Display [M]aximum Rainfall"); System.out.println("Determine if Rainfall is Below [T]hreshold"); System.out.println("Display [S]tatistical Analysis"); System.out.println("E[x]it"); } public void menuFunctions(char selection) { switch (selection) { case 'r': createRainGauge(); break; case 'd': displayDetailsWithConsole(); break; case 'a': addRainfallDataWithConsole(); break; case 'p': printRainfallDataWithConsole(); break; case 'h': displayHistogramWithConsole(); break; case 'm': displayMaximumRainfallWithConsole(); break; case 't': belowThresholdWithConsole(startDayInput, endDayInput, thresholdInput); break; case 's': statisticalAnalysisWithConsole(); break; case 'x': System.out.println("Thank you for using the 'Meteorological Monitoring Australia - Rain Gauge Program'"); break; default: System.out.println("ERROR - PLEASE MAKE A VALID SELECTION"); break; } System.out.println(); userMenu(); } private void createRainGauge() { //currentNumGaugesSelection = rainGauge.getCurrentNumGauges(); //maxNumGaugesSelection = rainGauge.getMaxNumGauges(); System.out.println("Do you want to create a [n]ew Rain Gauge or [d]isplay an existing one?"); System.out.println("***Please enter the letter corresponding to your choice***"); this.selection = kb.nextLine().toLowerCase().charAt(0); if (selection == 'n') { rainGaugeIdGenerate = randomNumber.nextInt(10000); System.out.println("Enter the site/location of the new Rain Gauge"); rainGaugeLocationInput = kb.nextLine().toUpperCase(); System.out.println("Enter the latitude of the site/location (in decimal degrees, 6 decimal places)"); rainGaugeLatitudeInput = Float.parseFloat(kb.nextLine()); System.out.println("Enter the longitude of the site/location (in decimal degrees, 6 decimal places)"); rainGaugeLongitudeInput = Float.parseFloat(kb.nextLine()); System.out.println("How many days of data do you want to enter for " + rainGaugeLocationInput + " rain gauge?"); daysOfDataInput = Integer.parseInt(kb.nextLine()); System.out.println("SUCCESS - NEW RAIN GAUGE ENTERED"); boolean added = this.rainGauge.rainGaugeCreated(rainGaugeLocationInput, rainGaugeLatitudeInput, rainGaugeLongitudeInput, daysOfDataInput); if (!added) { System.out.println("ERROR, COULD NOT ADD RAIN GAUGE"); } else if (selection == 'd') { rainGauge.displayDetails(); } else System.out.println("INVALID CHOICE, PLEASE TRY AGAIN"); } } public void displayDetailsWithConsole() { rainGauge.displayDetails(); } public void statisticalAnalysisWithConsole() { rainGauge.statisticalAnalysis(); } public void belowThresholdWithConsole(int startDay, int endDay, int threshold) { System.out.println("***Determining if all days within specific timeframe have rainfall below threshold amount***"); System.out.println(""); System.out.println("In reference to the data stored above, please enter a day number to start the timeframe (day number ' ')"); startDayInput = getIntegerInput(); System.out.println("In reference to the data stored above, please enter a day number to end the timeframe (day number ' ')"); endDayInput = getIntegerInput(); System.out.println("Please enter a threshold (in whole mm) to check the data against"); thresholdInput = getIntegerInput(); rainGauge.belowThreshold(startDayInput, endDayInput, thresholdInput); } public void displayMaximumRainfallWithConsole() { rainGauge.displayMaximumRainfall(); } public void displayHistogramWithConsole() { rainGauge.displayHistogram(); } public void printRainfallDataWithConsole() { rainGauge.printRainfallData(); } public void addRainfallDataWithConsole() { rainGauge.addRainfallData(); } public int getIntegerInput() { int userInput = Integer.parseInt(kb.nextLine()); return userInput; } public String getRainGaugeLocationInput() { return rainGaugeLocationInput; } public float getRainGaugeLatitudeInput() { return rainGaugeLatitudeInput; } public float getRainGaugeLongitudeInput() { return rainGaugeLongitudeInput; } public int getDaysOfDataInput() { return daysOfDataInput; } public int getDailyRainfallInput() { return dailyRainfallInput; } public int getStartDayInput() { return startDayInput; } public int getEndDayInput() { return endDayInput; } public int getThresholdInput() { return thresholdInput; } public Random getRandomNumber() { return randomNumber; } public char getSelection() { return selection; } public int getCurrentNum() { return currentNum; } public int getSize() { return size; } public int getRainGaugeIdGenerate() { return rainGaugeIdGenerate; } public int getCurrentNumGaugesSelection() { return currentNumGaugesSelection; } public int getMaxNumGaugesSelection() { return maxNumGaugesSelection; } public static void main(String[] args) { StageB rainGaugeObject = new StageB(); //rainGaugeObject.menuChoices(); } }
public class RainGauge { StageB stageBObject = new StageB(); private int rainGaugeId; private String rainGaugeLocation; private float rainGaugeLatitude; private float rainGaugeLongitude; private int daysOfData; private int dailyRainfall; private char selection; int maxRainfall; int totalRainfall; int threshold; int startDay; int endDay; private int maxNumGauges = 3; private int currentNumGauges = 0; private int currentNumRainfall = 0; private RainGauge[] rG = new RainGauge[this.maxNumGauges]; private int[] rD = new int[this.daysOfData]; public RainGauge(String rainGaugeLocation, float rainGaugeLatitude, float rainGaugeLongitude, int daysOfData) { this.rainGaugeId = rainGaugeId; this.rainGaugeLocation = rainGaugeLocation; this.rainGaugeLatitude = rainGaugeLatitude; this.rainGaugeLongitude = rainGaugeLongitude; this.daysOfData = daysOfData; } public RainGauge(int dailyRainfall) { this.dailyRainfall = dailyRainfall; } public boolean rainGaugeCreated(String rainGaugeLocation, float rainGaugeLatitude, float rainGaugeLongitude, int daysOfData) { boolean added = false; rainGaugeLocation = stageBObject.getRainGaugeLocationInput(); rainGaugeLatitude = stageBObject.getRainGaugeLatitudeInput(); rainGaugeLongitude = stageBObject.getRainGaugeLongitudeInput(); daysOfData = stageBObject.getDaysOfDataInput(); if (this.currentNumGauges <= this.maxNumGauges) { this.rG[this.currentNumGauges] = new RainGauge(rainGaugeLocation, rainGaugeLatitude, rainGaugeLongitude, daysOfData); this.currentNumGauges += 1; added = true; } return added; } public void addRainfallData() { int count = (daysOfData - 1); if (daysOfData != 0) { System.out.println("You have a maximum of " + daysOfData + " days of rainfall data to enter"); } else { System.out.println("ERROR, PLEASE ADD A RAIN GAUGE FIRST"); stageBObject.userMenu(); } for (int currentNum = 0; currentNum < rD.length; currentNumRainfall++) { System.out.println("Enter the daily rainfall (in whole mm)"); dailyRainfall = stageBObject.getDailyRainfallInput(); this.rD[currentNumRainfall] = dailyRainfall; System.out.println("You have " + count + " days of data left to enter"); count--; } if (currentNumRainfall > rD.length) { System.out.println("ERROR, YOU HAVE EXCEEDED THE MAXIMUM STORAGE LIMIT"); } System.out.println("----------------------------------------------------"); System.out.println("A summary of the data that you have entered"); int j = 0; int day = 1; while (j < rD.length) { System.out.println("Day " + day + " " + rD[j] + "mm"); j += 1; day++; } } public void printRainfallData() { System.out.println("----------------------------------------------------"); System.out.println("A summary of the data that you have entered"); int j = 0; int day = 1; while (j < rD.length) { System.out.println("Day " + day + " " + rD[j] + "mm"); j += 1; day++; } } public void displayDetails() { if (rainGaugeId != 0 && !rainGaugeLocation.isBlank() && rainGaugeLatitude != 0 && rainGaugeLongitude != 0 && daysOfData != 0) { System.out.println( "-------------------------------------------------------------------------------------------------"); String tableHeadingsFormat = "%-15s%-25s%-15s%-15s%-15s\n"; String tableDataFormat = "%10d%23s%22.6f%15.6f%16d\n"; System.out.printf(tableHeadingsFormat, "Site/Location ID # |", "Site/Location Name |", "Latitude |", "Longitude |", "Number of days data |"); System.out.printf(tableDataFormat, rainGaugeId, rainGaugeLocation, rainGaugeLatitude, rainGaugeLongitude, daysOfData); System.out.println( "-------------------------------------------------------------------------------------------------"); } else System.out.println("THERE ARE NO RAIN GAUGE DETAILS TO DISPLAY, PLEASE CREATE A RAIN GAUGE FIRST"); } public void statisticalAnalysis() { for (int i = 0; i < rD.length; i++) { totalRainfall += rD[i]; } float daysOfDataAverage = this.daysOfData; float totalRainfallAverage = this.totalRainfall; float averageRainfall = (totalRainfallAverage / daysOfDataAverage); float averageRainfallDisplay = Math.round(averageRainfall); int belowAverage = 0; int equalAverage = 0; int aboveAverage = 0; for (int i = 0; i < rD.length; i++) { if (rD[i] < averageRainfall) { belowAverage += 1; } else if (rD[i] > averageRainfall) { aboveAverage += 1; } else { equalAverage += 1; } } System.out.println( "----------------------------------------------------------------------------------------------------------------------"); String statisticsHeadingsFormat = "%-15s%-15s%-15s%-15s%-15s%-15s\n"; String statisticsFormat = "%7d%14d%18.0f%20d%22d%24d\n"; System.out.printf(statisticsHeadingsFormat, "Days of Data |", "Total (mm) |", "Daily Average (mm) |", "Days Below Average |", "Days Equal to Average |", "Days Above Average |"); System.out.printf(statisticsFormat, daysOfData, totalRainfall, averageRainfallDisplay, belowAverage, equalAverage, aboveAverage); System.out.println( "----------------------------------------------------------------------------------------------------------------------"); System.out.println(""); } public boolean belowThreshold(int startDay, int endDay, int threshold) { int totalBelow = 0; int startDayCalculation = stageBObject.getStartDayInput(); startDay = (startDayCalculation - 1); int endDayCalculation = stageBObject.getEndDayInput(); endDay = (endDayCalculation - 1); printRainfallData(); System.out.println(""); int timeframe = (endDay - startDay) + 1; int[] subArray = new int[timeframe]; int n = 0; int thresholdDay = startDay + 1; for (int i = startDay; i <= endDay; i++) { System.out.println("Rainfall (mm) " + rD[i] + " on Day " + thresholdDay); subArray[n] = rD[i]; n++; thresholdDay++; } System.out.println(""); System.out.println("New set of Data"); System.out.println(""); for (int m = 0; m < subArray.length; m++) { System.out.println("Rainfall (mm) " + subArray[m] + " on Day " + m); } System.out.println(""); boolean below = false; for (int l = 0; l < subArray.length; l++) { if (subArray[l] < threshold) { below = true; totalBelow += 1; } } System.out.println( "The number of days below the threshold of " + threshold + " mm" + " is " + totalBelow + " day/s"); return true; } public void displayMaximumRainfall() { int minRainfall; maxRainfall = this.rD[0]; minRainfall = this.rD[0]; for (int i = 1; i < rD.length - 1; i = i + 2) { if (i + 1 > rD.length) { if (this.rD[i] > maxRainfall) maxRainfall = this.rD[i]; if (this.rD[i] < minRainfall) minRainfall = this.rD[i]; } if (this.rD[i] > this.rD[i + 1]) { if (this.rD[i] > maxRainfall) maxRainfall = this.rD[i]; if (this.rD[i + 1] < minRainfall) minRainfall = this.rD[i + 1]; } if (this.rD[i] < this.rD[i + 1]) { if (this.rD[i] < minRainfall) minRainfall = this.rD[i]; if (this.rD[i + 1] > maxRainfall) maxRainfall = this.rD[i + 1]; } } System.out.println("The maximum rainfall value stored is " + maxRainfall + " mm"); } public void displayHistogram() { String display09 = ("0-9mm"); String display1019 = ("10-19mm"); String display2029 = ("20-29mm"); String display3039 = ("30-39mm"); String display4049 = ("40-49mm"); String display5059 = ("50-59mm"); System.out.println("----------------------------------------------------"); System.out.println("Histogram: Spread of Rainfall ('*' represents each day of data)"); System.out.println("===================================================="); System.out.print(display09); for (int j = 0; j < rD.length; j++) { if (rD[j] >= 0 && rD[j] < 10) System.out.print("|*|"); } System.out.println(); System.out.println("===================================================="); System.out.print(display1019); for (int j = 0; j < rD.length; j++) { if (rD[j] >= 10 && rD[j] < 20) System.out.print("|*|"); } System.out.println(); System.out.println("===================================================="); System.out.print(display2029); for (int j = 0; j < rD.length; j++) { if (rD[j] >= 20 && rD[j] < 30) System.out.print("|*|"); } System.out.println(); System.out.println("===================================================="); System.out.print(display3039); for (int j = 0; j < rD.length; j++) { if (rD[j] >= 30 && rD[j] < 40) System.out.print("|*|"); } System.out.println(); System.out.println("===================================================="); System.out.print(display4049); for (int j = 0; j < rD.length; j++) { if (rD[j] >= 40 && rD[j] < 50) System.out.print("|*|"); } System.out.println(); System.out.println("===================================================="); System.out.print(display5059); for (int j = 0; j < rD.length; j++) { if (rD[j] >= 50 && rD[j] < 60) System.out.print("|*|"); } System.out.println(); System.out.println("===================================================="); System.out.println("Histogram: Daily Rainfall ('*' represents 10mm of rain)"); int day = 0; String asterisk = ""; for (int j = 0; j < rD.length; j++) { day++; if (rD[j] >= 10 && rD[j] <= 19) { asterisk = " *"; System.out.println("Day " + day + " " + asterisk); } if (rD[j] >= 20 && rD[j] <= 29) { asterisk = " **"; System.out.println("Day " + day + " " + asterisk); } if (rD[j] >= 30 && rD[j] <= 39) { asterisk = " ***"; System.out.println("Day " + day + " " + asterisk); } if (rD[j] >= 40 && rD[j] <= 49) { asterisk = " ****"; System.out.println("Day " + day + " " + asterisk); } if (rD[j] >= 50 && rD[j] <= 59) { asterisk = " *****"; System.out.println("Day " + day + " " + asterisk); } } } public int getThreshold() { return threshold; } public int getStartDay() { return startDay; } public int getEndDay() { return endDay; } public String getRainGaugeLocation() { return rainGaugeLocation; } public float getRainGaugeLatitude() { return rainGaugeLatitude; } public float getRainGaugeLongitude() { return rainGaugeLongitude; } public int getDaysOfData() { return daysOfData; } public int getDailyRainfall() { return dailyRainfall; } public int getMaxNumGauges() { return maxNumGauges; } public int getCurrentNumGauges() { return currentNumGauges; } }