I've created a class Auto that contains an OptionSet array class (ie Color, Transmission), which connects to an OptionSet class that contains an Options array inner class(ie Blue, Red). I plan to read in a text file line by line and populate an Auto object with it. However, I don't know how to create an Auto object with a OptionSet array that is defined when reading the file, without having a NullPointerException.
From what I understand, I shouldn't use the specific constructor because the array length will become unchangeable, making reading other sized files difficult. But using the default constructor means the arrays in the optionSet and Option objects aren't initialized and cause NullPointerErrors. (I know arrayList is another option for building this, and one we'll be using; this is a class project that goes through common mistakes on its way to building a product.) IS there a way around this problem, or something else I'm missing?
Here's my error code:
Exception in thread "main" java.lang.NullPointerException
at model.Automotive.setOptionSetName(Automotive.java:61)
at util.FileInput.readData(FileInput.java:32)
at driver.Driver.main(Driver.java:17)
The auto class:
package model;
import java.io.*;
import java.io.Serializable;
import model.OptionSet;
import model.OptionSet.Option;
import util.FileInput;
public class Automotive implements Serializable{
//variables
private String name;
private static float basePrice;
private OptionSet[] opSet;
//constructor
public Automotive(int size, String n, float price) {
opSet = new OptionSet[size];
name = n;
basePrice = price;
for(int i=0; i<opSet.length; i++) {
opSet[i] = new OptionSet();
}
}
public Automotive() {
}
public void createOptionsSet(int opSetSize) {
this.opSet = new OptionSet[opSetSize];
}
public void createOption(int opSetLocation, int size) {
this.opSet[opSetLocation].createOption(size);
}
public void setName(String newName) {
name = newName;
}
public String getName() {
return name;
}
public void setPrice(float price) {
basePrice = price;
}
public float getPrice() {
return basePrice;
}
public OptionSet getOptionSet(int location) {
return opSet[location];
}
public void setOptionSetName(int opSetLocation, String opSetName) {
this.opSet[opSetLocation].setOptionSetName(opSetName);
}
public String getOptionSetName(int opSetLocation) {
return this.opSet[opSetLocation].getOptionSetName();
}
public void setOption(int opSetLocation, int opLocation, String name, float price) {
this.opSet[opSetLocation].setOption(opLocation, name, price);
}
public Option getOption(int opSetLocation, int opLocation) {
return this.opSet[opSetLocation].getOption(opLocation);
}
}
The optionSet class (with inner class Option)
package model;
import java.io.Serializable;
import java.util.Arrays;
import model.OptionSet;
public class OptionSet implements Serializable{
//variables
private OptionSet[] opSet;
private Option opt[];
private String name;
//constructor
protected OptionSet(String n, int size) {
opt = new Option[size];
name = n;
for(int i=0; i<opt.length; i++) {
opt[i] = new Option();
}
}
public OptionSet() {
}
//methods
protected void createOptionsSet(int size) {
OptionSet[] opSet = new OptionSet[size];//creates OptionSet array
}
protected void createOption(int size) {
this.opt = new Option[size];
}
protected void setOptionSetName(String newNname) {
name = newNname; //to name the optionSet cells - color, transmission, etc
}
protected String getOptionSetName() {
return name;
}
protected void setOption(int location, String newName, float newPrice) {
this.opt[location].setName(newName);
this.opt[location].setPrice(newPrice);
}
protected Option getOption(int location) {
return this.opt[location];
}
protected void setOptionName(int location, String newName) {
this.opt[location].setName(newName);
}
protected String getOptionName(int location) {
return this.opt[location].name;
}
protected void setOptionPrice(int location, float newPrice) {
this.opt[location].setPrice(newPrice);
}
protected float getOptionPrice(int location) {
return this.opt[location].price;
}
protected void deleteOption(int location) {
this.opt[location].deleteOption();
}
protected void deleteOptionName(int location) {
this.opt[location].deleteName();
}
protected void deleteOptionPrice(int location) {
this.opt[location].deletePrice();
}
//does this work to print a custom object?
protected void print(Automotive auto) {
System.out.printf("%10s", name);
for(int j=0; j<opt.length; j++) {
this.opt[j].print(auto);
}
}
//inner class Option
protected class Option implements Serializable{
private String name;
private float price;
Option(String name, float price){
name = name;
price = price;
}
public Option() {
}
protected void print(Automotive auto) {
System.out.printf("%10s", name);
System.out.printf("%10f", price);
}
protected void createOption(String name, float price) {
Option opt = new Option(name, price);
}
protected void setName(String newName) {
name = newName;
}
protected String getName() {
return name;
}
protected void setPrice(float newPrice) {
price = newPrice;
}
protected float getPrice() {
return price;
}
protected void updateName(String newName) {
name = newName;
}
protected void updatePrice(float newPrice) {
price = newPrice;
}
}
The FileInput class, using public Auto methods:
package util;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.StringTokenizer;
import model.*;
public class FileInput {
public Automotive readData(String fileName){
//houses parser
Automotive auto = new Automotive();
// auto.createOptionsSet(5);
try {
FileReader file = new FileReader(fileName);
BufferedReader buff = new BufferedReader(file);
String name = buff.readLine(); //Focus Wagon ZTW
auto.setName(name);
String price = buff.readLine(); //18445
auto.setPrice(Integer.parseInt(price));
int opSetSize = Integer.parseInt(buff.readLine()); //5
auto.createOptionsSet(opSetSize); //create optionSet of size 5
for(int opSetLocation=0; opSetLocation < opSetSize; opSetLocation++) {
String optionTitle = buff.readLine(); //Color
auto.setOptionSetName(opSetLocation, optionTitle);
int opSize = Integer.parseInt(buff.readLine()); //10
//optionsettotal, in each option set option array of size blah
auto.createOption(opSetLocation, opSize);
for (int opLocation=0; opLocation < opSize; opLocation++) { //loop to parse colors
String optionLine = buff.readLine(); //get first color, "gold, 0"
StringTokenizer st = new StringTokenizer(optionLine, ", ");
String optionName = st.nextToken();
float optionPrice = Float.parseFloat(st.nextToken());
auto.setOption(opSetLocation, opLocation, optionName, optionPrice);
}
}
buff.close();
}
catch (IOException e) {
System.out.println("Error -- " + e.toString());
}
return auto;
}
public void serializeAuto(Automotive auto)
{
try {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("auto.ser"));
out.writeObject(auto);
out.flush();
out.close();
} catch (IOException e) {
System.out.print("Error: " + e);
System.exit(1);
}
}
public Automotive deserializeAuto(String fileName) {
Automotive newAuto = null;
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName));
newAuto = (Automotive) in.readObject();
}
catch(IOException e) {
System.out.print("Error: " + e);
System.exit(1);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return newAuto;
}
}
And the Driver class for running the actual program:
package driver;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import model.Automotive;
import util.FileInput;
public class Driver{
public static void main(String[] args) {
//Build Automotive object from a file
FileInput file = new FileInput();
Automotive FordZTW = file.readData("C:\\Users\\~ Adam ~\\Documents\\Computer Programming Notes\\Advanced Problem Solving\\FordZTW.txt");
//print attributes before serialization
FordZTW.printAuto(FordZTW);
//Serialize object
file.serializeAuto(FordZTW);
//Deserialize the object and read it into memory
Automotive newFordZTW = file.deserializeAuto("auto.ser");
//print new attributes
newFordZTW.printAuto(FordZTW);
}
}