OOP Project

Production Line Tracker with a GUI and database

Problem Statement

Scenario

You have been hired to create software for a media player production facility that will keep track of what products are produced.

Without the software, workers on the production floor are physically producing items and having to write down what is produced in a production log book.

Management would like the production tracking to be more automated so the workers don't need to spend as much time recording what was produced, the log will be more accurate, and it will be easier to generate production reports.

In addition to the ability to record production, the software also needs the ability to add to the product line (the catalog of products that are able to be produced).

  • Goals (high level intended outcomes; for software, a Product Backlog)

    • Hypothetical / Real world

      1. Allow a user to add new products that are able to be produced and store them in a collection.

      2. The collection of products that can be produced can be displayed at any time.

      3. Allow a user to track production of products, including specifying how many items of that product were created. The program will then create a record for each of these items and store them in a collection.

      4. The collection of created items can be displayed at any time.

      5. Production statistics can be displayed – Total items produced, number of each item type, the number of unique products created etc.

      6. Employee accounts can be made.

      7. Allow easy modification to handle different products.

    • Actual / For class

      1. Solidify understanding of object oriented programming.

      2. Practice Java.

      3. Learn basic graphical user interface (GUI) programming.

      4. Learn basic database programming.

  • Boundaries / Scope (where the functions and responsibilities of the solution start and end / what it should do and what is left to other systems to do)

    • Hypothetical / Real world

      • For this particular production facility you will only need to track music and movie players.

      • The program does not need the ability to place or fulfill orders / reduce stock, just track production.

    • Actual / For class

      • TBD

  • Success criteria (set of conditions to be satisfied at completion; must be measurable and verifiable, like a test)

    • Hypothetical / Real world

      • Pass tests (in repl.it)

      • Follow rules for documentation, style, and coding conventions

    • Actual / For class

      • Grading forms / rubrics (in Canvas)

        • Documentation (see below)

        • Style (see below)

        • Quality (see below)

        • Assignment Specifications - include full project in your repository so your program can be easily imported and run.

      • Creation of artifact for portfolio

  • Constraints (externally imposed limitations on system requirements, design, or implementation or on the process used to develop or modify a system)

    • Hypothetical / Real world

      • The program will be a GUI database program written in Java.

      • The program must be flexible to allow for future expansion.

      • Code should be saved to a private GitHub repository.

      • Follow best practices for style, documentation, and quality.

    • Actual / For class

      • Communication and collaboration with classmates is allowed but should not extend to sharing actual code.

  • Assumptions (things that are accepted as true or as certain to happen, without proof)

    • You like to program.

    • You have foundational knowledge of programming from prerequisite courses.

    • You will spend at least 4 hours per week on the project.

    • The project should not require more than 7 hours per week. If so, contact the professor for assistance.

    • This will help you be successful in future classes and your career.

  • Stakeholders (individuals or organizations having a right, share, claim, or interest in a system or in its possession of characteristics that meet their needs and expectations )

    • Hypothetical / Real world

      • CEO

      • CTO

      • CIO

      • users

        • production facility workers

        • inventory managers

      • customers

      • I.T. support

    • Actual / For class

      • Yourself

      • Future potential employers

      • Professor

  • Timelines (a breakdown of the Product Backlog into time-bound smaller, more detailed tasks in Sprint Backlogs)

    • Three 5-week sprints, detailed below.

Program Specifications (General)

Expand sections below for details.

Sprint 1 - GUI, basic database

  • JavaFX program with database connectivity.

Sprint 2 - OOP

  • Pass tests (in repl.it) and include associated functionality within JavaFX program.

    • Use the one time link to join the repl.it classroom on the Canvas course home page.

    • After enrolling, you can just login to repl.it to access.

Sprint 3 - Full database integration and enhancements

  • Pass tests (in repl.it) and include associated functionality within JavaFX program.

  • Satisfy all specifications on this page.

Sprint 1 (Alpha)

GUI, basic database

