diff --git a/Bachelor_application.iml b/Bachelor_application.iml index b94cb914ec5ad223d705dca95552625827a51c34..68b64f9b614a6846b669043a8fa892222a344d73 100644 --- a/Bachelor_application.iml +++ b/Bachelor_application.iml @@ -55,16 +55,15 @@ <orderEntry type="library" name="Maven: com.google.auto.value:auto-value-annotations:1.9" level="project" /> <orderEntry type="library" name="Maven: org.apache.commons:commons-math3:3.6.1" level="project" /> <orderEntry type="library" name="Maven: joda-time:joda-time:2.10.14" level="project" /> - <orderEntry type="library" name="Maven: org.jblas:jblas:1.2.4" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.13.2" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" /> - <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.8.2" level="project" /> - <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.8.2" level="project" /> + <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter:5.9.0-M1" level="project" /> + <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-api:5.9.0-M1" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.opentest4j:opentest4j:1.2.0" level="project" /> - <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.8.2" level="project" /> + <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-commons:1.9.0-M1" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.apiguardian:apiguardian-api:1.1.2" level="project" /> - <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.8.2" level="project" /> - <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.8.2" level="project" /> - <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.8.2" level="project" /> + <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-params:5.9.0-M1" level="project" /> + <orderEntry type="library" scope="TEST" name="Maven: org.junit.jupiter:junit-jupiter-engine:5.9.0-M1" level="project" /> + <orderEntry type="library" scope="TEST" name="Maven: org.junit.platform:junit-platform-engine:1.9.0-M1" level="project" /> </component> </module> \ No newline at end of file diff --git a/README.md b/README.md index c1f9c8a9d8e011fa3d05d8bd02888010eb10349b..92f4df5a59ea8ce8f546ab3f4beb2d55e784009a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,20 @@ -Bachelor oppgave vår 2022 -Awesome teamates: +#Bachelor Thesis Spring 2022 + +This application visualize live- and historical data and calculates an estimate based on logistic regression that the drying operator can choose to follow in order to minimize over-drying. + + +The development team: +* #### Eilert Tunheim +* #### Mads Greni Arnesen +* #### Karin Pettersen + +Link to repo: https://git.gvk.idi.ntnu.no/mesji/bacheloroppgave_2022 + +## Deployment Instructions + +The java .jar file is located under `out\artifacts\Bachelor_application` + +In order to run the jar file, please use the following command: + +`java -jar Bachelor_application.jar` -Karin -Mads -Eilert diff --git a/pom.xml b/pom.xml index 3c4734f99a5c9efa149b22a301fdc4202bb2bbcc..ecb90099b8ac40d3b21e2a487b8ae3290d4f5c9f 100644 --- a/pom.xml +++ b/pom.xml @@ -40,14 +40,8 @@ <artifactId>joda-time</artifactId> <version>2.10.14</version> </dependency> - <dependency> - <groupId>org.jblas</groupId> - <artifactId>jblas</artifactId> - <version>1.2.4</version> - </dependency> <!-- https://mvnrepository.com/artifact/org.openjfx/javafx --> - <dependency> <groupId>org.openjfx</groupId> <artifactId>javafx</artifactId> @@ -72,8 +66,6 @@ <version>RELEASE</version> <scope>test</scope> </dependency> - - </dependencies> <properties> diff --git a/src/main/java/com/application/DB/AccountHandler.java b/src/main/java/com/application/DB/AccountHandler.java index 7c38d7daa53a7fb829153700face33bd79ae1e1b..a1cdbb126517c3455a67dbe9b2cfc36afbcd4986 100644 --- a/src/main/java/com/application/DB/AccountHandler.java +++ b/src/main/java/com/application/DB/AccountHandler.java @@ -5,12 +5,24 @@ import com.application.GUI.PopUpWindows.NotificationPopUp; import com.google.cloud.bigquery.FieldValueList; import com.google.cloud.bigquery.TableResult; -import static com.application.DB.Constants.*; import static com.application.DB.Settings.*; import static com.application.GUI.PopUpWindows.LoginPopup.getPasswordTextField; +/** + * This class handles the login system and all related functionality + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class AccountHandler { + /** + * This function iterates through the results and sets the information + * + * @param username input parameter for the username + * @param password input parameter for the password + * @throws Exception throws exception if anything goes wrong + */ public static void getAccountInformation(String username, String password) throws Exception { TableResult result = logIn(username,password); @@ -20,19 +32,19 @@ public class AccountHandler { if (row.get("Username").getValue().equals(username)) { CreateLogoBar.getLogin().setText(username); - setUserName(username); + HelpingFunctions.setUserName(username); if (!row.get("Phone_no").isNull()) { - setPhoneNo(row.get("Phone_no").getStringValue()); + HelpingFunctions.setPhoneNo(row.get("Phone_no").getStringValue()); } if (!row.get("First_name").isNull()) { - setFirstName(row.get("First_name").getStringValue()); + HelpingFunctions.setFirstName(row.get("First_name").getStringValue()); } if (!row.get("Last_name").isNull()) { - setLastName(row.get("Last_name").getStringValue()); + HelpingFunctions.setLastName(row.get("Last_name").getStringValue()); } if (!row.get("Admin").isNull()) { - setIsAdmin(row.get("Admin").getBooleanValue()); + HelpingFunctions.setIsAdmin(row.get("Admin").getBooleanValue()); } } } @@ -42,6 +54,14 @@ public class AccountHandler { } } + /** + * This function creates the login sql statement and returns a TableResult to be iterated through + * + * @param username input parameter for the username + * @param password input parameter for the password + * @return a TableResult that can be iterated through + * @throws Exception throws exception if anything goes wrong + */ public static TableResult logIn(String username, String password) throws Exception { // Sqlstatement @@ -56,6 +76,13 @@ public class AccountHandler { return HelpingFunctions.createQueryJob(sqlStatement); } + /** + * Retrieves information regarding an account based on the username input + * + * @param username input parameter for the username + * @return a TableResult that can be iterated through + * @throws Exception throws exception if anything goes wrong + */ public static TableResult getAccount(String username) throws Exception { // Sqlstatement @@ -70,6 +97,18 @@ public class AccountHandler { return HelpingFunctions.createQueryJob(sqlStatement); } + /** + * This function takes a number of parameters as input and creates a user in the database + * + * @param firstName input parameter for firstname + * @param lastName input parameter for lastName + * @param phoneNo input parameter for phoneNo + * @param username input parameter for username + * @param password input parameter for password + * @param isAdmin input parameter from the checkbox is the account is admin or not + * @return a boolean if the user was added or not + * @throws Exception throws exception if anything goes wrong + */ public static boolean addUser(String firstName, String lastName, String phoneNo, String username, String password, boolean isAdmin) throws Exception { if(getAccount(username).getTotalRows() == 0) { @@ -87,6 +126,13 @@ public class AccountHandler { } } + /** + * This function deletes an account based on the username input parameter + * + * @param username input parameter for username + * @return a boolean if the user was deleted or not + * @throws Exception throws exception if anything goes wrong + */ public static boolean deleteUser(String username) throws Exception { if(getAccount(username).getTotalRows() != 0){ @@ -102,5 +148,4 @@ public class AccountHandler { return false; } } - } diff --git a/src/main/java/com/application/DB/Constants.java b/src/main/java/com/application/DB/Constants.java index 17b4ae5e84ada6a3c938ee416973f071d2dc797d..0ab11bc16da202db4bbbabd295275338e6d17b2c 100644 --- a/src/main/java/com/application/DB/Constants.java +++ b/src/main/java/com/application/DB/Constants.java @@ -1,10 +1,13 @@ package com.application.DB; +/** + * This class contain a number of constants used throughout the application + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class Constants { - // Key name file for the database access - public static String KEY_FILE_NAME = "sf-drying-optimization-8a2e1b7ffc14.json"; - // Time related constants public static String START_TIME = ""; public static String STOP_TIME = ""; @@ -22,60 +25,9 @@ public class Constants { public static String SAWSET = ""; public static String MOISTURE_GOAL = ""; - // Number of manual moisture checks - public static int NUMBER_OF_CHECKS = 1; - - // Max number of input characters for sql injection prevention - public static int MAX_USER_INPUT_CHARACTERS = 10; - // Boolean constants to toggle default launch selected or not for checkboxes for showing graphs public static boolean DEFAULT_IS_SELECTED_LIVE_DATA = true; public static boolean DEFAULT_IS_SELECTED_REGRESSION = true; public static boolean DEFAULT_IS_SELECTED_REGRESSION_SHADOW = false; public static boolean DEFAULT_IS_SELECTED_PREVIOUS_DATA = true; - - // Account constants - private static boolean isAdmin = false; - private static String firstName; - private static String lastName; - private static String userName; - private static String phoneNo; - - public static String getUserName() { return userName;} - - public static void setUserName(String userName) { - Constants.userName = userName; - } - - public static String getPhoneNo() { - return phoneNo; - } - - public static void setPhoneNo(String phoneNo) { - Constants.phoneNo = phoneNo; - } - - public static boolean isIsAdmin() { - return isAdmin; - } - - public static void setIsAdmin(boolean isAdmin) { - Constants.isAdmin = isAdmin; - } - - public static String getFirstName() { - return firstName; - } - - public static void setFirstName(String firstName) { - Constants.firstName = firstName; - } - - public static String getLastName() { - return lastName; - } - - public static void setLastName(String lastName) { - Constants.lastName = lastName; - } } diff --git a/src/main/java/com/application/DB/DB.java b/src/main/java/com/application/DB/DB.java index 562486a66c8f2c4a144eaaf275414da6f07ab6ad..cf7c7d89f78b46132533fbfb15ba35b7b7eb3065 100644 --- a/src/main/java/com/application/DB/DB.java +++ b/src/main/java/com/application/DB/DB.java @@ -13,36 +13,28 @@ import static com.application.DB.HelpingFunctions.getNoOfChambers; * This class is responsible for handling database related activities * * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen - * @version 1.0 + * @version 1.0.0 */ public class DB { /** - * Launching the functions + * This function gathers all input parameters from the user and search for data * - * @param args default param - * @throws Exception throws exception in case of error + * @return a map containing drying cycles + * @throws Exception throws exception if error occurs */ - public static void main(String[] args) throws Exception { - //getKwh(); - //getName(); - //getZeroPointDate(); - //System.out.println(setInputParameters()); - //getNoOfChambers(); - - } - - public static Map<Integer, Map<String, Number>> setInputParameters() throws Exception { + // Map to store data Map<Integer, Map<String, Number>> allDryingPeriods = new HashMap<>(); + // Variables to indicate if the parameters have been deleted or not boolean sawsetRemoved = false; boolean treespeciesRemoved = false; boolean dimensionsRemoved = false; boolean moistureRemoved = false; - + // Defining variables HashMap<java.lang.String, java.lang.String> locationTables = null; ArrayList<Integer> valmeticsChamberIDS = null; ArrayList<Integer> kwhChamberIDS = null; @@ -76,11 +68,13 @@ public class DB { getNoOfChambers(); int chamberNo = 1; - + // While loop that check for data while(true){ + // Map to store data Map<Integer, Map<String, Number>> intermediateHashMap = new HashMap<>(); + // Iterating through all the sawmills for (HashMap.Entry<Integer, HashMap<String, HashMap<String, String>>> location : Settings.getSawmills().entrySet()) { // Clears the extraInputs variable @@ -89,12 +83,9 @@ public class DB { System.out.printf("\nLocation ID: \t%s\t\t\tRest of map: \t%s\n", location.getKey(), location.getValue()); System.out.println("Number of sawmills: "+ Settings.getSawmills().size()); - //allDryingPeriods = new TreeMap<>(); - locationID = location.getKey(); - //System.out.println(location.getValue()); - + // If the location is 124, "Furu" is stored as "Fura" in the database, swedish if (location.getKey() == 124) { // If location is Valasen, then the database stores furu as fura, swedish. if (Constants.TREE_SPECIES.equalsIgnoreCase("Furu")) { @@ -226,6 +217,7 @@ public class DB { } } + // Prints all the drying periods System.out.println(allDryingPeriods.size()); for (Map.Entry<Integer, Map<String, Number>> entry : allDryingPeriods.entrySet()) { System.out.printf("Timestamp: \t%s\t\t\tkWh: \t%s\n", entry.getKey(), entry.getValue()); @@ -283,7 +275,7 @@ public class DB { finalResults.put(index, sortedData); index += 1; - // entry.value burde matche med en av de og går igjennom alle + // checks for manual moisture for (Map.Entry<String, String> moistureEntry : HelpingFunctions.getManMoist().entrySet()) { if(moistureEntry.getKey().equals(entry.getValue())){ @@ -304,17 +296,7 @@ public class DB { // Defining a treemap to sort the data incrementally NavigableMap<Integer, Map<String, Number>> sortedFinalResults = new TreeMap<>(finalResults); - for (Map.Entry<Integer, Map<String, Number>> entry : sortedFinalResults.entrySet()) { - - Map<String, Number> data = entry.getValue(); - for (Map.Entry<String, Number> moistureEntry : data.entrySet()) { - - //System.out.println("Data key: "+moistureEntry.getKey()); // Key = datetime: 2022-01-18 20:23:36 - //System.out.println("Data Value: "+moistureEntry.getValue()); // Value = kwh: 5422 - } - - } - + // Prints the values for (Map.Entry<Integer, Map<String, Number>> entry : sortedFinalResults.entrySet()) { System.out.printf("Timestamp: \t%s\t\t\tkWh: \t%s\n", entry.getKey(), entry.getValue()); } @@ -388,8 +370,6 @@ public class DB { kilinID += 1; } - - // Retrieves the results from the queryjob TableResult result = HelpingFunctions.createQueryJob(sqlStatement); @@ -420,11 +400,6 @@ public class DB { } } - - //System.out.println("Start: "+row.get("DryingStarted").getTimestampValue()); - //System.out.println("Stop: "+row.get("DryingCompleted").getTimestampValue()); - - // Retrieving the data // DryingStarted: if(!row.get("DryingStarted").isNull()){ @@ -451,14 +426,8 @@ public class DB { } else formatedInTidTork = row.get("DryingStarted").getValue().toString(); } - - // Checks if response is given in a string date format - //if(row.get("DryingStarted").getValue().equals(Long.parseLong(row.get("DryingStarted").getValue().toString()))) { - - } - // CalculatedStop: // DryingCompleted: // Check if response is given in millis try{ @@ -481,8 +450,6 @@ public class DB { } - - // Getting manual measurement: // Adding days to search between String date = formatedUtTidTork.split(" ")[0]; @@ -529,18 +496,11 @@ public class DB { */ - - - - //System.out.println("Inn formated: "+formatedInTidTork); - //System.out.println("Ut formated: "+formatedUtTidTork+"\n"); - // Checks if intidtork or outtidtork is empty, if so they are ignored and not added to the list if (!formatedInTidTork.isEmpty() && !formatedUtTidTork.isEmpty()){ // Adds the data to the dates map dates.put(formatedInTidTork,formatedUtTidTork); } - //System.out.printf("%s\t\t\t%s\n",formatedInTidTork,formatedUtTidTork); } // Defining a treemap to sort the data incrementally @@ -566,6 +526,12 @@ public class DB { } + /** + * This function push the manual moisture level + * + * @param moisture input parameter for measured value + * @throws Exception throws exception in case of error + */ public static void pushManMoisture(String moisture) throws Exception { String startTime = null; @@ -606,7 +572,7 @@ public class DB { // Sqlstatement final String sqlStatement = "INSERT INTO " + PROJECT_ID + "." + LOCATION_ID + "." + MAN_MOISTURE_TABLE + "(moisture,tree_species,dimensions,sawset,moisture_goal,no_moisture_check,start_time,stop_time,finished) " + - "VALUES("+moisture+","+treeSpecies+","+dimensions+","+sawset+","+moistureGoal+","+ Constants.NUMBER_OF_CHECKS+","+startTime+","+stopTime+","+IS_FINISHED+") "; + "VALUES("+moisture+","+treeSpecies+","+dimensions+","+sawset+","+moistureGoal+","+ NUMBER_OF_CHECKS+","+startTime+","+stopTime+","+IS_FINISHED+") "; System.out.println(sqlStatement); @@ -639,11 +605,8 @@ public class DB { // Retrieves the results from the queryjob TableResult result = HelpingFunctions.createQueryJob(sqlStatement); - //System.out.println("InTidTork\t\t\tUtTidTork"); // Iterating through the results HelpingFunctions.iterateKwhValues(data, result, KWH_NAME_PARAMETER, KWH_TIMESTAMP_NAME_PARAMETER); return new TreeMap<>(data); } - - } diff --git a/src/main/java/com/application/DB/HelpingFunctions.java b/src/main/java/com/application/DB/HelpingFunctions.java index a354a794e847db5b5796e47922aeca2b7fc896bd..167049b76e1796b2298ac69a8abbaccee421f607 100644 --- a/src/main/java/com/application/DB/HelpingFunctions.java +++ b/src/main/java/com/application/DB/HelpingFunctions.java @@ -4,7 +4,6 @@ import com.application.GUI.PopUpWindows.NotificationPopUp; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.cloud.bigquery.*; -import io.opencensus.internal.StringUtils; import java.io.File; import java.io.FileInputStream; @@ -13,18 +12,32 @@ import java.util.HashMap; import java.util.Map; import java.util.TimeZone; -import static com.application.DB.Constants.KEY_FILE_NAME; -import static com.application.DB.Constants.MAX_USER_INPUT_CHARACTERS; import static com.application.DB.Settings.*; - +/** + * This class contain a number of helping function that is accessed throughout the application + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class HelpingFunctions { + // Key name file for the database access + public static String KEY_FILE_NAME = "sf-drying-optimization-8a2e1b7ffc14.json"; + + // Map to store manual moisture static Map<String,String> manMoist = new HashMap<>(); + // Account constants + static boolean isAdmin = false; + static String firstName; + static String lastName; + static String userName; + static String phoneNo; + /** - * Creates a simple date format to use for converting millis in numbers to a usefull date format + * Creates a simple date format to use for converting millis in numbers to a useful date format * * @return returns the date format */ @@ -150,6 +163,11 @@ public class HelpingFunctions { } } + /** + * This function gets the total number of chambers that are searched for + * + * @return an integer indecating the total number of chambers + */ public static int getNoOfChambers(){ int valmeticsChamberIDS = 0; int kwhChamberIDS = 0; @@ -170,6 +188,24 @@ public class HelpingFunctions { return noOfChambers; } + /** + * This function handles input validation + * + * @param input string of input parameter from the user to be checked + * @return a boolean to indicate if the input is accepted or not + */ + public static boolean isValidInput (String input){ + if(input.length() > MAX_USER_INPUT_CHARACTERS) { + NotificationPopUp.displayNotificationWindow("A maximum of "+MAX_USER_INPUT_CHARACTERS+" characters is allowed!"); + return true; + } + else if(input.toLowerCase().contains("union")){ + NotificationPopUp.displayNotificationWindow("Keyword: 'UNION' is not allowed"); + return true; + } + else return false; +} + public static boolean isLoadedData() { return Constants.LOADED_DATA; } @@ -178,21 +214,41 @@ public class HelpingFunctions { Constants.LOADED_DATA = loadedData; } + public static String getUserName() { return userName;} -public static boolean isValidInput (String input){ - if(input.length() > Constants.MAX_USER_INPUT_CHARACTERS) { - NotificationPopUp.displayNotificationWindow("A maximum of "+MAX_USER_INPUT_CHARACTERS+" characters is allowed!"); - return true; + public static void setUserName(String userName) { + HelpingFunctions.userName = userName; } - else if(input.contains("UNION")){ - NotificationPopUp.displayNotificationWindow("Keyword: 'UNION' is not allowed"); - return true; + + public static String getPhoneNo() { + return phoneNo; } - else return false; -} + public static void setPhoneNo(String phoneNo) { + HelpingFunctions.phoneNo = phoneNo; + } + public static boolean isIsAdmin() { + return isAdmin; + } + + public static void setIsAdmin(boolean isAdmin) { + HelpingFunctions.isAdmin = isAdmin; + } + + public static String getFirstName() { + return firstName; + } + public static void setFirstName(String firstName) { + HelpingFunctions.firstName = firstName; + } + public static String getLastName() { + return lastName; + } + public static void setLastName(String lastName) { + HelpingFunctions.lastName = lastName; + } } diff --git a/src/main/java/com/application/DB/Settings.java b/src/main/java/com/application/DB/Settings.java index e4bca572acf675007cb262cade9be2704dc6b21b..2ffbc38fe480b2ce6e3a5cef9990ea93c821ae42 100644 --- a/src/main/java/com/application/DB/Settings.java +++ b/src/main/java/com/application/DB/Settings.java @@ -5,7 +5,10 @@ import java.util.Arrays; import java.util.HashMap; /** - * This class contains constants to be used related to database activities + * This class contains changeable settings for the application + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 */ public final class Settings { @@ -13,6 +16,11 @@ public final class Settings { // Empty constructor } + // Number of manual moisture checks + public static int NUMBER_OF_CHECKS = 1; + // Max number of input characters for sql injection prevention + public static int MAX_USER_INPUT_CHARACTERS = 15; + // Number of wanted drying periods public static int NUMBER_OF_PERIODS = 2; diff --git a/src/main/java/com/application/GUI/LineChartFunctionality.java b/src/main/java/com/application/GUI/LineChartFunctionality.java index 93593a377e83e4010fff62b69ed1848ef175f7b0..9cbb9980c1448473b501b3b3c05ab62d10a72cb2 100644 --- a/src/main/java/com/application/GUI/LineChartFunctionality.java +++ b/src/main/java/com/application/GUI/LineChartFunctionality.java @@ -13,14 +13,18 @@ import org.apache.commons.math3.distribution.TDistribution; import org.apache.commons.math3.exception.MathIllegalArgumentException; import org.apache.commons.math3.stat.descriptive.SummaryStatistics; import org.apache.commons.math3.stat.regression.SimpleRegression; -import org.jblas.DoubleMatrix; -import org.jblas.Solve; import java.text.SimpleDateFormat; import java.util.*; import static com.application.Main.*; +/** + * This class handle all the GUI functionality and statistics calculations + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class LineChartFunctionality { private static LineChart<String, Number> lineChart; @@ -39,6 +43,7 @@ public class LineChartFunctionality { private static boolean printLiveData; private static boolean printPreviousData; + // Constructor public LineChartFunctionality() { xAxis = new CategoryAxis(); yAxis = new NumberAxis(); @@ -63,7 +68,7 @@ public class LineChartFunctionality { /** - * Prints the graphs to the line chart + * Prints the selected graphs to the line chart * * Note: Something wrong when exceeding 8 series, think the next series choose a random series color */ @@ -107,15 +112,11 @@ public class LineChartFunctionality { getMenuViewPreviousData().setSelected(true); // If there are more than 5 series, adds 3 new empty series to keep the color scheme - //int index = getLineChart().getData().size(); for (int i = 0; i < getPreviousData().size(); i++) { int index = getLineChart().getData().size(); - //System.out.println(getPreviousData().size()); if (index % 8 == 0 ){ for (int j = 0; j < 3; j++) { updateLineChart(new XYChart.Series<>()); - //index++; - System.out.println("@@@@@@@"); } } updateLineChart(getPreviousData().get(i)); @@ -127,103 +128,102 @@ public class LineChartFunctionality { } - + /** + * This function calculates the confidence interval + * + * @param multiMap input containing the drying cycle data + * @param CIShadow input to indicate if the confidence interval shadow is stored or not + * @return a map containing the processed data + */ private static Map<Integer, ArrayList<Double>> statistics(Map<Integer, ArrayList<Double>> multiMap, boolean CIShadow){ - //System.out.println("\n\nMultimap: \n"); + // Iterates through all the data for (Map.Entry<Integer, ArrayList<Double>> entry : multiMap.entrySet()) { - //System.out.printf("\nIndex: \t%s\t\t\tkWh: \t%s\n", entry.getKey(), entry.getValue()); - - //System.out.println("entry: "+entry); - //if(entry.getValue().size()>1){ - SummaryStatistics stats = new SummaryStatistics(); + SummaryStatistics data = new SummaryStatistics(); for (double val : entry.getValue()) { - stats.addValue(val); + data.addValue(val); } - //System.out.println("Stats: "+stats); - - // Calculate 95% confidence interval - double ci = calcMeanCI(stats, Settings.CONFIDENCE_INTERVAL); - //System.out.println(String.format("Mean: %f", stats.getMean())); - double lower = stats.getMean() - ci; - double upper = stats.getMean() + ci; - //System.out.println(String.format("Confidence Interval "+ Settings.CONFIDENCE_INTERVAL*100+"%%: %f, %f", lower, upper)); + // Calculate the confidence interval + double confidenceInterval = calcMeanConfidenceInterval(data); + double lower = data.getMean() - confidenceInterval; + double upper = data.getMean() + confidenceInterval; // Deletes entries if they are out of bounds with the confidence interval entry.getValue().removeIf(value -> Double.compare(value, lower) < 0 || Double.compare(value, upper) > 0); + // Checks if the confidence interval shall be returned or not if(CIShadow){ ArrayList<Double> lowerUpperBounds = new ArrayList<>(); lowerUpperBounds.add(lower); lowerUpperBounds.add(upper); multiMap.replace(entry.getKey(), lowerUpperBounds); } - //} } return multiMap; } - private static double calcMeanCI(SummaryStatistics stats, double level) { + /** + * This function calculates the confidence interval mean value + * + * @param data the data to base the calculation on + * @return returns the confidence interval mean value + */ + private static double calcMeanConfidenceInterval(SummaryStatistics data) { try { - // Create T Distribution with N-1 degrees of freedom - TDistribution tDist = new TDistribution(stats.getN() - 1); - // Calculate critical value - double critVal = tDist.inverseCumulativeProbability(1.0 - (1 - level) / 2); - // Calculate confidence interval - return critVal * stats.getStandardDeviation() / Math.sqrt(stats.getN()); + // Create a T distribution + TDistribution tDistribution = new TDistribution(data.getN() - 1); + // Calculate the critical value + double criticalValue = tDistribution.inverseCumulativeProbability(1.0 - (1 - Settings.CONFIDENCE_INTERVAL) / 2); + // Calculate the confidence interval + return criticalValue * data.getStandardDeviation() / Math.sqrt(data.getN()); } catch (MathIllegalArgumentException e) { return Double.NaN; } } + /** + * This function serves as the main function that controls all the functionality. + * This function takes the data inputted and plots it and calculates the statistics. + * + * @param userInput data regarding the drying cycles + * @throws Exception throws exception if an error occurs + */ + public static void loadSingleSeries(Map<Integer, Map<String, Number>> userInput) throws Exception { - public static LineChart<String, Number> loadSingleSeries(Map<Integer, Map<String, Number>> userInput) throws Exception { + // Clears the linechart if there are previous graphs plotted clearLineChart(); - + // Defining a map to store data Map<Integer, ArrayList<Double>> multiMap = new HashMap<>(); + // Iterates through the data for (Map.Entry<Integer, Map<String, Number>> entryKwh : userInput.entrySet()) { Map data = entryKwh.getValue(); - //System.out.println(data.size()); - XYChart.Series<String, Number> newSeries = new XYChart.Series<String, Number>(); int index = 0; for (Object entryData : data.entrySet()) { - //System.out.println("data: \t"+entryData); String entryString = entryData.toString(); String[] arr = entryString.split("="); - String date = arr[0]; Double kwhValue = Double.parseDouble(arr[1]); - //System.out.printf("Date: \t%s\t\t\tkWh: \t%s\n",date,kwhValue); - // Checks if the index already got an arraylist, if not one is created multiMap.computeIfAbsent(index, k -> new ArrayList<Double>()); multiMap.get(index).add(kwhValue); - // Connect the data to a series - newSeries.getData().add(new XYChart.Data<String, Number>(String.valueOf(index), kwhValue)); index++; } - //allSeries.add(newSeries); - //updateLineChart(newSeries); - //lineChart.setOpacity(1); } - //System.out.println("Series size: "+allSeries.size()); - - - // Finds the end datapoint at the end of each graph int numberOfGraphs = 0; + // Defines lists to store data ArrayList<Double> dataArraylistXAxis = new ArrayList<>(); ArrayList<Double> dataArraylistYAxis = new ArrayList<>(); - Map<Integer, ArrayList<Double>> endOfGraphPointsXAxis = new HashMap<>(); Map<Integer, ArrayList<Double>> endOfGraphPointsYAxis = new HashMap<>(); + // Iterates through the data for (int i = 0; i < multiMap.size(); i++) { ArrayList<Double> list = multiMap.get(i); for (int j = 0; j < list.size(); j++) { @@ -231,11 +231,8 @@ public class LineChartFunctionality { numberOfGraphs = list.size(); } if (list.size() < numberOfGraphs) { - dataArraylistXAxis.add((double) i); dataArraylistYAxis.add(multiMap.get(i).get(j)); - //System.out.println(tempList); - numberOfGraphs = list.size(); } } @@ -243,56 +240,33 @@ public class LineChartFunctionality { dataArraylistXAxis.add((double) multiMap.size()); dataArraylistYAxis.add(multiMap.get(multiMap.size()-1).get(0)); - //System.out.println(dataArraylistYAxis); - - endOfGraphPointsXAxis.put(0,dataArraylistXAxis); endOfGraphPointsYAxis.put(0,dataArraylistYAxis); - System.out.println(endOfGraphPointsXAxis); - System.out.println(endOfGraphPointsYAxis); - Map<Integer, ArrayList<Double>> endOfGraphPointsConfidenceXAxis = statistics(endOfGraphPointsXAxis,false); Map<Integer, ArrayList<Double>> endOfGraphPointsConfidenceYaxis = statistics(endOfGraphPointsYAxis,false); - System.out.println("X-axis:"+ endOfGraphPointsConfidenceXAxis); - System.out.println("X-axis size: "+ endOfGraphPointsConfidenceXAxis.size()); - System.out.println("------------"); - System.out.println("Y-axis:"+ endOfGraphPointsConfidenceYaxis); - System.out.println("Y-axis size: "+ endOfGraphPointsConfidenceYaxis.size()); - System.out.println("------------"); - - + // X-axis dataPointsXAxis = 0; for (Map.Entry<Integer, ArrayList<Double>> entry : endOfGraphPointsConfidenceXAxis.entrySet()) { - System.out.println("Arraylist: "+ entry.getValue()); for (int i = 0; i < entry.getValue().size(); i++) { - System.out.println("End of graphs: "+ entry.getValue().get(i)); dataPointsXAxis += entry.getValue().get(i); } } dataPointsXAxis = dataPointsXAxis /endOfGraphPointsConfidenceXAxis.get(0).size(); - System.out.println("Datapoints: " + dataPointsXAxis); - + // Y-axis dataPointsYAxis = 0; for (Map.Entry<Integer, ArrayList<Double>> entry : endOfGraphPointsConfidenceYaxis.entrySet()) { - System.out.println("Arraylist: "+ entry.getValue()); for (int i = 0; i < entry.getValue().size(); i++) { - System.out.println("End of graphs: "+ entry.getValue().get(i)); dataPointsYAxis += entry.getValue().get(i); } } dataPointsYAxis = dataPointsYAxis /endOfGraphPointsConfidenceYaxis.get(0).size(); - System.out.println("Datapoints Y-axis: " + dataPointsYAxis); - - // Stores the data from the confidence interval in a new map Map<Integer, ArrayList<Double>> confidenceIntervalData = statistics(multiMap,false); - //getNonLinearRegression(confidenceIntervalData); - // Checks the max size for the arraylists needed for the data array later int jMaxSize = 0; for (int i = 0; i < confidenceIntervalData.size(); i++) { @@ -301,23 +275,20 @@ public class LineChartFunctionality { } } - - // Defines an array to be used for the regression + // Defines an array to be used for the linear regression double[][] data = new double[confidenceIntervalData.size()*jMaxSize][2]; int index = 0; - //System.out.println(confidenceIntervalData); for (int i = 0; i < confidenceIntervalData.size(); i++) { - ArrayList<Double> list = confidenceIntervalData.get(i); - - for (int j = 0; j < list.size(); j++) { + for (Double aDouble : list) { data[index][0] = i; - data[index][1] = list.get(j); + data[index][1] = aDouble; index++; } } + // Adds the data to the confidence interval shadow getRegressionSeriesConfidenceInterval().getData().clear(); Map<Integer, ArrayList<Double>> confidenceIntervalShadow = statistics(multiMap,true); for ( Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalShadow.entrySet()) { @@ -327,59 +298,14 @@ public class LineChartFunctionality { } } - System.out.println(data.length); - //System.out.println(data[12][1]); - + // Does the linear regression SimpleRegression simpleRegression = new SimpleRegression(); - simpleRegression.addData(data); - //simpleRegression.regress(); - - - for (double[] datum : data) { - //System.out.println(""); - for (double v : datum) { - //System.out.println("Data: "+v); - } - } - - //updateLineChart(liveDataSeries); - - - //XYChart.Series<String, Number> regressionSeries = new XYChart.Series<String, Number>(); + // Does the logistic regression getRegressionSeries().getData().clear(); for (int i = 0; i <= getDataPointsXAxis(); i++) { - // Connect the data to a series - //System.out.println(simpleRegression.predict(i)); - //regressionSeries.getData().add(new XYChart.Data<String, Number>(String.valueOf(i), simpleRegression.predict(i))); - /* - regressionSeries.getData().add(new XYChart.Data<String, Number>( - String.valueOf(i), - getNonLinearRegression( - confidenceIntervalData, - getDataPointsYAxis(), - //simpleRegression.getIntercept(), - simpleRegression.getSlope(), - //simpleRegression.getIntercept() - getDataPointsYAxis(), - i, - getDataPointsXAxis() - ))); - - */ - - /* - regressionSeries.getData().add(new XYChart.Data<String, Number>( - String.valueOf(i), - getCubicNonLinearRegression(confidenceIntervalData,i) - )); - - */ - - - getRegressionSeries().getData().add(new XYChart.Data<String, Number>( String.valueOf(i), getNonLinearRegression( @@ -389,21 +315,14 @@ public class LineChartFunctionality { i, getDataPointsXAxis() ))); - - } - //updateLineChart(getRegressionSeries()); - //lineChart.setOpacity(1); - - + // Adds the previous data to series getPreviousData().clear(); for (Map.Entry<Integer, Map<String, Number>> entryKwh : userInput.entrySet()) { - //System.out.println(data.size()); XYChart.Series<String, Number> newSeries = new XYChart.Series<String, Number>(); index = 0; for (Object entryData : entryKwh.getValue().entrySet()) { - //System.out.println("data: \t"+entryData); String entryString = entryData.toString(); Double kwhValue = Double.parseDouble(entryString.split("=")[1]); @@ -412,36 +331,17 @@ public class LineChartFunctionality { index++; } addPreviousData(newSeries); - //allSeries.add(newSeries); - //updateLineChart(newSeries); - //lineChart.setOpacity(1); } - - - - - System.out.println("Get R: " + simpleRegression.getR()); - System.out.println("Get getRSquare: " + simpleRegression.getRSquare()); - System.out.println("Get getRegressionSumSquares: " + simpleRegression.getRegressionSumSquares()); - - System.out.println("Get N: " + simpleRegression.getN()); - - // and then you can predict the time at a given temperature value - System.out.println("Predicted Time: " + simpleRegression.predict(35)); - - // You can also get the slope and intercept from your data - System.out.println("Alpha! = " + simpleRegression.getSlope()); - System.out.println("intercept = " + simpleRegression.getIntercept()); - - //simpleRegression.add - getTimeLeft(0); - printGraphs(); - - return getLineChart(); } + /** + * This function loads the live data and plots the data in the graph + * + * @param userInput the input parameter for the live data + * @throws Exception throws an exception if an error occur + */ public static void loadLiveData(Map<String, Number> userInput) throws Exception { // Clears any data already there @@ -466,6 +366,13 @@ public class LineChartFunctionality { } } + /** + * Finds the difference between two dates + * + * @param start_date input parameter for the first date + * @param end_date input parameter for the second date + * @return returns the differnce in minutes + */ private static long findDifference(String start_date, String end_date) { // Defining a simple date format SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @@ -487,11 +394,19 @@ public class LineChartFunctionality { return 0; } + /** + * This function calculates the remaining time of the current drying cycle + * + * @param liveData input parameter for the data to base the calculations on + */ public static void getTimeLeft(int liveData){ + + // Defines variables int minutes = 0; int hours = 0; if(liveData == 0) { + // There are 10 minutes between each datapoint minutes = getDataPointsXAxis()*10; } else { @@ -512,135 +427,22 @@ public class LineChartFunctionality { } - public static double getNonLinearRegression(Map<Integer, ArrayList<Double>> confidenceIntervalData, double y0, double alpha, double j, double n) { - //return Math.exp(intercept+slope*i)/(1+Math.exp(intercept+slope*i)); - - - double beta = 0.0; - //double n = confidenceIntervalData.size(); - for (Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalData.entrySet()) { - for (int i = 0; i < entry.getValue().size(); i++) { - if(beta < entry.getValue().get(i)){ - beta = entry.getValue().get(i); - } - } - } - - beta = getDataPointsYAxis()+y0; - //System.out.println("Beta: " +beta); - //System.out.println("y0: "+y0); - - - //System.out.println("maxYValue: " + maxYValue); - //System.out.println("j*n: "+j/n); - - //double p_t = (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*j/n/(ADJUST_REGRESSION)))))-y0; //Beste til nå - double p_t = (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*j/n/((alpha/10))))))-y0; //Beste til nå - //double p_t = (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*(j-n)))))-y0; //Beste til nå - - - /* - System.out.println("---------------------------"); - System.out.println("y0: " + y0); - System.out.println("Alpha: " + alpha); - System.out.println("Beta: " + beta); - //System.out.println(p_t); - - */ - - - - return p_t; - - } - - /** - * Third degree cubic non-linear regression + * This function handles the logistic regression * - * n = - * - * sumT1 = - * sumT2 = - * sumT3 = - * sumT4 = - * - * sumY = - * sumYxT1= - * sumYxT2 = - * @param confidenceIntervalData Data to process - * @return + * @param confidenceIntervalData the input parameter for the data to base the regression on + * @param y0 the input parameter for the intercept from the linear regression + * @param alpha the input parameter for the slope value from the linear regression + * @param j the input parameter for current x-axis datapoint to predict the value for + * @param n the input parameter for the total number of points along the x-axis + * @return the predicted value at a given point */ - public static double getCubicNonLinearRegression(Map<Integer, ArrayList<Double>> confidenceIntervalData, int index){ - - double n = confidenceIntervalData.size(); - //double n = getDataPointsYAxis(); - //System.out.println(n); - - double sumT1 = 0; - double sumT2 = 0; - double sumT3 = 0; - double sumT4 = 0; - - double sumY = 0; - double sumYxT1 = 0; - double sumYxT2 = 0; - - - - for (Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalData.entrySet()) { - - sumT1 += entry.getKey(); - sumT2 += Math.pow(entry.getKey(),2); - sumT3 += Math.pow(entry.getKey(),3); - sumT4 += Math.pow(entry.getKey(),4); - - for (int j = 0; j < entry.getValue().size(); j++) { - - sumY += entry.getValue().get(j); - sumYxT1 += entry.getValue().get(j) * entry.getKey(); - sumYxT2 += entry.getValue().get(j) * Math.pow(entry.getKey(), 2); - } - } - - - - -/* - for (Map.Entry<Integer, ArrayList<Double>> entry : confidenceIntervalData.entrySet()) { - - - - for (int j = 0; j < entry.getValue().size(); j++) { - - sumT1 += Math.pow(entry.getValue().get(j), 1); - sumT2 += Math.pow(entry.getValue().get(j), 2); - sumT3 += Math.pow(entry.getValue().get(j), 3); - sumT4 += Math.pow(entry.getValue().get(j), 4); - - sumY += entry.getKey(); - sumYxT1 += entry.getKey() * entry.getValue().get(j); - sumYxT2 += entry.getKey() * Math.pow(entry.getValue().get(j), 2); - } - } - - */ - - - - DoubleMatrix firstMatrix = new DoubleMatrix(new double[][]{{n,sumT1,sumT2},{sumT1,sumT2,sumT3},{sumT2,sumT3,sumT4}}); - DoubleMatrix secondMatrix = new DoubleMatrix( new double[]{sumY, sumYxT1, sumYxT2}); - - - DoubleMatrix solvedMatrix = Solve.solve(firstMatrix,secondMatrix); - //System.out.println(solvedMatrix); - - //return ((solvedMatrix.get(0)) + (solvedMatrix.get(1) * index) + (solvedMatrix.get(2) * Math.pow(index, 2))); - //return ((solvedMatrix.get(1) * index) + (solvedMatrix.get(2) * Math.pow(index, 2)))*(-1); - return ((solvedMatrix.get(1) * index) + (solvedMatrix.get(2) * Math.pow(index, 2))); - + public static double getNonLinearRegression(Map<Integer, ArrayList<Double>> confidenceIntervalData, double y0, double alpha, double j, double n) { + double beta = getDataPointsYAxis()+y0; + return (((beta * y0))/(y0 +((beta- y0)*Math.exp(-alpha*j/n/((alpha/10))))))-y0; } + // Getters and setters public static int getDataPointsXAxis() { return dataPointsXAxis; } @@ -661,10 +463,6 @@ public class LineChartFunctionality { return liveDataSeries; } - public static void setRegressionSeries(XYChart.Series<String, Number> regressionSeries) { - LineChartFunctionality.regressionSeries = regressionSeries; - } - public static XYChart.Series<String, Number> getRegressionSeries() { return regressionSeries; } @@ -713,10 +511,6 @@ public class LineChartFunctionality { return regressionSeriesConfidenceInterval; } - public static void setRegressionSeriesConfidenceInterval(XYChart.Series<String, Number> regressionSeriesConfidenceInterval) { - LineChartFunctionality.regressionSeriesConfidenceInterval = regressionSeriesConfidenceInterval; - } - public static LineChart<String, Number> getLineChart() { return lineChart; } @@ -729,6 +523,5 @@ public class LineChartFunctionality { public static void clearLineChart() { getLineChart().getData().clear(); - //lineChart.getData(). } } diff --git a/src/main/java/com/application/GUI/Panes/CreateBottomBar.java b/src/main/java/com/application/GUI/Panes/CreateBottomBar.java index 70fd9122dc4f2062e39c19bb8fecce2277fc599a..3cc701701c9bb56dd60e76bfb9698ba7c1404587 100644 --- a/src/main/java/com/application/GUI/Panes/CreateBottomBar.java +++ b/src/main/java/com/application/GUI/Panes/CreateBottomBar.java @@ -8,6 +8,12 @@ import javafx.scene.control.CheckBox; import javafx.scene.control.Label; import javafx.scene.layout.HBox; +/** + * This class creates the bottombar + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class CreateBottomBar { private final Main main; @@ -15,6 +21,11 @@ public class CreateBottomBar { this.main = main; } + /** + * This function create the bottombar + * + * @return the finished bottombar + */ public HBox createBottomBar() { HBox hBox = new HBox(); @@ -72,7 +83,7 @@ public class CreateBottomBar { } }); - + // Adds all the components to the HBox hBox.getChildren().addAll(liveDataText, Main.getLiveDataBox(), regressionText, Main.getRegressionBox(), regressionConfidenceIntervalText, Main.getRegressionConfidenceIntervalBox(), previousText, Main.getPreviousBox()); hBox.setAlignment(Pos.CENTER_RIGHT); hBox.setSpacing(5); diff --git a/src/main/java/com/application/GUI/Panes/CreateLogoBar.java b/src/main/java/com/application/GUI/Panes/CreateLogoBar.java index 2223ffd351950b7379a359a36768ade5377aeede..bf91fd121391e9ab02f1c37a073f007acf3d055f 100644 --- a/src/main/java/com/application/GUI/Panes/CreateLogoBar.java +++ b/src/main/java/com/application/GUI/Panes/CreateLogoBar.java @@ -11,17 +11,24 @@ import javafx.scene.layout.Region; import java.io.FileInputStream; import java.io.FileNotFoundException; -import static com.application.DB.Constants.isIsAdmin; +import static com.application.DB.HelpingFunctions.isIsAdmin; +/** + * This class creates the logobar + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class CreateLogoBar { + // The login button private static Button login = new Button("Login"); /** * This function imports the logos and defines the alignments * * @return a logoBar containing the logos in proper alignments - * @throws FileNotFoundException + * @throws FileNotFoundException throws exception if an error occurs */ public HBox createLogoBar() throws FileNotFoundException { // Defining the image paths diff --git a/src/main/java/com/application/GUI/Panes/CreateMenuBar.java b/src/main/java/com/application/GUI/Panes/CreateMenuBar.java index b5467ef0cacc5f60b8cb5d244ce817a642038622..4e27791d2015ec01a1cea9ff89335c4b27a7c187 100644 --- a/src/main/java/com/application/GUI/Panes/CreateMenuBar.java +++ b/src/main/java/com/application/GUI/Panes/CreateMenuBar.java @@ -8,6 +8,12 @@ import javafx.scene.control.CheckMenuItem; import javafx.scene.control.Menu; import javafx.scene.control.MenuItem; +/** + * This class creates the menubar + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class CreateMenuBar { private final Main main; @@ -19,7 +25,7 @@ public class CreateMenuBar { * Creates the menubar with buttons. * Defines each action when button is clicked. * - * @return MenuBar as a HBox + * @return MenuBar as a menubar */ public javafx.scene.control.MenuBar createMenuBar() { @@ -31,19 +37,23 @@ public class CreateMenuBar { Menu menuView = new Menu("View"); Menu menuHelp = new Menu("Help"); + // Adds menu item for file MenuItem menuFileExit = new MenuItem("Exit"); menuFileExit.setOnAction(event -> Main.exitApplication()); + // Adds menu item for view Main.setMenuViewLiveData(new CheckMenuItem("Live Data")); main.setMenuViewRegression(new CheckMenuItem("Regression")); main.setMenuViewRegressionShadow(new CheckMenuItem("Regression Shadow")); main.setMenuViewPreviousData(new CheckMenuItem("Previous Data")); + // Sets the default values Main.getMenuViewLiveData().setSelected(Constants.DEFAULT_IS_SELECTED_LIVE_DATA); Main.getMenuViewRegression().setSelected(Constants.DEFAULT_IS_SELECTED_REGRESSION); Main.getMenuViewRegressionShadow().setSelected(Constants.DEFAULT_IS_SELECTED_REGRESSION_SHADOW); Main.getMenuViewPreviousData().setSelected(Constants.DEFAULT_IS_SELECTED_PREVIOUS_DATA); + // Sets the updated value when the box is checked or unchecked Main.getMenuViewLiveData().setOnAction(event -> { if (Main.getMenuViewLiveData().isSelected()) { LineChartFunctionality.setPrintLiveData(true); @@ -53,6 +63,8 @@ public class CreateMenuBar { LineChartFunctionality.printGraphs(); } }); + + // Sets the updated value when the box is checked or unchecked Main.getMenuViewRegression().setOnAction(event -> { if (Main.getMenuViewRegression().isSelected()) { LineChartFunctionality.setPrintRegression(true); @@ -62,6 +74,8 @@ public class CreateMenuBar { LineChartFunctionality.printGraphs(); } }); + + // Sets the updated value when the box is checked or unchecked Main.getMenuViewRegressionShadow().setOnAction(event -> { if (Main.getMenuViewRegressionShadow().isSelected()) { LineChartFunctionality.setPrintRegressionConfidenceInterval(true); @@ -71,6 +85,8 @@ public class CreateMenuBar { LineChartFunctionality.printGraphs(); } }); + + // Sets the updated value when the box is checked or unchecked Main.getMenuViewPreviousData().setOnAction(event -> { if (Main.getMenuViewPreviousData().isSelected()) { LineChartFunctionality.setPrintPreviousData(true); @@ -81,12 +97,13 @@ public class CreateMenuBar { } }); + // Adds menu item for Help MenuItem aboutUs = new MenuItem("About Us"); aboutUs.setOnAction(event -> getAboutUs()); MenuItem help = new MenuItem("Help"); help.setOnAction(event -> getHelp()); - + // Adds all components to the menus menuFile.getItems().addAll(menuFileExit); menuView.getItems().addAll(Main.getMenuViewLiveData(), Main.getMenuViewRegression(), Main.getMenuViewRegressionShadow(), Main.getMenuViewPreviousData()); menuHelp.getItems().addAll(aboutUs, help); diff --git a/src/main/java/com/application/GUI/Panes/CreateSideBar.java b/src/main/java/com/application/GUI/Panes/CreateSideBar.java index e163cf760fdec168e9e18e749c4b0ecc46040ba6..88b4770c33165259af15ec1fa891997d9b1ab2f8 100644 --- a/src/main/java/com/application/GUI/Panes/CreateSideBar.java +++ b/src/main/java/com/application/GUI/Panes/CreateSideBar.java @@ -20,16 +20,28 @@ import static com.application.GUI.LineChartFunctionality.getDataPointsXAxis; import static com.application.GUI.LineChartFunctionality.getLiveData; import static java.util.logging.Level.SEVERE; +/** + * This class creates the sidebar + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class CreateSideBar { public CreateSideBar(Main main) { } + /** + * This function creates the sidebar + * + * @return the finished sidebar + */ public VBox createSideBar() { // Creating a vbox VBox sideBarVBox = new VBox(); + // Defining label and text-field for tree species Label treeSpeciesLabel = new Label("Tree Species"); treeSpeciesLabel.setId("sideBarLabelText"); Main.setTreeSpeciesText(new TextField()); @@ -38,6 +50,7 @@ public class CreateSideBar { Main.getTreeSpeciesText().setText(Constants.TREE_SPECIES); Main.getTreeSpeciesText().setEditable(false); + // Defining label and text-field for dimensions Label dimensionsLabel = new Label("Width x Height"); dimensionsLabel.setId("sideBarLabelText"); Main.setDimensionsText(new TextField()); @@ -46,6 +59,7 @@ public class CreateSideBar { Main.getDimensionsText().setText(Constants.DIMENSIONS); Main.getDimensionsText().setEditable(false); + // Defining label and text-field for sawset Label sawsetLabel = new Label("Sawset"); sawsetLabel.setId("sideBarLabelText"); Main.setSawsetText(new TextField()); @@ -54,6 +68,7 @@ public class CreateSideBar { Main.getSawsetText().setText(Constants.SAWSET); Main.getSawsetText().setEditable(false); + // Defining label and text-field for moisture goal Label moistureGoalLabel = new Label("Moisture Goal"); moistureGoalLabel.setId("sideBarLabelText"); Main.setMoistureGoalText(new TextField()); @@ -62,6 +77,7 @@ public class CreateSideBar { Main.getMoistureGoalText().setText(Constants.MOISTURE_GOAL); Main.getMoistureGoalText().setEditable(false); + // Defining label and text-field timeleft Label timeLeftLabel = new Label("Time Left"); timeLeftLabel.setId("sideBarLabelText"); Main.setTimeLeftText(new TextField()); @@ -70,6 +86,7 @@ public class CreateSideBar { Main.getTimeLeftText().setText(Constants.TIME_LEFT); Main.getTimeLeftText().setEditable(false); + // Define buttons Button inputParametersButton = new Button("Input Parameters"); inputParametersButton.setId("sideBarButtonInputParameters"); inputParametersButton.setOnAction(e -> InputPopup.display()); @@ -89,6 +106,7 @@ public class CreateSideBar { ringProgressIndicator.makeIndeterminate(); ringProgressIndicator.setId("progressBar"); + // Defines thread for updating the circular progressbar class WorkerThread extends Thread{ RingProgressIndicator rpi; int progress = 0; @@ -126,10 +144,9 @@ public class CreateSideBar { } } } - new WorkerThread(ringProgressIndicator).start(); - + // Adds all the components to the VBox sideBarVBox.getChildren().addAll(ringProgressIndicator, treeSpeciesLabel, Main.getTreeSpeciesText(), dimensionsLabel, Main.getDimensionsText(), sawsetLabel, Main.getSawsetText(), moistureGoalLabel, Main.getMoistureGoalText(), timeLeftLabel, Main.getTimeLeftText(), inputParametersButton, finishButton, exitButton); diff --git a/src/main/java/com/application/GUI/PopUpWindows/InputPopup.java b/src/main/java/com/application/GUI/PopUpWindows/InputPopup.java index fe07431d0739826764285cbccabbde1a73fd8b2f..ed385b3a56febc7f58cdb3c01d93030a3638a8a3 100644 --- a/src/main/java/com/application/GUI/PopUpWindows/InputPopup.java +++ b/src/main/java/com/application/GUI/PopUpWindows/InputPopup.java @@ -17,7 +17,6 @@ import java.util.Map; import static com.application.DB.HelpingFunctions.isValidInput; import static com.application.DB.Settings.*; import static com.application.DB.DB.getCurrentDrying; -import static com.application.DB.Constants.MAX_USER_INPUT_CHARACTERS; import static com.application.DB.HelpingFunctions.setLoadedData; import static com.application.GUI.LineChartFunctionality.*; import static com.application.GUI.Panes.CreateLogoBar.getLogin; @@ -33,6 +32,9 @@ import static com.application.DB.DB.setInputParameters; */ public class InputPopup { + /** + * This function displays the input parameter window + */ public static void display() { Stage window = new Stage(); @@ -128,52 +130,44 @@ public class InputPopup { Constants.MOISTURE_GOAL = moistureList.getValue(); } - - boolean err = false; + // If an account is not logged in, then the search is not started if(getLogin().getText().equals("Login")){ err = true; + NotificationPopUp.displayNotificationWindow("Please login!"); } // If the input is null, sets the value to be empty if (treeSpeciesList.getValue() == null) { Constants.TREE_SPECIES = ""; - } else if (isValidInput(treeSpeciesList.getValue())) { - treeSpeciesList.setValue(""); - err = true; } - if (dimensionsList.getValue() == null) { Constants.DIMENSIONS = ""; - } else if (dimensionsList.getValue().length() > MAX_USER_INPUT_CHARACTERS) { - NotificationPopUp.displayNotificationWindow("A maximum of "+MAX_USER_INPUT_CHARACTERS+" characters is allowed!"); - dimensionsList.setValue(""); - err = true; } - if (sawsetList.getValue() == null) { Constants.SAWSET = ""; - } else if (sawsetList.getValue().length() > MAX_USER_INPUT_CHARACTERS) { - NotificationPopUp.displayNotificationWindow("A maximum of "+MAX_USER_INPUT_CHARACTERS+" characters is allowed!"); - sawsetList.setValue(""); - err = true; } - if (moistureList.getValue() == null) { Constants.MOISTURE_GOAL = ""; - } else if (moistureList.getValue().length() > MAX_USER_INPUT_CHARACTERS) { - NotificationPopUp.displayNotificationWindow("A maximum of "+MAX_USER_INPUT_CHARACTERS+" characters is allowed!"); - moistureList.setValue(""); - err = true; } + // Validates inputs + if(isValidInput(Constants.TREE_SPECIES) || + isValidInput(Constants.DIMENSIONS) || + isValidInput(Constants.SAWSET) || + isValidInput(Constants.MOISTURE_GOAL)) { + err = true; + treeSpeciesList.setValue(""); + dimensionsList.setValue(""); + sawsetList.setValue(""); + moistureList.setValue(""); + } - - + // Checks if there is an error, if so the search is not started if (!err) { - + // Sets the values in the text-fields setTreeSpeciesText(Constants.TREE_SPECIES); setDimensionsText(Constants.DIMENSIONS); setSawsetText(Constants.SAWSET); @@ -181,11 +175,7 @@ public class InputPopup { window.close(); - - - - // Fungerende ny thread!!@@@@@ - // Gather data + // Gather data thread try { Thread thread = new Thread(() -> { @@ -209,9 +199,7 @@ public class InputPopup { thread.setDaemon(true); thread.interrupt(); thread.join(); - //Platform.exit(); thread.start(); - } catch (Exception ex) { ex.printStackTrace(); } @@ -241,101 +229,14 @@ public class InputPopup { liveDataThread.setDaemon(true); liveDataThread.interrupt(); liveDataThread.join(); - //Platform.exit(); liveDataThread.start(); - } catch (Exception ex) { ex.printStackTrace(); } + } + }); - } else { - NotificationPopUp.displayNotificationWindow("Please login!"); - } - } - - ); - -/* - // Fungerende ny thread!!@@@@@ - try{ - Thread thread = new Thread(new Runnable() { - - @Override - public void run() { - try { - // Henter her data fra databasen - loadSingleSeries(setInputParameters()); - //loadSingleSeries(); - //loadMultipleSeries(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - }); - thread.start(); - } catch (Exception ex) { - ex.printStackTrace(); - } - } - - ); - */ - - - - - -/* - class KwhThread implements Runnable { - - Map<Integer, Map<String, Number>> dataVariable; - private volatile boolean finished; - - @Override - public void run() { - try{ - dataVariable = setInputParameters(); - } catch (Exception ex) { - ex.printStackTrace(); - } - finished = true; - - synchronized (this){ - this.notify(); - } - } - - public Map<Integer, Map<String, Number>> getDataVariable() throws InterruptedException { - - synchronized (this){ - if(!finished) - this.wait(); - } - return dataVariable; - } - } - - KwhThread kwhThread = new KwhThread(); - - Thread thread = new Thread(kwhThread); - thread.setName("GetKwhThread"); - thread.start(); - - try { - loadSingleSeries(kwhThread.getDataVariable()); - } catch (Exception ex) { - ex.printStackTrace(); - } - - - */ - -/* - - - */ - - + // Adds all the components to the VBox VBox layout = new VBox(10); layout.getChildren().addAll(inputLabel, treeSpeciesInputLabel, treeSpeciesList, dimensionsInputLabel, dimensionsList, sawsetInputLabel, sawsetList, moistureGoalInputLabel, moistureList, startButton); diff --git a/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java b/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java index 4efc31586ad18c9cce9da6f8e8e724a9cbf4ee87..b49a065eaf8af9e9b324bdf99a08e7df5d5b4309 100644 --- a/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java +++ b/src/main/java/com/application/GUI/PopUpWindows/LoginPopup.java @@ -1,11 +1,10 @@ package com.application.GUI.PopUpWindows; -import javafx.event.EventHandler; +import com.application.DB.HelpingFunctions; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.input.KeyCode; -import javafx.scene.input.KeyEvent; import javafx.scene.layout.VBox; import javafx.stage.Modality; import javafx.stage.Stage; @@ -14,16 +13,23 @@ import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import static com.application.DB.AccountHandler.*; -import static com.application.DB.Constants.*; +import static com.application.DB.HelpingFunctions.isValidInput; import static com.application.GUI.Panes.CreateLogoBar.getLogin; +/** + * This class handles all login functionality + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class LoginPopup { + // Defines input fields private static PasswordField PASSWORD_TEXT_FIELD = new PasswordField(); private static TextField USERNAME_TEXT_FIELD = new TextField(); /** - * Tries to login + * Tries to log in * * @return a boolean if an error should be thrown or not. True gives no error, false throws an error. */ @@ -42,6 +48,9 @@ public class LoginPopup { } + /** + * This function adds all components to the login window + */ public static void login(){ Stage window = new Stage(); @@ -55,23 +64,30 @@ public class LoginPopup { Button loginButton = new Button("Login"); getPasswordTextField().clear(); + // Closes the window if the close button is pressed closeButton.setOnAction(event -> window.close()); + + // Handles login if enter is pressed on the keyboard in the password field getPasswordTextField().setOnKeyPressed( event -> { - if( event.getCode() == KeyCode.ENTER ) { - if(loginButtonPressed()){ - window.close(); + if (event.getCode() == KeyCode.ENTER) { + if(!isValidInput(getPasswordTextField().getText()) && !isValidInput(getUsernameTextField().getText())) { + if (loginButtonPressed()) { + window.close(); + } } } }); + // Handles login if the login button is pressed loginButton.setOnAction(event -> { - if(loginButtonPressed()){ - window.close(); + if(!isValidInput(getPasswordTextField().getText()) && !isValidInput(getUsernameTextField().getText())) { + if (loginButtonPressed()) { + window.close(); + } } }); - - + // Adds all components VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.getChildren().addAll(userNameLabel, getUsernameTextField(), passwordLabel, getPasswordTextField(), loginButton, closeButton); @@ -82,22 +98,28 @@ public class LoginPopup { window.showAndWait(); } + /** + * This function handles admin window functionality + */ public static void adminPopup(){ Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); window.setTitle("Admin window"); + // Information fields Label usernameLabel = new Label("Username: "); TextField usernameTextfield = new TextField(); - usernameTextfield.setText(getUserName()); + usernameTextfield.setText(HelpingFunctions.getUserName()); usernameTextfield.setEditable(false); + // Defines all buttons Button addUser = new Button("Add User"); Button deleteUser = new Button("Delete User"); Button logout = new Button("Logout"); Button close = new Button("Close"); + // Handles functionality for each button addUser.setOnAction(event -> { adminAddUser(); }); @@ -110,7 +132,7 @@ public class LoginPopup { }); close.setOnAction(event -> window.close()); - + // adds all components to the VBox VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.getChildren().addAll(usernameLabel, usernameTextfield, addUser, deleteUser, logout, close); @@ -121,12 +143,16 @@ public class LoginPopup { window.showAndWait(); } + /** + * This function adds a user to the database based on the input parameters given by the user + */ public static void adminAddUser(){ Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); window.setTitle("Admin window"); + // Defines all labels Label firstNameLabel = new Label("First Name: "); Label lastNameLabel = new Label("Last Name: "); Label phoneNoLabel = new Label("Phone No: "); @@ -135,6 +161,7 @@ public class LoginPopup { Label passwordSecondLabel = new Label("Password Repeat: "); Label isAdminLabel = new Label("Is Admin: "); + // Defines all input fields TextField firstNameTextField = new TextField(); TextField lastNameTextField = new TextField(); TextField phoneNoTextField = new TextField(); @@ -144,13 +171,23 @@ public class LoginPopup { CheckBox isAdminBox = new CheckBox(); isAdminBox.setSelected(false); + // Defines all buttons Button close = new Button("Close"); Button addUser = new Button("Add User"); + // Handles the functionality for each button close.setOnAction(event -> window.close()); addUser.setOnAction(event -> { - // If the passwords match each other, add the user, if not display an errormessage + // Validate input parameters + if(!isValidInput(firstNameTextField.getText()) && + !isValidInput(lastNameTextField.getText()) && + !isValidInput(phoneNoTextField.getText()) && + !isValidInput(usernameTextField.getText()) && + !isValidInput(passwordFirstField.getText()) && + !isValidInput(passwordSecondField.getText())) { + + // If the passwords match each other, add the user, if not, display an error message if(passwordFirstField.getText().contentEquals(passwordSecondField.getText())){ // Hashing the password if they match. @@ -166,7 +203,7 @@ public class LoginPopup { } catch (Exception e) { e.printStackTrace(); } - } else { + } }else { NotificationPopUp.displayNotificationWindow("Passwords does not match!"); passwordFirstField.clear(); passwordSecondField.clear(); @@ -174,7 +211,7 @@ public class LoginPopup { }); - + // Adds all components to the VBox VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.getChildren().addAll(firstNameLabel, firstNameTextField, lastNameLabel, lastNameTextField, @@ -188,34 +225,45 @@ public class LoginPopup { window.showAndWait(); } + /** + * This function handles deleting an account + */ public static void adminDeleteUser(){ Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); window.setTitle("Admin window"); + // Defines the input field Label usernameLabel = new Label("Username: "); TextField usernameTextField = new TextField(); + // Defines all buttons Button close = new Button("Close"); Button delete = new Button("Delete User"); + // Handle the functionality for each button close.setOnAction(event -> window.close()); delete.setOnAction(event -> { - try { - boolean results = deleteUser(usernameTextField.getText()); - if(results){ - NotificationPopUp.displayNotificationWindow(usernameTextField.getText()+" was successfully deleted!"); - window.close(); - } else { - NotificationPopUp.displayNotificationWindow("Could not find username: " + usernameTextField.getText()); - usernameTextField.clear(); + // Validate the input parameter + if(!isValidInput(usernameTextField.getText())) { + try { + // Checks if the user is deleted + boolean results = deleteUser(usernameTextField.getText()); + if (results) { + NotificationPopUp.displayNotificationWindow(usernameTextField.getText() + " was successfully deleted!"); + window.close(); + } else { + NotificationPopUp.displayNotificationWindow("Could not find username: " + usernameTextField.getText()); + usernameTextField.clear(); + } + } catch (Exception e) { + e.printStackTrace(); } - } catch (Exception e) { - e.printStackTrace(); } }); + // Adds the components to the VBox VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.getChildren().addAll(usernameLabel, usernameTextField, delete, close); @@ -226,43 +274,53 @@ public class LoginPopup { window.showAndWait(); } + /** + * This function handles logout functionality + */ public static void logout(){ getLogin().setText("Login"); - setFirstName(""); - setLastName(""); - setIsAdmin(false); - setPhoneNo(""); - setUserName(""); + HelpingFunctions.setFirstName(""); + HelpingFunctions.setLastName(""); + HelpingFunctions.setIsAdmin(false); + HelpingFunctions.setPhoneNo(""); + HelpingFunctions.setUserName(""); } + /** + * This function handles popup screen for a normal user + */ public static void userPopup(){ Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); window.setTitle("User window"); - + // Defines labels Label nameLabel = new Label("Name: "); Label phoneNoLabel = new Label("Phone no: "); + // Defines information fields TextField nameTextfield = new TextField(); TextField phoneNoTextField = new TextField(); - nameTextfield.setEditable(false); phoneNoTextField.setEditable(false); - nameTextfield.setText(getFirstName() + " " + getLastName()); - phoneNoTextField.setText(getPhoneNo()); - + // Sets the values + nameTextfield.setText(HelpingFunctions.getFirstName() + " " + HelpingFunctions.getLastName()); + phoneNoTextField.setText(HelpingFunctions.getPhoneNo()); + // Define buttons Button close = new Button("Close"); Button logout = new Button("Logout"); + + // Handle each button close.setOnAction(event -> window.close()); logout.setOnAction(event -> { logout(); window.close(); }); + // Adds all components to the VBox VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.getChildren().addAll(nameLabel, nameTextfield, phoneNoLabel, phoneNoTextField, logout, close); @@ -273,6 +331,12 @@ public class LoginPopup { window.showAndWait(); } + /** + * This function hash the password using the SHA-512 algorithm + * + * @param password input parameter for the password + * @return a 64-bit hashed string + */ public static String hashPassword(String password){ try { MessageDigest messageDigest = MessageDigest.getInstance("SHA-512"); diff --git a/src/main/java/com/application/GUI/PopUpWindows/NotificationPopUp.java b/src/main/java/com/application/GUI/PopUpWindows/NotificationPopUp.java index d652d5831d1cd76228311d0a3a1a344110e59e1f..7b6dbd244435aabd19698a3f69811a48fe238f12 100644 --- a/src/main/java/com/application/GUI/PopUpWindows/NotificationPopUp.java +++ b/src/main/java/com/application/GUI/PopUpWindows/NotificationPopUp.java @@ -10,19 +10,32 @@ import javafx.scene.text.TextAlignment; import javafx.stage.Modality; import javafx.stage.Stage; +/** + * This class handles functionality regarding a notification window + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class NotificationPopUp { + /** + * This function displays the notification window + * + * @param message input parameter for what to display in the window + */ public static void displayNotificationWindow(String message){ Stage window = new Stage(); window.initModality(Modality.APPLICATION_MODAL); window.setTitle("Notification window"); + // Defines label Label messageLabel = new Label(); messageLabel.setText(message); messageLabel.setWrapText(true); messageLabel.setTextAlignment(TextAlignment.CENTER); + // Define buttons and handles functionality Button close = new Button("Close"); close.setOnAction(event -> window.close()); @@ -32,6 +45,7 @@ public class NotificationPopUp { } }); + // Adds the components to the VBox VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.getChildren().addAll(messageLabel,close); diff --git a/src/main/java/com/application/GUI/PopUpWindows/OutputPopup.java b/src/main/java/com/application/GUI/PopUpWindows/OutputPopup.java index 9c4409b1b609c912b4c16e0e06c6051f3d2c4679..f0dd47b2436e260382b7239021646b26c37ef3ab 100644 --- a/src/main/java/com/application/GUI/PopUpWindows/OutputPopup.java +++ b/src/main/java/com/application/GUI/PopUpWindows/OutputPopup.java @@ -2,6 +2,7 @@ package com.application.GUI.PopUpWindows; import com.application.DB.Constants; import com.application.DB.DB; +import com.application.DB.Settings; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.Button; @@ -15,10 +16,20 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import static com.application.DB.Constants.IS_FINISHED; -import static com.application.DB.Constants.MAX_USER_INPUT_CHARACTERS; - +import static com.application.DB.Settings.MAX_USER_INPUT_CHARACTERS; +import static com.application.DB.HelpingFunctions.isValidInput; + +/** + * This class handles the output window for sending the resulted manual moisture levels + * + * @author Eilert Tunheim, Karin Pettersen, Mads Arnesen + * @version 1.0.0 + */ public class OutputPopup { + /** + * This function handles the output window and it's functionality + */ public static void displayOutputWindow(){ Stage window = new Stage(); @@ -47,23 +58,24 @@ public class OutputPopup { boolean err = false; - if(moistureCheckTextField.getCharacters().length() > MAX_USER_INPUT_CHARACTERS){ + // Validates inputs + if(isValidInput(moistureCheckTextField.getText())){ err = true; } + // Checks if there is an error if(!err){ if(!moistureCheckTextField.getCharacters().toString().isEmpty() && !moistureCheckTextField.getCharacters().toString().equals("Please enter a value")) { Constants.STOP_TIME = null; DB.pushManMoisture(moistureCheckTextField.getCharacters().toString()); - Constants.NUMBER_OF_CHECKS++; + Settings.NUMBER_OF_CHECKS++; window.close(); } else { NotificationPopUp.displayNotificationWindow("Please enter a value!"); moistureCheckTextField.setPromptText("Please enter a value"); } } else { - NotificationPopUp.displayNotificationWindow("A maximum of "+MAX_USER_INPUT_CHARACTERS+" characters is allowed!"); moistureCheckTextField.setText(""); moistureCheckTextField.setPromptText("Please enter a value"); } @@ -82,10 +94,12 @@ public class OutputPopup { boolean err = false; - if(moistureCheckTextField.getCharacters().length() > MAX_USER_INPUT_CHARACTERS){ + // Validates inputs + if(isValidInput(moistureCheckTextField.getText())){ err = true; } + // Checks if there is an error if(!err) { if (!moistureCheckTextField.getCharacters().toString().isEmpty() && !moistureCheckTextField.getCharacters().toString().equals("Please enter a value")) { @@ -98,7 +112,6 @@ public class OutputPopup { moistureCheckTextField.setPromptText("Please enter a value"); } } else { - NotificationPopUp.displayNotificationWindow("A maximum of "+MAX_USER_INPUT_CHARACTERS+" characters is allowed!"); moistureCheckTextField.setText(""); moistureCheckTextField.setPromptText("Please enter a value"); } @@ -107,7 +120,7 @@ public class OutputPopup { } }); - + // Adds the components to the VBox VBox layout = new VBox(10); layout.setAlignment(Pos.CENTER); layout.setSpacing(10); diff --git a/src/main/java/com/application/Main.java b/src/main/java/com/application/Main.java index a20d33c4374e5a21560cb5274a300ab06b08f9b1..401fa340e04f330fa24d2f0714b71eb659035999 100644 --- a/src/main/java/com/application/Main.java +++ b/src/main/java/com/application/Main.java @@ -56,13 +56,16 @@ public class Main extends Application { /** * Starts the application * - * @param args - * @throws IOException + * @param args input parameter + * @throws IOException throws exception if an error occurs */ public static void main(String[] args) throws IOException { launch(args); } + /** + * This function exists the application and stops all threads + */ public static void exitApplication(){ Platform.exit(); System.exit(0); @@ -89,8 +92,8 @@ public class Main extends Application { /** * Sets the primaryStage and sets the scene for the window. * - * @param primaryStage - * @throws Exception + * @param primaryStage The main stage + * @throws Exception throws exception if an error occurs */ @Override public void start(Stage primaryStage) throws Exception { @@ -143,6 +146,7 @@ public class Main extends Application { InputPopup.display(); } + // Getters and setters public static void setTreeSpeciesText(String treeSpeciesText) { Main.treeSpeciesText.setText(treeSpeciesText); } diff --git a/src/main/resources/META-INF/MANIFEST.MF b/src/main/resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..797d99b7b0f4c83c466174cd972c3ce28a801788 --- /dev/null +++ b/src/main/resources/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.application.Main + diff --git a/target/classes/META-INF/MANIFEST.MF b/target/classes/META-INF/MANIFEST.MF new file mode 100644 index 0000000000000000000000000000000000000000..797d99b7b0f4c83c466174cd972c3ce28a801788 --- /dev/null +++ b/target/classes/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: com.application.Main + diff --git a/target/classes/com/application/DB/AccountHandler.class b/target/classes/com/application/DB/AccountHandler.class index 02a8049690ac1479b6016badc13cbef09e5aa87a..d5110b4f58f1a9949a42881752efd486a4612f3e 100644 Binary files a/target/classes/com/application/DB/AccountHandler.class and b/target/classes/com/application/DB/AccountHandler.class differ diff --git a/target/classes/com/application/DB/Constants.class b/target/classes/com/application/DB/Constants.class index b1d3fc3702ed1019a1d6296da0a1b093a81acaa1..5896c31289630e5a8161b6252e25be17bf42f76d 100644 Binary files a/target/classes/com/application/DB/Constants.class and b/target/classes/com/application/DB/Constants.class differ diff --git a/target/classes/com/application/DB/DB.class b/target/classes/com/application/DB/DB.class index f9cd0427f1d17a46b71d6a7a175b9be36af824b4..a825339b6b5ed204b006897d5466f95bb97b51c5 100644 Binary files a/target/classes/com/application/DB/DB.class and b/target/classes/com/application/DB/DB.class differ diff --git a/target/classes/com/application/DB/HelpingFunctions.class b/target/classes/com/application/DB/HelpingFunctions.class index 2847eab1c308e4df52d0b801cd32249daaf9dd44..92ff3b35eb143b82ea5d2440d08608ab820fcb77 100644 Binary files a/target/classes/com/application/DB/HelpingFunctions.class and b/target/classes/com/application/DB/HelpingFunctions.class differ diff --git a/target/classes/com/application/DB/Settings.class b/target/classes/com/application/DB/Settings.class index 11c74e1770b4ec970e9fab118316e9a475a22fa4..8f101ba0feab083e0f1ec8ecd35a63097fbd45cb 100644 Binary files a/target/classes/com/application/DB/Settings.class and b/target/classes/com/application/DB/Settings.class differ diff --git a/target/classes/com/application/GUI/LineChartFunctionality.class b/target/classes/com/application/GUI/LineChartFunctionality.class index d59122510be4edd89ff2e579aafbfee5b4c128b7..1f3b0194298587fa67b0527fe214a6213476a565 100644 Binary files a/target/classes/com/application/GUI/LineChartFunctionality.class and b/target/classes/com/application/GUI/LineChartFunctionality.class differ diff --git a/target/classes/com/application/GUI/Panes/CreateBottomBar.class b/target/classes/com/application/GUI/Panes/CreateBottomBar.class index b4e9e9dc33f1bc2c8b688aba5b9d63b2e41b611a..4c742e7dc3d2f30e0412192687caccef2b6300ff 100644 Binary files a/target/classes/com/application/GUI/Panes/CreateBottomBar.class and b/target/classes/com/application/GUI/Panes/CreateBottomBar.class differ diff --git a/target/classes/com/application/GUI/Panes/CreateLogoBar.class b/target/classes/com/application/GUI/Panes/CreateLogoBar.class index a6b54397e6e4553d0ef452e5a1e8aac47fb7089e..233a78b6c5fda09a2b9465f1c44a328c70d11cde 100644 Binary files a/target/classes/com/application/GUI/Panes/CreateLogoBar.class and b/target/classes/com/application/GUI/Panes/CreateLogoBar.class differ diff --git a/target/classes/com/application/GUI/Panes/CreateMenuBar.class b/target/classes/com/application/GUI/Panes/CreateMenuBar.class index 6bd812b1113a0d44265474590eaeb25e9a949414..df916986db78dfadb70449a6b5641169c1a2db2f 100644 Binary files a/target/classes/com/application/GUI/Panes/CreateMenuBar.class and b/target/classes/com/application/GUI/Panes/CreateMenuBar.class differ diff --git a/target/classes/com/application/GUI/Panes/CreateSideBar$1WorkerThread.class b/target/classes/com/application/GUI/Panes/CreateSideBar$1WorkerThread.class index 1c4762d467e67e469a7eace70195ca0bcf96ca45..ea4bc09aca87c66b1325eb7c8d3dbc5820a34045 100644 Binary files a/target/classes/com/application/GUI/Panes/CreateSideBar$1WorkerThread.class and b/target/classes/com/application/GUI/Panes/CreateSideBar$1WorkerThread.class differ diff --git a/target/classes/com/application/GUI/Panes/CreateSideBar.class b/target/classes/com/application/GUI/Panes/CreateSideBar.class index 26d0b938bb9c2378c6bac3d61839fd7c708458af..c83aa2a4f9531d929a93f39d92598537e3015791 100644 Binary files a/target/classes/com/application/GUI/Panes/CreateSideBar.class and b/target/classes/com/application/GUI/Panes/CreateSideBar.class differ diff --git a/target/classes/com/application/GUI/PopUpWindows/InputPopup.class b/target/classes/com/application/GUI/PopUpWindows/InputPopup.class index 728dd498b6efc1a0bb249930929c014285629008..e7eb12e410bd1889aa3b7fe3118b589c4c4b4f94 100644 Binary files a/target/classes/com/application/GUI/PopUpWindows/InputPopup.class and b/target/classes/com/application/GUI/PopUpWindows/InputPopup.class differ diff --git a/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class b/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class index 19715f0e293043d1ef3fbf45b4642726e97bca2d..220487c3fd9639673b726883ff432a67acd271b9 100644 Binary files a/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class and b/target/classes/com/application/GUI/PopUpWindows/LoginPopup.class differ diff --git a/target/classes/com/application/GUI/PopUpWindows/NotificationPopUp.class b/target/classes/com/application/GUI/PopUpWindows/NotificationPopUp.class index 46fddb3bb686ed5a92fd6e5aad2e1355fefd9ccb..a9c00c10e72e42d87e8068ddb116b8591b6dd678 100644 Binary files a/target/classes/com/application/GUI/PopUpWindows/NotificationPopUp.class and b/target/classes/com/application/GUI/PopUpWindows/NotificationPopUp.class differ diff --git a/target/classes/com/application/GUI/PopUpWindows/OutputPopup.class b/target/classes/com/application/GUI/PopUpWindows/OutputPopup.class index 04851fe4919902ae6f14901bab0a633baec5c884..fcda004495e6d98adc5ccc4fb3ca69b349caa1d5 100644 Binary files a/target/classes/com/application/GUI/PopUpWindows/OutputPopup.class and b/target/classes/com/application/GUI/PopUpWindows/OutputPopup.class differ diff --git a/target/classes/com/application/Main.class b/target/classes/com/application/Main.class index 6b48ef79d20cc6414449b1d7dd4c8f8131946f60..55eee43285ec1448f838753dfb2aec73ec2d8c46 100644 Binary files a/target/classes/com/application/Main.class and b/target/classes/com/application/Main.class differ