Skip to content

Instantly share code, notes, and snippets.

@starks981
Created July 28, 2018 01:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save starks981/e9ebc5900cc32226b4071b1568be65c0 to your computer and use it in GitHub Desktop.
Save starks981/e9ebc5900cc32226b4071b1568be65c0 to your computer and use it in GitHub Desktop.
Task Management Application/To Do List using JavaFX
/*
* 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();
}
}
}
.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