SmolinskiW_Program09.java
/**
* William Smolinski
* CISS 111
* Program09 - Uses a GUI to simulate a store and buying shirts
*/
package com.example.smolinskiw_program09;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Scanner;
public class SmolinskiW_Program09 extends Application {
@Override
public void start(Stage stage) throws IOException
{
//Array to hold the total for each size
int[] sizeQuantities = new int[6];
//Array to hold the prices for each size
double[] sizePrices = new double[6];
//PRIMARY SCENE ----------------------------------------------------------
//Creating the MenuBar
MenuBar menuBar = new MenuBar();
Menu helpMenu = new Menu("Help");
MenuItem help = new MenuItem("Open Help");
helpMenu.getItems().add(help);
menuBar.getMenus().add(helpMenu);
BorderPane borderPane = new BorderPane();
borderPane.setTop(menuBar);
//TextField to get the quantity to buy
TextField quantity = new TextField("Quantity");
quantity.setPrefSize(100, 35);
//Sets up the combo boxes to select sizes
ComboBox selectSizes = new ComboBox();
selectSizes.getItems().addAll("XS", "S", "M", "L", "XL", "XXL");
selectSizes.setPrefSize(75, 35);
//Button to add the quantity to your order
Button addButton = new Button("Add");
addButton.setPrefSize(100, 35);
HBox mainActions = new HBox(quantity, selectSizes, addButton);
mainActions.setSpacing(20);
//Creates labels to show the cart history for the last 5 quantities
Label historyTitle = new Label("History:");
Label history = new Label();
history.setMaxHeight(100);
history.setMaxWidth(300);
//history.setBackground(new Background(new BackgroundFill(Color.BLUE, CornerRadii.EMPTY, Insets.EMPTY)));
//Creates the buttons to view the cart
Button viewCart = new Button("View Cart");
viewCart.setPrefSize(100, 35);
//Creates the label and button for getting the file to get the prices from
Label selectedFile = new Label();
selectedFile.setMinSize(195, 35);
selectedFile.setMaxSize(195, 35);
selectedFile.setAlignment(Pos.CENTER_LEFT);
selectedFile.setText("FILE:");
Button changeFile = new Button("Change");
changeFile.setPrefSize(100, 35);
FileChooser fileChooser = new FileChooser();
HBox fileSection = new HBox(selectedFile, changeFile);
fileSection.setSpacing(20);
//VBox to organize the scene
VBox mainSceneLayout = new VBox(mainActions, historyTitle, history, viewCart, fileSection);
mainSceneLayout.setSpacing(10);
mainSceneLayout.setPadding(new Insets(10));
borderPane.setCenter(mainSceneLayout);
//Creates the scene
Scene mainScene = new Scene(borderPane, 340, 325);
//Applying the stylesheet
var result = mainScene.getStylesheets().add("myStyle.css");
historyTitle.getStyleClass().add("label-title");
history.getStyleClass().add("label-main");
selectedFile.getStyleClass().add("label-main");
addButton.getStyleClass().add("button-main");
changeFile.getStyleClass().add("button-main");
viewCart.getStyleClass().add("button-main");
selectSizes.getStyleClass().add("combo-box-main");
quantity.getStyleClass().add("text-field-main");
//SECONDARY SCENE------------------------------------------------------------------
//Creating the MenuBar for the secondary scene
MenuBar menuBar2 = new MenuBar();
Menu helpMenu2 = new Menu("Help");
MenuItem help2 = new MenuItem("Open Help");
helpMenu2.getItems().add(help2);
menuBar2.getMenus().add(helpMenu2);
BorderPane borderPane2 = new BorderPane();
borderPane2.setTop(menuBar2);
//Label to display the information about the order
Label sizesAndTotals = new Label();
//Creates the buttons for the secondary scene
Button secondarySceneBackButton = new Button("Back");
secondarySceneBackButton.setPrefSize(100, 35);
Button getReceipt = new Button("Receipt");
getReceipt.setPrefSize(100, 35);
Button clear = new Button("Clear");
clear.setPrefSize(100, 35);
HBox bottomButtons = new HBox(secondarySceneBackButton, clear, getReceipt);
bottomButtons.setSpacing(25);
bottomButtons.setAlignment(Pos.CENTER);
//VBox to organize the scene
VBox secondarySceneLayout = new VBox(sizesAndTotals, bottomButtons);
secondarySceneLayout.setPadding(new Insets(10));
secondarySceneLayout.setSpacing(10);
borderPane2.setCenter(secondarySceneLayout);
Scene secondaryScene = new Scene(borderPane2, 340, 300);
//Applying the stylesheet
var result2 = secondaryScene.getStylesheets().add("myStyle.css");
sizesAndTotals.getStyleClass().add("label-main");
secondarySceneBackButton.getStyleClass().add("button-main");
getReceipt.getStyleClass().add("button-main");
clear.getStyleClass().add("button-main");
//Changes the stage to the main scene
secondarySceneBackButton.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
stage.setScene(mainScene);
}
});
//HELP SCENE-------------------------------------------------------------------
//Borderpane for the help scene
BorderPane helpSceneBorderpane = new BorderPane();
//Creates the back button
Button helpBackButton = new Button("Back");
helpBackButton.setPrefSize(100, 35);
//Displays the text in the help scene
Label displayHelp = new Label("Program09 by: William Smolinski\n" +
"\nHOW TO USE:\n" +
"\n1. Enter a number for the quantity and a size then hit the add button\n" +
"\n2. It will give an error or tell you the result of the operation in the history section\n" +
"\n3. Make sure you select a file at the bottom to use for prices\n" +
"\n4. You can open the cart to view more details about your order and check out");
//VBox to organize the scene
VBox helpSceneLayout = new VBox(displayHelp, helpBackButton);
helpSceneLayout.setSpacing(10);
helpSceneLayout.setPadding(new Insets(10));
helpSceneBorderpane.setCenter(helpSceneLayout);
Scene helpScene = new Scene(helpSceneBorderpane, 600, 400);
//Applying the stylesheet
var result3 = helpScene.getStylesheets().add("myStyle.css");
displayHelp.getStyleClass().add("label-help");
helpBackButton.getStyleClass().add("button-main");
//Changes the stage to the help scene
help.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
stage.setScene(helpScene);
}
});
//Changes the stage back to the main scene
helpBackButton.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
stage.setScene(mainScene);
}
});
//MAIN EVENT HANDLERS---------------------------------------------------------------
//Handles adding new quantities to the cart
addButton.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
int quantityNum = 0;
boolean validInput = false;
String selectedSize = "";
//Checks to see if a valid number was entered for the quantity
try
{
quantityNum = Integer.parseInt(quantity.getText());
validInput = true;
}
catch (Exception e)
{
history.setText("INVALID NUMBER\n" + history.getText());
}
if(selectSizes.getValue() != null)
{
selectedSize = (String)selectSizes.getValue();
}
else
{
history.setText("NO SIZE SELECTED\n" + history.getText());
validInput = false;
}
int index = getSizeIndex(selectedSize);
//Quantity can't be more than 1 million for one item to keep output looking clean
// (and it isn't practical to buy 1 million shirts)
if(sizeQuantities[index] + quantityNum >= 1000000)
{
history.setText("TOO MANY OF THIS SIZE\n" + history.getText());
validInput = false;
}
if(validInput)
{
String labelText = "";
//Clears the size
if(quantityNum == 0)
{
sizeQuantities[index] = 0;
labelText = selectedSize + " Cleared\n";
}
else if(quantityNum < 0) //Takes away the quantity entered
{
//Can't have a negative quantity
if(sizeQuantities[index] + quantityNum <= 0)
{
sizeQuantities[index] = 0;
labelText = selectedSize + " Cleared\n";
}
else
{
sizeQuantities[index] += quantityNum;
labelText = selectedSize + ": " + (sizeQuantities[index] - quantityNum) + " - " +
(quantityNum * -1) + " = " + sizeQuantities[index] + "\n";
}
}
else //Adds the quantity
{
sizeQuantities[index] += quantityNum;
labelText = selectedSize + ": " + (sizeQuantities[index] - quantityNum) + " + " +
quantityNum + " = " + sizeQuantities[index] + "\n";
}
history.setText(labelText + history.getText());
}
}
});
//Changes the stage to the secondary scene and updates the cart info
viewCart.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
//Check if valid file is selected and update text in secondary scene
stage.setScene(secondaryScene);
sizesAndTotals.setText(getNeatOutput(sizeQuantities, sizePrices));
}
});
//Clears the cart
clear.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
//Clears the array
for(int i = 0; i < 6; i++)
{
sizeQuantities[i] = 0;
}
history.setText("CLEARED\n" + history.getText());
sizesAndTotals.setText(getNeatOutput(sizeQuantities, sizePrices));
}
});
//Handles changing and checking the file for prices
changeFile.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
//Set to null to initialize
File priceFile = null;
//Set to null to initialize
Scanner inputFile = null;
boolean validFile = false;
boolean choseAFile = false;
//Gets a file from the fileChooser
//try-catch used to that when the user exits the fileChooser it doesn't give a massive error to the console
try
{
priceFile = fileChooser.showOpenDialog(stage);
selectedFile.setText(priceFile.getName());
choseAFile = true;
}
catch(Exception e)
{
//No file selected
}
//Determines if the file is valid
if(choseAFile)
{
try
{
inputFile = new Scanner(priceFile);
validFile = true;
}
catch(Exception e)
{
history.setText("INVALID FILE\n" + history.getText());
}
}
String line;
double price;
//Used to make sure all sizes are gathered
boolean hasSizePrice[] = new boolean[6];
//Handles reading the file
if(validFile)
{
//Designed to take input in the format of the file provided in the assignment
while (inputFile.hasNext())
{
line = inputFile.nextLine();
price = getPrice(line);
//If a valid number is in the file in the correct format
if(price >= 0)
{
//If the line contains the size, the price gathered from that line will be the price for the size
//It will change the price if there is duplicate sizes with prices
//For example you could have 2 lines of XS with the top one being 10.00 and the bottom 11.00
//and the price will be set to 11.00
if(line.contains("XS"))
{
sizePrices[0] = price;
hasSizePrice[0] = true;
}
else if(line.contains("S"))
{
sizePrices[1] = price;
hasSizePrice[1] = true;
}
else if(line.contains("M"))
{
sizePrices[2] = price;
hasSizePrice[2] = true;
}
else if(line.contains("XXL"))
{
sizePrices[5] = price;
hasSizePrice[5] = true;
}
else if(line.contains("XL"))
{
sizePrices[4] = price;
hasSizePrice[4] = true;
}
else if(line.contains("L"))
{
sizePrices[3] = price;
hasSizePrice[3] = true;
}
}
}
boolean allSizes = true;
int count = 0;
//Loops through to make sure all sizes have a price
while(allSizes && count < hasSizePrice.length)
{
if(!hasSizePrice[count])
{
allSizes = false;
}
else
{
count += 1;
}
}
//Outputs to history if not all prices were gathered
if(!allSizes)
{
history.setText("NOT ALL SIZE PRICES GATHERED\n" + history.getText());
}
else
{
history.setText("FILE SUCCESSFULLY GATHERED\n" + history.getText());
}
inputFile.close();
}
}
});
getReceipt.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent actionEvent)
{
//Set to null to initialize
File outputFile = null;
PrintWriter writeToFile = null;
boolean validFile = false;
boolean choseAFile = false;
//In a try-catch to prevent a massive error from being printed to the console when the user exits the file chooser
try
{
//Lets the user choose a file for output
outputFile = fileChooser.showOpenDialog(stage);
//Makes sure the file is a .txt so that you don't mess up any other files on your system on accident
if(outputFile.getName().endsWith(".txt"))
{
validFile = true;
}
else
{
history.setText("NOT .txt FILE\n" + history.getText());
}
choseAFile = true;
}
catch (Exception e)
{
//No file selected
}
if(choseAFile)
{
//Makes sure a valid file is chosen for output
try
{
writeToFile = new PrintWriter(outputFile);
}
catch(Exception e)
{
history.setText("INVALID OUTPUT FILE\n" + history.getText());
validFile = false;
}
}
//Writes the neat output to the file
if(validFile)
{
writeToFile.println(getNeatOutput(sizeQuantities, sizePrices));
writeToFile.close();
//This also clears history
history.setText("RECEIPT PRINTED");
//Clears the cart and sets you back to the main screen
//Clears the array
for(int i = 0; i < 6; i++)
{
sizeQuantities[i] = 0;
}
sizesAndTotals.setText(getNeatOutput(sizeQuantities, sizePrices));
stage.setScene(mainScene);
}
}
});
//ON START-----------------------------------------------------
//Sets the main scene to the stage
stage.setScene(mainScene);
//Sets the title and shows the stage
stage.setTitle("SmolinskiW_Program09");
stage.show();
}
public static void main(String[] args)
{
launch();
}
/**
* Method to get the index in the array for each size based on the String of the size name
* @param size String of the size name
* @return Returns the index in the array of that size as an int
*/
public static int getSizeIndex(String size)
{
if(size.equals("XS"))
{
return 0;
}
else if(size.equals("S"))
{
return 1;
}
else if(size.equals("M"))
{
return 2;
}
else if(size.equals("L"))
{
return 3;
}
else if(size.equals("XL"))
{
return 4;
}
else
{
return 5;
}
}
/**
* Method to update the text of the cart
* @param quantities int Array with the quantities of each size
* @param prices int Array with the prices of each size
* @return Returns a String with the output formatted nicely
*/
public static String getNeatOutput(int[] quantities, double[] prices)
{
double totalWithTax = 0;
//Gets the total with tax
for(int i = 0; i < prices.length; i++)
{
totalWithTax += (prices[i] * quantities[i]);
}
totalWithTax *= 1.08;
return (String.format("%s\t%10s\t%10s%.2f", "XS: ", quantities[0], " $", (prices[0] * quantities[0])) + "\n" +
String.format("%s\t%10s\t%10s%.2f", "S: ", quantities[1], " $", (prices[1] * quantities[1])) + "\n" +
String.format("%s\t%10s\t%10s%.2f", "M: ", quantities[2], " $", (prices[2] * quantities[2])) + "\n" +
String.format("%s\t%10s\t%10s%.2f", "L: ", quantities[3], " $", (prices[3] * quantities[3])) + "\n" +
String.format("%s\t%10s\t%10s%.2f", "XL: ", quantities[4], " $", (prices[4] * quantities[4])) + "\n" +
String.format("%s\t%10s\t%10s%.2f", "XXL: ", quantities[5], " $", (prices[5] * quantities[5])) + "\n" +
String.format("\nTotal (with 8%s tax): $%.2f", "%", totalWithTax));
}
/**
* Method to get the price of the size from the line
* @param line String of the line in the file to get the price from
* @return Returns the price as a double
*/
public static double getPrice(String line)
{
String[] splitLine = line.split(" ");
try
{
return Double.parseDouble(splitLine[1]);
}
catch(Exception e)
{
//Invalid file format
return -1;
}
}
}