Week 1 / Week 2

  • Create JavaFX FXML project using Gradle. See IntelliJ page, GUI page, and IntelliJ Help

  • Share to private repository on GitHub. See GitHub page.

  • Create README. Details in Documentation Expectations at bottom of page.

Week 2

  • Add a tab view with three tabs: Product Line, Produce, and Production Log Reference

  • Add a CSS file with some code Reference Tutorial

  • Quality expectations: see bottom of page

  • Style expectations: see bottom of page

  • Documentation expectations: see bottom of page

Week 3

  • In the Product Line tab

    • In the AnchorPane

      • Add a 2x3 GridPane

        • Add a Label and text field for Product Name in row 0, columns 0 and 1

        • Add a Label and text field for Manufacturer in row 1, columns 0 and 1

        • Add a Label and ChoiceBox for Item Type in row 2, columns 0 and 1

      • Add a Button that says Add Product

        • Add an event handler to the button click event. For now, just have it print to the console (System.out.println)

      • Add a Label and a Table View for Existing Products

  • In the Produce tab

    • In the AnchorPane

      • Add a Label and ListView for Choose Product

      • Add a Label and ComboBox (data type String) for Choose Quantity

      • Add a Button that says Record Production

        • For now, just have the button print to the console (System.out.println)

  • In the Production Log tab

    • In the AnchorPane

      • Add a TextArea

Week 4

  • Install database software if necessary

  • Create database in a res folder at same level as src folder

    • Similar to...

create table Product

(

id int auto_increment,

name varchar,

type varchar,

manufacturer varchar

);


create unique index Product_id_uindex

on Product (id);


alter table Product

add constraint Product_pk

primary key (id);


create table ProductionRecord

(

production_num int auto_increment,

product_id int,

serial_num varchar,

date_produced datetime

);

  • Connect to database

    • If not using Gradle or Maven, to make your program more portable, copy the H2 driver jar file from its install location (likely Program Files (x86) H2 bin), paste it into your res folder, and set this location in the IntelliJ Project Structure (Modules -> Dependencies).

  • You will get a FindBugs error for not having a password or including the password. Eventually you will retrieve the password from another file but you don't need to worry about this for now.

  • Make sure to commit and push your res folder to the remote repository.

Week 5

  • Use a controller for almost all code.

  • In the Product Line tab, for the Add Product button event handler, add code to insert a product into the database

    • As an incremental step for testing, you can hard code this statement INSERT INTO Product(type, manufacturer, name) VALUES ( 'AUDIO', 'Apple', 'iPod' ); See JDBC - Insert Records Example

    • Once that works, build the sql statement by getting the values from the user interface. video

    • To avoid a FindBugs error, use a Prepared Statement. See JDBC PreparedStatement. video

    • For now, every time a product is added to the database, output the full list of products to the console.

  • In the Produce tab, for the ComboBox

    • Populate with values 1-10 in an initialize method in the Controller

    • To allow the users to enter other values in the combobox, call the method setEditable(true);

    • To show a default value, call the method getSelectionModel().selectFirst();

  • Prepare for submission

Sprint 2 (Beta)

OOP

Week 6 Enum, Interface, Abstract Class

Issue 1 - Product

All items will have a pre-set type. Currently there are 4 types. Create an enum called ItemType that will store the following information:

Type Code

Audio AU

Visual VI

AudioMobile AM

VisualMobile VM

  • See Enum Types The Java™ Tutorials

  • In the Product Line tab

    • Fill the ChoiceBox with the types. You can use an enhanced for loop or addAll. All the constants of an enum type can be obtained by calling the implicit public static T[] values() method.

    • Update your code to insert a product to use the choicebox selected item.

Create an interface called Item that will force all classes to implement the following functions:

  • A method getId that would return an int

  • A method setName that would have one String parameter

  • A method getName that would return a String

  • A method setManufacturer that would have one String parameter

  • A method getManufacturer that would return a String

  • See Java - Interfaces tutorialspoint

Create an abstract type called Product that will implement the Item interface. Product will implement the basic functionality that all items on a production line should have. Add the following fields to Product

  • int id

  • ItemType type

  • String manufacturer

  • String name

Complete the methods from the interface Item.

Add a constructor that will take in the name, manufacturer, and type of the product and set them to the field variables.

Add a toString method that will return the following: (example data shown).

Name: iPod

Manufacturer: Apple

Type: AM

To test the Product class, temporarily create a Widget class that extends Product. Store a created Widget object to the database and a productLine collection.

Week 7 Inheritance

Issue 2 - AudioPlayer

MultimediaControl

All of the items on this production line will have basic media controls. Create an interface called MultimediaControl that will define the following methods which don't need to return anything.

    • play()

    • stop()

    • previous()

    • next();

AudioPlayer

We require a concrete class that will allow us to capture the details of an audio player. Create a class called AudioPlayer that is a subclass of Product and implements the MultimediaControl interface.

The class will have 2 fields

    • String supportedAudioFormats

    • String supportedPlaylistFormats

Create a constructor that will take in 4 parameters – name, manufacturer, supportedAudioFormats, and supportedPlaylistFormats.

The constructor should call its parent's constructor and also setup the media type to AUDIO.

Implement the methods from the MultimediaControl interface by simply writing the action to the console.

E.g. in play System.out.println("Playing"); Normally we would have code that would instruct the media player to play, but we will simply display a message.

Create a toString method that will display the superclass's toString method, but also add rows for supportedAudioFormats and supportedPlaylistFormats.

Week 8 Polymorphism

Issue 3 - MultimediaControl

MonitorType

The production facility will also create portable movie players. The main difference between these and the audio players is that they contain screens. Create an enum called MonitorType that will store

Type

LCD

LED

ScreenSpec

Create an interface called ScreenSpec. This will define 3 methods:

    • public String getResolution();

    • public int getRefreshRate();

    • public int getResponseTime();

Screen

Create a class called Screen that implements ScreenSpec. Add three fields

    • String resolution

    • int refreshrate

    • int responsetime

Complete the methods from the ScreenSpec interface.

Add a toString method that will return the details of the 3 fields in the same format as the Product class.

MoviePlayer

Create a class called MoviePlayer that extends Product and implements MultimediaControl.

Add 2 fields to this class called screen and monitorType and assign appropriate types to them.

Create a constructor that accepts the name, manufacturer, a screen, and a monitor type. The constructor can set the item type to VISUAL.

Complete the methods from the MultimediaControl interface in a similar fashion to the AudioPlayer.

Create a toString method that calls the Product toString and displays the monitor and the screen details.

MultimediaControl

The audio players and the movie players share the same control interface on the physical devices. The control interface does not care if the device is a video player or an audio player. Below is a driver that will demonstrate that any class that implements the MultimediaControl Interface would be able to be instantiated and use its methods used no matter if it was an audio or movie player.

LO. Define and use iterators and other operations on aggregates.

GUI Update:

  • Demonstrate this functionality in your user interface. For example, you could use the code below and call testMultimedia in your initialize method or you could do something more elaborate in the GUI.

public static void testMultimedia() {

AudioPlayer newAudioProduct = new AudioPlayer("DP-X1A", "Onkyo",

"DSD/FLAC/ALAC/WAV/AIFF/MQA/Ogg-Vorbis/MP3/AAC", "M3U/PLS/WPL");

Screen newScreen = new Screen("720x480", 40, 22);

MoviePlayer newMovieProduct = new MoviePlayer("DBPOWER MK101", "OracleProduction", newScreen,

MonitorType.LCD);

ArrayList<MultimediaControl> productList = new ArrayList<MultimediaControl>();

productList.add(newAudioProduct);

productList.add(newMovieProduct);

for (MultimediaControl p : productList) {

System.out.println(p);

p.play();

p.stop();

p.next();

p.previous();

}

}

Week 9 Polymorphism

Issue 4 - ProductionRecord

Create a ProductionRecord class with int fields for productionNumber (this will be unique for every item produced and get auto incremented by the database), an int field for productID (to correspond to the productID from the Product table / class), String field for serialNumber, and a field for the dateProduced that is type Date (from java.util).

Create accessors and mutators for all fields.

Make one constructor that just has a parameter for the productID. This will be the constructor called when the user records production from the user interface.

In this constructor,

  • Set the productionNumber to 0 (because the database will end up auto-incrementing).

  • Set the serialNumber to "0" for now.

  • Set the date to the current date using new Date().

Create an overloaded constructor to use when creating ProductionRecord objects from the database. This constructor needs parameters for all fields.

Override toString to return a string in the format "Prod. Num: 0 Product ID: 0 Serial Num: 0 Date: Mon Oct 14 10:29:48 UTC 2019"

Display the production record in the TextArea on the Production Log tab.

Security / FindBugs tip: Defensive copying

Week 10 Encapsulation

Issue 5 - Production enhancement

Add the ability for the program to generate a unique serial number for each produced product.

  • Overload the ProductionRecord constructor to accept a Product and an int which holds the count of the number of items of its type that have been created. (You can write the code to generate the count later.)

  • Set the serialNumber to start with the first three letters of the Manufacturer name, then the two letter ItemType code, then five digits (with leading 0s if necessary) that are unique and sequential for the item type. The entire Serial Number should be programmatically created and assigned.

  • Optional (for now) challenge: Show the product name instead of the product ID in the TextArea on the Production Log tab.

Week 11 Lists and ArrayLists

Issue 6 - TableView

Show all Products in the Product Line tab TableView. See http://tutorials.jenkov.com/javafx/tableview.html and TableViewData sample program.

  • Create an ObservableList named productLine to hold all of the Products that can be produced. For now, when the Add Product button is clicked, add to this list.

  • Set the items of the TableView to the ObservableList

    • You can do this in a setupProductLineTable method that also sets the columns and does the setCellValueFactory

Show all Products in the Produce tab ListView.

  • Use the selected item from the ListView as the item used to record production.

Show the production log in the Production Log tab TextArea.

Sprint 3 (Release)

Full database integration and enhancements

Week 12 Lambda Expressions

Issue 7 - Compare Products and Full Database Integration

Make sure the H2 driver jar file (usually located in Program Files (x86) H2 bin) is copied into your res folder and that location is set in the IntelliJ Project Structure (Modules -> Dependencies).

Controller initialize method should do things that you want to happen once when the program starts:

  1. define the ObservableList (it can be declared at class level)

  2. call setupProductLineTable

  3. associate the ObservableList with the Product Line ListView

  4. call loadProductList

  5. call loadProductionLog

Add Product button should:

  1. insert added product into database

  2. call loadProductList

loadProductList method should:

  1. Create Product objects from the Product database table and add them to the productLine ObservableList (which will automatically update the Product Line ListView).

  2. Sample code to read from a database, create an object, and save to list

Record Production button should:

  1. Get the selected product from the Product Line ListView and the quantity from the comboBox.

  2. Create an ArrayList of ProductionRecord objects named productionRun.

  3. Send the productionRun to an addToProductionDB method. (Tip: use a TimeStamp object for the date)

  4. call loadProductionLog

  5. call showProduction

showProduction should:

  1. populate the TextArea on the Production Log tab with the information from the productionLog, replacing the productId with the product name, with one line for each product produced

The addToProductionDB method should:

  1. Loop through the productionRun, inserting productionRecord object information into the ProductionRecord database table.

The loadProductionLog method should:

  1. Create ProductionRecord objects from the records in the ProductionRecord database table.

    1. Tip: make a deep copy to avoid a "Malicious code vulnerability - May expose internal representation by incorporating reference to mutable object" bug.

  2. Populate the productionLog ArrayList

  3. call showProduction

Week 13 Strings, Regular Expressions

Issue 8

Set a database password and read the password from a file.

