Issue
I have a library program that adds values into an array list, writes the lists to a delimited file. When my array list is getting populated, it only copies the last values. Here's the code I have right now:
// LibraryGUI.java file
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import java.util.Optional;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
public class LibraryGUI extends Application {
private Library library = new Library(this);
private static Button btAddItem = new Button("Add");
private static Button btCheckOut = new Button("Check Out");
private static Button btCheckIn = new Button("Check In");
private static Button btDelete = new Button("Delete");
private ListView<String> list;
@Override
public void start(Stage primaryStage) throws Exception {
HBox buttonPanel = new HBox();
buttonPanel.getChildren().addAll(btAddItem, btCheckOut, btCheckIn, btDelete);
buttonPanel.setAlignment(Pos.CENTER);
buttonPanel.setSpacing(17);
list = new ListView<String>();
list.setEditable(true);
ObservableList<String> allItems = FXCollections.observableArrayList(library.listAllItems());
list.setItems(allItems);
allItems.addListener((ListChangeListener<Object>) change -> {
System.out.println("List View Changed");
});
BorderPane bPane = new BorderPane();
BorderPane.setAlignment(list, Pos.TOP_LEFT);
BorderPane.setMargin(list, new Insets(14,14,8,14));
BorderPane.setMargin(buttonPanel, new Insets(0,8,8,8));
bPane.setCenter(list);
bPane.setBottom(buttonPanel);
// Add Item Button action
btAddItem.setOnAction(e -> {
addNewItem();
list.setItems(FXCollections.observableArrayList(library.listAllItems())); // Update GUI
});
// Check Out Item Button action
btCheckOut.setOnAction(e -> {
checkOutItem();
list.setItems(FXCollections.observableArrayList(library.listAllItems())); // Update GUI
});
// Check In Item Button action
btCheckIn.setOnAction(e -> {
checkInItem();
list.setItems(FXCollections.observableArrayList(library.listAllItems())); // Update GUI
});
// Delete Item Button action
btDelete.setOnAction(e -> {
deleteItem();
list.setItems(FXCollections.observableArrayList(library.listAllItems())); // Update GUI
});
Scene scene = new Scene(bPane, 600, 600);
primaryStage.setTitle("Lending Library");
primaryStage.setScene(scene);
primaryStage.setWidth(bPane.getWidth());
primaryStage.setHeight(bPane.getHeight());
primaryStage.setResizable(false);
primaryStage.show();
// Save on close
primaryStage.setOnCloseRequest(e -> {
try {
library.save();
} catch (Exception exp) {
System.out.println("File did not save!");
} finally {
System.exit(0);
}
});
}
// Method to add an item in the list
public void addNewItem() {
String name = null, format = null;
TextInputDialog dialogBox = new TextInputDialog();
dialogBox.setTitle("Add Item");
dialogBox.setHeaderText(null);
dialogBox.setContentText("Name of Item:");
Optional<String> input = dialogBox.showAndWait();
if (input.isPresent()) {
name = input.get();
}
dialogBox.getEditor().clear();
dialogBox.setContentText("FormatType: ");
input = dialogBox.showAndWait();
if (input.isPresent()) {
format = input.get();
}
library.addNewItem(name, format);
try {
library.save();
} catch (Exception exc) {
System.out.println("File did not save!");
exc.printStackTrace();
}
}
// Method to delete an item in the list
public void deleteItem() {
Object selected = list.getSelectionModel().getSelectedItem();
String s = selected.toString();
String title = s.substring(0, s.lastIndexOf("("));
title = title.trim();
library.delete(title);
try {
library.save();
} catch (Exception exc) {
System.out.println("File did not save!");
exc.printStackTrace();
}
}
// Method to check out item in the list
public void checkOutItem() {
String name = null,
date = null;
TextInputDialog dialogBox = new TextInputDialog();
dialogBox.setTitle("Item Check Out");
dialogBox.setHeaderText(null);
dialogBox.setContentText("Enter Person Loaning To: ");
Optional<String> result = dialogBox.showAndWait();
if (result.isPresent()) {
name = result.get();
}
dialogBox.getEditor().clear();
dialogBox.setContentText("Date: ");
result = dialogBox.showAndWait();
if (result.isPresent()) {
date = result.get();
}
try {
library.markItemOnLoan(list.getSelectionModel().getSelectedIndex(), name, date);
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText(null);
alert.setContentText(e.getMessage());
}
}
// Method to check in items in the list
public void checkInItem() {
Object selected = list.getSelectionModel().getSelectedItem(); // gets the selected item
String s = selected.toString(); // converts that to a String
String title = s.substring(0, s.lastIndexOf("(")); // extracts the title
title.trim(); // removes any trailing whitespace
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("Item Check In");
dialog.setHeaderText(null);
dialog.setContentText("Enter Title Returned: ");
try {
library.markItemReturned(list.getSelectionModel().getSelectedIndex());
} catch (Exception e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setTitle("Error");
alert.setHeaderText(null);
alert.setContentText(e.getMessage());
}
}
// Method to start GUI
public static void main(String[] args) {
Application.launch(args);
}
}
This is my Library.java file
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.io.File;
import java.io.PrintWriter;
public class Library {
private ArrayList<MediaItem> items;
private LibraryGUI gui;
private ArrayList<String> masterList;
public Library(LibraryGUI GUI) {
this.gui = gui;
items = new ArrayList<MediaItem>();
try {
open();
} catch (Exception exp) {
System.out.println(exp.getMessage());
exp.printStackTrace();
}
}
// Method to add new item
public void addNewItem(String title, String format) {
items.add(new MediaItem(title, format));
System.out.println("Item Added");
System.out.println(items.get(items.size() - 1).getTitle());
}
// Method to mark item on loan
public void markItemOnLoan(int index, String title, String loanDate) throws Exception {
try {
items.get(index).markOnLoan(title, loanDate);
} catch (Exception e) {
throw e;
}
return;
}
//
public ArrayList<String> listAllItems() {
System.out.println("\nItems Updated~");
masterList = new ArrayList<String>();
System.out.println("Number of values in Items: "+ items.size()); // Debugging console output
for (int index = 0; index < (items.size()); index++) {
System.out.println("Index for showing Array list: " + index); // Debugging console output
String mItem = "";
mItem = items.get(index).getTitle();
System.out.println(items.get(index).getTitle()); // Debugging console output
mItem += " (";
mItem += items.get(index).getFormat();
mItem += ")";
if (items.get(index).isOnLoan()) {
mItem += (" loaned to " + items.get(index).getLoanedTo() + " on " + items.get(index).getDateLoaned());
}
masterList.add(mItem);
System.out.println("Number of items in Master List: "+ masterList.size()); // Debugging console output
System.out.println("Added " + items.get(index).getTitle()); // Debugging console output
}
return masterList;
}
// Method to mark item returned
public void markItemReturned(int index) {
try {
items.get(index).markReturned();
} catch (Exception e) {
e.printStackTrace();
}
return;
}
// Method to delete item
public void delete(String title) {
Iterator<MediaItem> iter = items.iterator();
while (iter.hasNext()) {
MediaItem mItem = iter.next();
if(mItem.getTitle().equalsIgnoreCase(title))
iter.remove();
}
}
// Method to save items to file
public void save() throws Exception {
File file = new File("libraryItems.txt");
PrintWriter pw = new PrintWriter(file);
for(MediaItem item : items) {
pw.println(
"%" + item.getTitle() + "%" + item.getFormat() + "%" + item.isOnLoan() +
"%" + (item.isOnLoan() ? item.getLoanedTo() : "null") + "%" +
(item.isOnLoan() ? item.getDateLoaned() : "null"));
}
System.out.println("File Saved");
pw.close();
}
// Method to open file
public void open() throws Exception {
MediaItem mItem = new MediaItem();
String itemStr;
String loanedTo;
Scanner fileInput = new Scanner(new File("libraryItems.txt"));
fileInput.useDelimiter("%");
while (fileInput.hasNext()) {
System.out.println("File opened!"); // Debugging console output
mItem.setTitle(fileInput.next());
mItem.setFormat(fileInput.next());
mItem.setOnLoan(fileInput.nextBoolean());
loanedTo = fileInput.next();
mItem.setLoanedTo(loanedTo != "null" ? loanedTo: null);
itemStr = fileInput.next();
mItem.setDateLoaned(itemStr != "null" ? itemStr : null);
System.out.println(mItem.getTitle() + " (" + mItem.getFormat() + ") " + mItem.isOnLoan() +
" " + (mItem.isOnLoan() ? mItem.getLoanedTo() : "null") + " " +
(mItem.isOnLoan() ? mItem.getDateLoaned() : "null")); // Debugging console output
items.add(mItem);
System.out.println("Item added: " + mItem.getTitle()); // Debugging console output
System.out.println("Number of values in Item: " + items.size()); // Debugging console output
}
System.out.println("Number of values in Item: " + items.size()); // Debugging console output
fileInput.close();
}
}
This is my MediaItem.java file
public class MediaItem {
private String title;
private String format;
private boolean onLoan;
private String dateLoaned;
private String loanedTo;
public MediaItem() {
title = null;
format = null;
onLoan = false;
dateLoaned = null;
loanedTo = null;
}
public MediaItem(String title, String format){
this.title = title;
this.format = format;
this.onLoan = false;
this.dateLoaned = null;
this.loanedTo = null;
}
public void markOnLoan(String name, String date){
if(onLoan)
System.out.println("This title is already loaned to " + loanedTo + " on " + dateLoaned);
else {
this.loanedTo = name;
this.dateLoaned = date;
this.onLoan = true;
}
}
public void markReturned() {
if(!onLoan) {
System.out.println("This title is not currently loaned out");
}else
{
this.onLoan = false;
this.loanedTo = null;
this.dateLoaned = null;
}
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public boolean isOnLoan() {
return onLoan;
}
public void setOnLoan(boolean onLoan) {
this.onLoan = onLoan;
}
public String getDateLoaned() {
return dateLoaned;
}
public void setDateLoaned(String dateLoaned) {
this.dateLoaned = dateLoaned;
}
public String getLoanedTo() {
return loanedTo;
}
public void setLoanedTo(String loanedTo) {
this.loanedTo = loanedTo;
}
}
And this is a sample libraryItems.txt file
%one%DVD%false%null%null
%two%DVD%false%null%null
%three%DVD%false%null%null
From my 'debugging' console output I can tell that in the "public ArrayList listAllItems" method is when the problem is occurring, but I'm not sure why. I have looked at similar questions and they don't seem to be working! A nudge in the right direction is appreciated!
Solution
Your code for item creation resides outside the while
loop in open()
. This results in only one instance per call being created. This instance is repeatedly updated.
You need to move the item creation inside the loop body:
public void open() throws Exception {
try (Scanner fileInput = new Scanner(new File("libraryItems.txt"))) { // try-with resources makes sure that the Scanner is closed even on an error
fileInput.useDelimiter("%");
System.out.println("File opened!"); // Debugging console output
while (fileInput.hasNext()) {
MediaItem mItem = new MediaItem(); // create one item per line
mItem.setTitle(fileInput.next());
mItem.setFormat(fileInput.next());
mItem.setOnLoan(fileInput.nextBoolean());
String loanedTo = fileInput.next();
mItem.setLoanedTo(loanedTo != "null" ? loanedTo: null);
String itemStr = fileInput.next();
mItem.setDateLoaned(itemStr != "null" ? itemStr : null);
System.out.println(mItem.getTitle() + " (" + mItem.getFormat() + ") " + mItem.isOnLoan() +
" " + (mItem.isOnLoan() ? mItem.getLoanedTo() : "null") + " " +
(mItem.isOnLoan() ? mItem.getDateLoaned() : "null")); // Debugging console output
items.add(mItem);
System.out.println("Item added: " + mItem.getTitle()); // Debugging console output
System.out.println("Number of values in Item: " + items.size()); // Debugging console output
}
System.out.println("Number of values in Item: " + items.size()); // Debugging console output
}
}
Answered By - fabian