-
-
Save starks981/e9ebc5900cc32226b4071b1568be65c0 to your computer and use it in GitHub Desktop.
Task Management Application/To Do List using JavaFX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* App for task management | |
* Author - Chris Starkey | |
* Work Started 7-6-2018 | |
* Work Completed 7-27-2018 | |
*/ | |
// import classes needed for the program | |
import java.io.BufferedReader; | |
import java.io.BufferedWriter; | |
import java.io.FileReader; | |
import java.io.FileWriter; | |
import java.util.LinkedList; | |
import javafx.application.Application; | |
import javafx.geometry.Insets; | |
import javafx.geometry.Pos; | |
import javafx.scene.Scene; | |
import javafx.scene.control.Alert; | |
import javafx.scene.control.Alert.AlertType; | |
import javafx.scene.control.Button; | |
import javafx.scene.control.CheckBox; | |
import javafx.scene.control.Label; | |
import javafx.scene.control.PasswordField; | |
import javafx.scene.control.ScrollPane; | |
import javafx.scene.control.TextField; | |
import javafx.scene.layout.FlowPane; | |
import javafx.scene.layout.GridPane; | |
import javafx.scene.layout.HBox; | |
import javafx.scene.layout.VBox; | |
import javafx.scene.text.Text; | |
import javafx.stage.Modality; | |
import javafx.stage.Stage; | |
public class Main extends Application { | |
// Main Stage | |
Stage window; | |
// Login Scene and a Task Scene | |
Scene loginScene, taskScene; | |
// String to capture login name | |
String loggedIn; | |
// Linked List that will hold the current list of tasks | |
LinkedList<String> taskList = new LinkedList<>(); | |
// Set the root node as a GridPane | |
GridPane root = new GridPane(); | |
// Text to show error if login is incorrect | |
Text errorMsg = new Text(); | |
// Text that says login | |
Text loginText = new Text("Login:"); | |
// Create a label for the username textfield | |
Label usernameLbl = new Label("Username"); | |
// Create a label for the password textfield | |
Label passwordLbl = new Label("Password"); | |
// Create a textfield for the user's username | |
TextField usernameTfld = new TextField(); | |
// Create a passwordfield for the user's password | |
PasswordField passwordTfld = new PasswordField(); | |
// Create a login button | |
Button loginBtn = new Button("Login"); | |
// Create a HBox to store the loginBtn | |
HBox loginHbox = new HBox(10); | |
// Create a vbox to hold the task list | |
VBox taskDisplay = new VBox(10); | |
// Create an array of checkboxes with unknown size | |
CheckBox[] cbs; | |
// Main Method will call launch to start my JavaFX application | |
public static void main(String args[]) { | |
launch(); | |
} | |
// Override the start method | |
public void start(Stage myStage) { | |
// Set the main stage | |
window = myStage; | |
// Give a title to the stage | |
window.setTitle("Task Manager"); | |
// Align the root node in the center | |
root.setAlignment(Pos.CENTER); | |
// Set a horizontal gap between controls | |
root.setHgap(10); | |
// Set a vertical gap between controls | |
root.setVgap(10); | |
// Set padding of the root node | |
root.setPadding(new Insets(25, 25, 25, 25)); | |
// Align the login button to the bottom right | |
loginHbox.setAlignment(Pos.BOTTOM_RIGHT); | |
// Add the login button to the hbox | |
loginHbox.getChildren().add(loginBtn); | |
// Lambda expression to handle the button click event | |
// If credentials are wrong display error. | |
loginBtn.setOnAction((ae) -> { | |
// On click of the login button, call the loginAttempt method. | |
// If true redirect the user to the taskscene | |
if (loginAttempt(usernameTfld.getText(), passwordTfld.getText())) { | |
// Call the buildTaskScene method | |
buildTaskScene(); | |
// Set the taskScene on the main stage | |
window.setScene(taskScene); | |
// Clear the error message text | |
errorMsg.setText(""); | |
} | |
// If false, display an error message to the user | |
else { | |
errorMsg.setText("Invalid Credentials.\nPlease update and try again."); | |
} | |
}); | |
// Add the components to the root node | |
root.add(loginText, 0, 0, 2, 1); | |
root.add(usernameLbl, 0, 1); | |
root.add(usernameTfld, 1, 1); | |
root.add(passwordLbl, 0, 2); | |
root.add(passwordTfld, 1, 2); | |
root.add(loginHbox, 1, 3); | |
root.add(errorMsg, 1, 5); | |
// Create the scene for the root node | |
loginScene = new Scene(root, 350, 200); | |
// Set the id of the logintext for the css | |
loginText.setId("headerText"); | |
// Set the id of the errormsg for the css | |
errorMsg.setId("errorMsg"); | |
// Load the style sheet | |
loginScene.getStylesheets().add("Task.css"); | |
// Add the scene to the stage | |
window.setScene(loginScene); | |
// Show the stage | |
window.show(); | |
} | |
// Method to build task scene | |
void buildTaskScene() { | |
// Set the root of the task scene as a grid pane | |
GridPane root2 = new GridPane(); | |
// Center the root node | |
root2.setAlignment(Pos.CENTER); | |
// Set a horizontal gap between controls | |
root2.setHgap(10); | |
// Set a vertical gap between controls | |
root2.setVgap(10); | |
// Set padding of the root node | |
root2.setPadding(new Insets(25, 25, 25, 25)); | |
// Build HBox welcome menu | |
HBox menu = new HBox(); | |
// Text to display a welcome message to the user | |
Text welcome = new Text("Welcome " + loggedIn + "!"); | |
// Set the css id of the welcome message | |
welcome.setId("headerText"); | |
// Add the welcome message to the hbox | |
menu.getChildren().addAll(welcome); | |
// Create an hbox to hold 3 buttons | |
HBox bottomMenu = new HBox(10); | |
// Create a log out button | |
Button logOut = new Button("Log Out"); | |
// Lambda expression for logout button click | |
logOut.setOnAction((ae) -> { | |
// Call the delete tasks method | |
deleteTasks(); | |
// Clear the username textfield | |
usernameTfld.clear(); | |
// Clear the password textfield | |
passwordTfld.clear(); | |
// Set the stage with the loginScene | |
window.setScene(loginScene); | |
}); | |
// Create an add task button | |
Button addTask = new Button("Add Task"); | |
// Lambda expression for the add task button click | |
addTask.setOnAction((ae) -> { | |
// Create a new popup window (stage) | |
Stage stage = new Stage(); | |
// Set the title of the new stage | |
stage.setTitle("Add Task"); | |
// Create a flowpane for the root node | |
FlowPane pane = new FlowPane(); | |
// Center the flowpane | |
pane.setAlignment(Pos.CENTER); | |
// Set a 10 pixel gap between controls | |
pane.setHgap(10); | |
// Create an add button | |
Button add = new Button("Add"); | |
// Create a textfield for the new task addition | |
TextField addTfld = new TextField(); | |
// Lambda expression for the add task button click | |
add.setOnAction((e) -> { | |
// Check to ensure the textfield is not empty | |
if (!addTfld.getText().equals("")) { | |
// Try to write to the users task file | |
try { | |
// Create a buffered writer to write to the file | |
BufferedWriter bw = new BufferedWriter(new FileWriter("resources\\" + loggedIn + "Tasks.txt", true)); | |
// If the taskList is not empty then write a new line | |
// then write the contents of the text field | |
if (!taskList.isEmpty()) { | |
bw.newLine(); | |
bw.write(addTfld.getText()); | |
} | |
// If the tasklist is empty then write the contents of the text field | |
else { | |
bw.write(addTfld.getText()); | |
} | |
// Close the buffered writer | |
bw.close(); | |
// Catch any exceptions and display issue to the user | |
} | |
catch (Exception exc) { | |
Alert alert = new Alert(AlertType.WARNING); | |
alert.setTitle("Error"); | |
alert.setHeaderText("Error: File Not Found"); | |
alert.showAndWait(); | |
} | |
// Call the loadTasks method to reload the taskScene with the newly added task | |
loadTasks(); | |
} | |
// Close the stage | |
stage.close(); | |
}); | |
// Add the textfield and add button to the root | |
pane.getChildren().addAll(addTfld, add); | |
// Add the root node to a Scene | |
Scene addTaskScene = new Scene(pane, 250, 100); | |
// Load the style sheet | |
addTaskScene.getStylesheets().add("Task.css"); | |
// Set the scene on the stage | |
stage.setScene(addTaskScene); | |
// Ensure the user enters a task or closes stage before going back to taskScene | |
stage.initModality(Modality.APPLICATION_MODAL); | |
// Show the popup window (stage) | |
stage.show(); | |
}); | |
// Create a clearCompleted button | |
Button clearCompleted = new Button("Clear Completed"); | |
// Lambda expression to handle the clear completed button click | |
clearCompleted.setOnAction((ae) -> { | |
// call the deleteTasks method | |
deleteTasks(); | |
// call the loadTasks method | |
loadTasks(); | |
}); | |
// Add the buttons to the bottom menu | |
bottomMenu.getChildren().addAll(addTask, clearCompleted, logOut); | |
// Center the bottom Hbox | |
bottomMenu.setAlignment(Pos.CENTER); | |
// Create a scrollpane for the taskDisplay | |
ScrollPane sp = new ScrollPane(taskDisplay); | |
// Set the Vertical scrollbar to only show when necessary | |
sp.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); | |
// Set the horizontal scrollbar to only show when necessary | |
sp.setHbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED); | |
// Set a preferred size for the scrollpane | |
sp.setPrefSize(300, 200); | |
// Call the loadtasks method | |
loadTasks(); | |
// Add the components to the root node | |
root2.add(menu, 1, 0); | |
root2.add(sp, 1, 3); | |
root2.add(bottomMenu, 1, 5); | |
// Set the root node to the taskScene | |
taskScene = new Scene(root2, 400, 300); | |
// Load the style sheet to the taskScene | |
taskScene.getStylesheets().add("Task.css"); | |
// Lambda Expression to delete the tasks if user closes window | |
// without logging out | |
window.setOnCloseRequest(event -> deleteTasks()); | |
} | |
// Method to check login credentials | |
boolean loginAttempt(String username, String password) { | |
// String to store the line read from the file | |
String reader; | |
// Try with resources block to create a new Filereader and compare each line | |
// with the parameters | |
try (BufferedReader br = new BufferedReader(new FileReader("resources\\LoginInfo.txt"))) { | |
while ((reader = br.readLine()) != null) { | |
// If there is a match then return true and set loggedIn to the username | |
if (reader.equals(username + "\t" + password)) { | |
loggedIn = username; | |
return true; | |
} | |
} | |
} | |
// If there was an exception show an error to the user | |
catch (Exception e) { | |
Alert alert = new Alert(AlertType.WARNING); | |
alert.setTitle("Error"); | |
alert.setHeaderText("Error: File Not Found"); | |
alert.showAndWait(); | |
} | |
// If no match was found return false | |
return false; | |
} | |
// Method to load the tasks stored in the users file | |
void loadTasks() { | |
// String to store the line read from the file | |
String reader; | |
// Empty the taskList for a fresh load of tasks | |
while (!taskList.isEmpty()) { | |
taskList.remove(0); | |
} | |
// Clear the taskDisplay for a fresh load of tasks | |
taskDisplay.getChildren().clear(); | |
// Try with resources block to create a new filereader | |
try (BufferedReader br = new BufferedReader(new FileReader("resources\\" + loggedIn + "Tasks.txt"))) { | |
// While there is more to read from the file | |
while ((reader = br.readLine()) != null) { | |
// Add the line to the taskList | |
taskList.add(reader); | |
} | |
// Initialize the size of the cbs array to the size | |
// of the tasklist | |
cbs = new CheckBox[taskList.size()]; | |
// Loop through the taskList | |
for (int i = 0; i < taskList.size(); i++) { | |
// Create a new checkbox and set the label to the tasklist element | |
CheckBox cb = new CheckBox(taskList.get(i)); | |
// Add the checkbox to the cbs array | |
cbs[i] = cb; | |
// Add the checkbox to the taskDisplay | |
taskDisplay.getChildren().add(cb); | |
} | |
} | |
// If there was an exception show an error to the user | |
catch (Exception e) { | |
Alert alert = new Alert(AlertType.WARNING); | |
alert.setTitle("Error"); | |
alert.setHeaderText("Error: File Not Found"); | |
alert.showAndWait(); | |
} | |
} | |
// Method to check if a task shoule be removed | |
void deleteTasks() { | |
// Clear the TaskList | |
taskList.clear(); | |
// Loop through the checkbox array to see if it was checked | |
for (int i = 0; i < cbs.length; i++) { | |
if (!cbs[i].isSelected()) { | |
// If it was not then add it back to the tasklist | |
taskList.add(cbs[i].getText()); | |
} | |
} | |
// Try block to write to the users task file | |
try { | |
BufferedWriter bw = new BufferedWriter(new FileWriter("resources\\" + loggedIn + "Tasks.txt", false)); | |
// Loop through the taskList | |
for (int i = 0; i < taskList.size(); i++) { | |
// If you are at the last element to add | |
// Add the task to the file | |
if (i == taskList.size() - 1) { | |
bw.write(taskList.get(i)); | |
} | |
// Else, add the task to the file plus a newline | |
else { | |
bw.write(taskList.get(i)); | |
bw.newLine(); | |
} | |
} | |
// Close the buffered writer | |
bw.close(); | |
} | |
// If an exception was caught, display an error to the user | |
catch (Exception e) { | |
Alert alert = new Alert(AlertType.WARNING); | |
alert.setTitle("Error"); | |
alert.setHeaderText("Error: File Not Found"); | |
alert.showAndWait(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.button{ | |
-fx-background-color: #4EB1BA; | |
-fx-text-fill: #E9E9E9; | |
} | |
.button:hover{ | |
-fx-background-color: #E9E9E9; | |
-fx-text-fill: #4EB1BA; | |
} | |
.button:focused{ | |
-fx-background-color: #E9E9E9; | |
-fx-text-fill: #4EB1BA; | |
} | |
.check-box:selected .text { | |
-fx-strikethrough: true; | |
-fx-fill: red; | |
} | |
.check-box:selected:hover .text { | |
-fx-strikethrough: true; | |
-fx-fill: red; | |
} | |
.check-box:selected:focused .text { | |
-fx-strikethrough: true; | |
-fx-fill: red; | |
} | |
.check-box .text { | |
-fx-fill: white; | |
} | |
.check-box:hover .text{ | |
-fx-fill: #4EB1BA; | |
} | |
.check-box:focused .text{ | |
-fx-fill: #4EB1BA; | |
} | |
#headerText{ | |
-fx-font: 16px Arial; | |
-fx-fill: #E9E9E9; | |
-fx-font-weight: bold; | |
} | |
#errorMsg{ | |
-fx-fill: RED; | |
} | |
.root{ | |
-fx-background: #222930; | |
-fx-font-weight: bold; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment