I am doing a midterm where we have to make a GUI grocery list. The professor is asking us to make the list into a .txt file and read from that file. There is also a delete section and delete all which I haven't coded yet. Usually I test the code whenever I add something new into it. When trying to test this one I noticed that it crashes. The code is writing to the Grocery.txt but isn't showing what is wrote into the list box. I know I am most likely missing something small. When I look at my textbook "Murach's Java programming 6th Edition" It looks almost the same except the example they are using is reading three different things from the file. They are using a array to read. I am trying to place each one on its own line. I know right now it won't. I am trying to test if it reads it at all which currently it isn't.
Update: I changed some of the code around now when I click add I am getting an empty alert box that says error. Updated code is placed. I will be afk for a few hours and will be back to work on it. Thank you for all your help.
FINAL update: found the error it was in my if (errorMsg == " ") { for some reason it wasn't reading it correctly changing it to if(errorMsg.isBlank()) fixed it. Thank you all for your input and I will be better at posting the question whenever I need to post again. The program still won't run correctly but the issue I was having has been fixed and I can figure the rest out myself.
Again thank you and happy programming
Here is my current code:
package com.mycompany.zaph_midterm;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import javafx.application.Application;
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.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class App extends Application {
public TextField addGrocery;
public ListView<String> groceryList = new ListView<>();
@Override
public void start(Stage stage) {
stage.setTitle("Grocery List");
//Setting grid
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setPadding(new Insets(15,15,15,15));
grid.setHgap(10);
grid.setVgap(10);
//attaching grid to scene
Scene scene = new Scene(grid);
//Setting the add section
HBox hbox = new HBox();
GridPane addHbox = new GridPane();
addHbox.add(new Label ("Items: "), 0, 0);
addHbox.add(new Label(" "), 1, 0);
addGrocery = new TextField();
addHbox.add(addGrocery, 2, 0);
Button addButton = new Button("Add");
addButton.setOnAction(event -> addButtonClicked());
addHbox.add(new Label(" "), 3, 0);
addHbox.add(addButton, 4, 0);
hbox.getChildren().add(addHbox);
grid.add(hbox, 0, 0);
//Setting list to show
HBox groceryBox = new HBox();
GridPane groceryGrid = new GridPane();
groceryGrid.add(new Label("List: "), 0, 0);
groceryList.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
groceryList.getItems().add(grocery.readFromFile(addGrocery.getText()));
groceryGrid.add(groceryList, 2, 0);
groceryBox.getChildren().add(groceryGrid);
grid.add(groceryBox, 0, 1);
stage.setScene(scene);
stage.show();
}
// Add button clicked
private void addButtonClicked() {
//Validation of user Input
Validation v = new Validation();
String errorMsg = "";
errorMsg += v.hasValue(addGrocery.getText());
errorMsg += v.isBlank(addGrocery.getText());
// Using if/else to add to grocery List
if (errorMsg.isBlank()){
GroceryList grocery = new GroceryList();
//Adding to Grocery List
grocery.printToFile(addGrocery.getText());
}else {
Alert wrong = new Alert(Alert.AlertType.ERROR);
wrong.setHeaderText("Error");
wrong.setContentText(errorMsg);
wrong.showAndWait();
}
}
public static void main(String[] args) {
launch();
}
Validation class:
package com.mycompany.zaph_midterm;
public class Validation {
private final String lineEnd;
public Validation() {
this.lineEnd = "\n";
}
public Validation(String lineEnd) {
this.lineEnd = lineEnd;
}
public String isBlank(String name) {
String error = "";
if(name.isBlank()) {
error = "Must have groceries in the add text box.";
}
return error;
}// end of isBlank
public String hasValue(String name) {
//if user input is able to be parsed then an error message will return
String error = "";
try {
Double.parseDouble(name);
} catch (NumberFormatException e) {
return error;
}
error ="Text box must only contain letters";
return error;
}
}
GroceryList Class:
package com.mycompany.zaph_midterm;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import static java.lang.System.out;
public class GroceryList {
private String grocery;
public GroceryList() {
grocery = " ";
}
public void setGroceryList(String args){
this.grocery = grocery;
}
public String getGroceryList() {
return grocery;
}
public void printToFile(String grocery) {
//creating file
try (PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter("Grocery.txt")))) {
//writing to file
out.print(grocery);
}
//catching error if found
catch (IOException e){
System.out.println(e);
}
}
public void deleteFromFile(String grocery) {
}
public String readFromFile(String grocery) throws IOException{
try (BufferedReader in = new BufferedReader(
new FileReader("Grocery.txt"))){
String line = in.readLine();
while (line != null){
line = grocery;
return grocery;
}
}
catch (IOException e) {
Alert error = new Alert(Alert.AlertType.ERROR);
error.setHeaderText("Didn't work");
error.setContentText("Something is wrong");
error.showAndWait();
}
return grocery;
}
}
}
I tried moving the try(BufferedReader) to the addButtonCLicked() still crashed so I moved it up under the //setting list to show and it still crashes.
Your Question is unfocused and unclear. But, for fun, I will take a stab at revamping your code.
One big useful concept in programming in separation of concerns. This means organizing your code in separate chunks that each focus on a particular job.
One job is writing your grocery list items to storage, and reading them back. That should be in one specific class. We will call this class
Repository.We need to define the objects to go into the repository. Your
GroceryListclass is ill-conceived as the list is just a collection of items. It is the item we need to define. We can that simply with a record. The one and only job of this class is to represent validated state necessary to represent a grocery item from the real world.The repository needs to save grocery items and retrieve again. The one and only job of this class is the persistent storage and retrieval of our objects’ state. Here we write a simple bogus implementation, good enough to get going.
Write some tests to verify. We expect all “true” results.
All our tests passed.
Tip to the advanced student: In real work, we would write tests using a framework such as Jupiter. Then we run the tests in a test-harness such as JUnit 5.
Now build the GUI in JavaFX implemented as OpenJFX.
With that all working, we can go back to our
Repository. We can rewrite to actually save to a file rather than use our dummy list in memory.Look to the Java NIO classes such as
Path,Paths, andFilesto simplify your file handling.Tip to the advanced student:
Repositoryshould be an interface, with two concrete implementations: one for our in-memory list, another for our file storage.Beware… This file-based
Repositoryhas a bug: User cannot add more than one grocery item. We can deterimine with certainty that the bug lives in this file-basedRepositoryimplementation because we can switch back to the in-memory list based implementation to see the bug disappear. This bug-verification is a big benefit to writing the simpler bogus implementation. I will leave the undiscovered bug in place, as I have already done too much for a schoolwork assignment.Another issue: All our tests pass despite the bug in this file-based implementation. That means our tests are insufficient, and need revision. I will leave that too as an exercise for the reader.