The program is required to create an audit trail of the production line so that it records which employee recorded production. To accomplish this you will need to create a class and tab named Employee that will allow the user to input their full name and then create a user id of their first name, a period, and then their surname, an email address of their first initial and last name.

The class will have 4 fields

  • StringBuilder name;

  • String username;

  • String password;

  • String email;

The class will have the following methods defined:

  • private void setUsername

  • private boolean checkName

  • private void setEmail

  • private boolean isValidPassword

The constructor will accept a String for name (firstname and surname) and String for password.

The constructor will call checkName to check if the name contains a space. If it does, it will call setUsername and setEmail, passing the name in to both. If it doesn't contain a space, set the username to "default" and the email to "user@oracleacademy.Test"

setUsername will set the username field to the first initial of the first name and then the last name, all lowercase.

setEmail will set the email field to the first name, then a period, then the last name (all lowercase) followed by @oracleacademy.Test

The constructor will call isValidPassword. If the password is valid (containing a lowercase letter, uppercase letter, and a special character) the password field gets set to the supplied password. If the password is invalid, the password field gets set to "pw".

Overload toString to produce:

Employee Details

Name : Tim Lee

Username : tlee

Email : tim.lee@oracleacademy.Test

Initial Password : aBcd!

Week 14 Recursion, Modules

Issue 9

To ensure that sensitive information is not leaked it is important that the information saved to file is encoded. To meet these regulations you need to add a method that will reverse the order of the text stored for the database password. This should be done recursively using a method named reverseString().

The following new methods have to be defined:

  • public String reverseString(String pw)

Week 15 Quality Review and Deployment

Issue 10

Make enhancements related to Human User Factors including Input and Output, Error Messages, and Software Robustness. Program should gracefully handle conditions like empty textboxes, strings input instead of numbers, missing database, missing jar, etc.

Additional Optional Challenges


Sorting and Searching

  • Add functionality to your classes that would allow them to be sorted by name with the Collections.sort method.

  • Add functionality to your user interface to show production based on factors like product type, manufacturer, name, etc.

deptId

An additional piece of information is required to be produced for the auditing with the users department information being required as well. The department code is made up of four letters and two numbers.

The format of the department code is the first letter must be in uppercase with the following three all being lowercase and no spaces.

The following three fields need to be added to the EmployeeInfo class:

  • String deptId;

  • Pattern p;

  • Scanner in;

The following new methods have to be defined:

  • public String getDeptId()

  • private void setDeptId()

  • private String getId()

  • private boolean validId(String id)

As there will be multiple inputs across the class now the scanner will need to be declared and closed in the constructor. The pattern to control the format of the input will also have to be declared in the constructor. In between opening and closing the scanner, the constructor will need to not only get the name but also the deptId of the user.

setDeptId() will call getDeptId() to get the id from the user before validId() is used to check if the input matches the pattern. If the pattern matches then the given id is set to deptId otherwise a default value of None01 should be assigned.

As there are now two values to be displayed (code, deptId) create a toString() method that will override the output and allow you to simply display the value of the object to the screen.

Update the TestProductionLine class to use the toString() method to display the values to the console.

printType

Create a static method called printType in Product that will iterate through your Collection and print all the classes of a particular type.

Example – print only AudioPlayer classes in the collection.

For an extra bonus you could modify it so that it would accept the Class that you want to print in the parameter list. This way we could use it against classes that we have not yet built.

Limit the collection to only use subclasses of Product.

Quality and Security Expectations

  • Code Inspection

    • Review SWEBOK Ch. 13 section 17.

    • In IntelliJ IDEA, Analyze -> Inspect Code should find no warnings.

      • Optionally, increase strictness in Settings/Preferences | Editor | Code Inspections | Java.

  • Other

    • All code that could cause an exception should be in a try.

