Issue
I have an arraylist of students and I am writing it to a text file in my save method and this is successful every time i run the application and it loads all of my objects the first time i run the program successfully. My problem is when I start the app again after closing and try to save and load new objects then it only loads my old objects from the first session and not any of the new saved objects.Save method is to write and load method is to read
package application;
import java.io.Serializable;
public class Student implements Serializable{
private String name = null; //students name
private int ID = 0; //students ID number
private String DOB = null; //Students Date of Birth
public Student(String name,int ID, String DOB) {
this.setName(name);
this.setID(ID);
this.setDOB(DOB);
}
public void printStudent() {
System.out.println("Name: " + name + " ID: " + ID + " DOB: " + DOB);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getDOB() {
return DOB;
}
public void setDOB(String dOB) {
DOB = dOB;
}
@Override public String toString() {
return "Name: " + name + " | ID: " + ID + " | Date of birth: " + DOB;
}
}
package application;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.StringJoiner;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
public class Test extends Application {
ArrayList<Student> arraylist = new ArrayList<Student>(); //arraylist of student objects
Student student;
Student line;
Validation validation = new Validation();
@Override
public void start(Stage primaryStage) {
try {
primaryStage.setTitle("MTU Student record system");
Label enterNamelbl = new Label("Enter Student Name");
TextField enterNametxt = new TextField();
HBox hbox1 = new HBox(42,enterNamelbl,enterNametxt);
hbox1.setAlignment(Pos.CENTER);
Label enterIDlbl = new Label("Enter Student ID");
TextField enterIDtxt = new TextField();
HBox hbox2 = new HBox(70,enterIDlbl,enterIDtxt);
hbox2.setAlignment(Pos.CENTER);
Label enterDOBlbl = new Label("Enter Student Date of Birth");
TextField enterDOBtxt = new TextField();
HBox hbox3 = new HBox(27,enterDOBlbl,enterDOBtxt);
hbox3.setAlignment(Pos.CENTER);
Button addbtn = new Button("Add");
Button removebtn = new Button("Remove");
Button listbtn = new Button("List");
HBox hbox4 = new HBox(12,addbtn,removebtn,listbtn);
hbox4.setAlignment(Pos.CENTER);
TextArea textArea = new TextArea();
HBox hbox5 = new HBox(textArea);
Button load = new Button("Load");
Button save = new Button("Save");
Button exit = new Button("Exit");
HBox hbox6 = new HBox(12,load,save,exit);
hbox6.setAlignment(Pos.BOTTOM_RIGHT);
VBox vbox1 = new VBox(29,hbox1,hbox2,hbox3,hbox4,hbox5,hbox6);
vbox1.setPadding(new Insets(10,10,10,10));
//adding a student to the arraylist
addbtn.setOnAction(e-> {
validation.isInt(enterIDtxt, enterIDtxt.getText());
String name = enterNametxt.getText();
int ID = Integer.parseInt(enterIDtxt.getText());
String Dob = enterDOBtxt.getText();
//validating user input
Student student = new Student(name,ID,Dob);
arraylist.add(student);
System.out.println(arraylist); //to remove later
});
//listing the arraylist of students
listbtn.setOnAction(e -> {
textArea.setText(null);
for(Student stu : arraylist){
textArea.appendText(stu + "\n");
}
});
//removing a student
removebtn.setOnAction(e -> {
int ID = Integer.parseInt(enterIDtxt.getText());
Student studentToRemove = null; //temporary variable to store student obj
for(Student student:arraylist){
if(student.getID()==ID);
studentToRemove = student;
}
if(studentToRemove==null)
System.out.println("No customer found");
else
arraylist.remove(studentToRemove); //need to throw an alert here
});
//saving everything to a txt file
save.setOnAction(e ->{
try {
File file = new File("StudentData.txt");
//File to store student data
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(file,true));
os.writeObject(arraylist); //writting all the items too the txt file
os.close();
}
catch(FileNotFoundException e1){
e1.printStackTrace();
}
catch(IOException e1) {
e1.printStackTrace();
}
});
//load everything from the txt file
load.setOnAction(e ->{
try {
textArea.setText(null);
FileInputStream fis = new FileInputStream("StudentData.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
List<Student> students = (List<Student>) ois.readObject();
// for(Student stu : students){
textArea.appendText(students + "\n");
// }
ois.close();
}
catch (FileNotFoundException e1) {
e1.printStackTrace();
}
catch (IOException e1) {
e1.printStackTrace();
}
catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
});
Scene mainScene = new Scene(vbox1,500,500);
//mainScene.getStylesheets().add("application.css");
primaryStage.setScene(mainScene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
Solution
There are 2 problems
During Writing
You are specifying
FileOutputStream(File,true)
From the docs this will append data to your File so you are not actually adding data to your ArrayList but infact it will append multiple ArrayLists to your file so remove the boolean flag and write
FileOutputStream(file);
Which will overwrite the content of the file
During Reading
Due to your writing error you were only reading the first ArrayList written to your file the very first time you ever ran your application hence why you were getting only old data
After reading the ArrayList from your file in the load setAction code add that loaded data to your original ArrayList used by your application
arrayList.addAll(students);
Also objects written to files are not in text format so to avoid misleading people change the extension to something else for the sake of clarity
Answered By - Sync it
Answer Checked By - Gilberto Lyons (JavaFixing Admin)