Structure / Style Expectations

  • Google Style

    • Follow the Google Java Style Guide

    • Download the Style Guide from https://github.com/google/styleguide, unzip it, then import intellij-java-google-style.xml into IntelliJ through File -> Settings -> Code Style -> Scheme -> Gear icon -> Import Scheme -> IntelliJ IDEA code style XML

    • Use Ctrl + Alt + L to auto format.

  • Naming

    • When specified, name everything exactly as instructed.

    • When not specified, give descriptive names using proper naming conventions.

  • CheckStyle

    • Use the CheckStyle plugin. File -> Settings -> Plugins -> type checkstyle in search box -> click Search in repositories.

    • Once installed, you should see CheckStyle at the bottom left of the window. Click it. Choose Google Checks in the dropdown box for Rules. Click the button to Check Project.

  • Blank Lines

    • Use single blank lines between methods and where it improves readability. No multiple consecutive blank lines.

Documentation / Comments Expectations

Comments

  • Comments in code that describe non-obvious code.

  • Cite any resources used such as web sites, classmates, etc.

Javadoc Comments

Write Javadoc style comments for all classes and methods including:

  • Description

    • A required component of every doc.

    • The first sentence (end in a period). It should be a summary sentence, concise but complete.

    • Optionally, include an additional <p> tag and a longer description.

  • Block tags:

    • At a minimum, include the following:

      • For a class

      • For a method

        • @param - a description of the parameter variable, if there is one

        • @return - a description of the returned value, if the method returns something

  • More comprehensive information: How to Write Doc Comments

Sample doc comments in a class

/**

* Represents a student enrolled in the school.

* A student can be enrolled in many courses.

* @author Your Name

*/

public class Student {


/**

* The first and last name of this student.

*/

private String name;

/**

* Gets the first and last name of this Student.

* @return this Student's name.

*/

public String getName() {

return name;

}


/**

* Changes the name of this Student.

* This may involve a lengthy legal process.

* @param newName This Student's new name.

* Should include both first

* and last name.

*/

public void setName(String newName) {

name = newName;

}

}

Assignment Specifications

Required for Final Submission Only

README

  • A README.md file on your repository root page containing information about the program that follows the README-TEMPLATE.

    • If your repository doesn't already have one, there is a button on the bottom of the page on GitHub to add one. After adding a readme on GitHub you should Pull in IntelliJ.

  • IntelliJ has some built-in markdown tools and there are Markdown and Markdown Navigator plugins available or you can use StackEdit and reference Mastering Markdown

Javadoc

  1. Tools -> Generate Javadoc

    1. Box to Include JDK should be unchecked

    2. Box for @author should be checked

    3. Output directory should be a docs folder in your project at the same level as the src folder.

    4. If you get an error, check that the Project SDK is set in Settings | Project Structure

  2. Include generated external Javadoc in repository.

    1. Make sure to include the docs folder when you commit and push.

    2. Set the docs folder to use GitHub Pages in the repository Settings. (repo must be public)

    3. Add a link to index.html file in your Readme.

Diagrams

Add as images in README

  • Class Diagrams

    • From the IntelliJ plugin (or StarUML)

    • IntelliJ: Right click package folder -> Diagrams -> Show Diagram -> Java Class Diagrams

    • If you don't have a package, add one by right clicking the src folder and choosing New -> Package then drag your .java files into it, leaving option boxes unchecked.

    • If you don't see Diagrams...

      • The plugin is available on Ultimate edition only.

      • It is installed by default but if you don't have it you can add it through File -> Settings -> Plugins -> search UML Support.

    • Only include your classes in the diagram.

    • Save the diagram as an image.

  • Database Diagram

    • Right click database in Database tab -> Diagrams -> Show Visualization

    • Only include your database tables in the diagram.

    • Save the diagram as an image.

Human User Factor Expectations

  • General Human User Factor information

  • Specific implementations for this project:

    • Combobox and choicebox should have a default value selected. Combobox should handle non-numeric input.

    • Incomplete input should not be stored. For example, if the Add Product button is clicked but a Product Name wasn't entered in the textbox, the user should be notified and focus should go to the textbox.

    • Users should be notified if the database connection isn't available and when operations succeed or fail.

Resources