Building a Todo App with Core Java

In this tutorial, we will learn how to create a simple Todo application using Core Java. This application will allow users to add, update, delete, and list tasks, providing a simple yet powerful tool for managing daily activities. We'll delve into the implementation details of three main components: Task, TaskManager, and Main.

Setting Up the Project Structure

The project is organized into three main classes:
  • Task.java: Defines the properties and behaviors of a task.
  • TaskManager.java: Manages a list of tasks and provides functionalities such as add, update, delete, and list.
  • Main.java: Contains the application's entry point and user interface.
  • Additionally, we have an enumeration Category.java that defines the possible categories for tasks.

Step 1: Defining the Task Class

Each task in our Todo application has an ID, description, category, and completion status. Let's create a Task class and add the following code to it:
package net.javaguides.todo;

import java.io.Serializable;

public class Task implements Serializable {
    private static final long serialVersionUID = 1L;

    private int id;
    private String description;
    private Category category;
    private boolean isCompleted;

    public Task(int id, String description, Category category) {
        this.id = id;
        this.description = description;
        this.category = category;
        this.isCompleted = false;
    }

    // Getters and Setters
    public int getId() { return id; }
    public String getDescription() { return description; }
    public void setDescription(String description) { this.description = description; }
    public Category getCategory() { return category; }
    public void setCategory(Category category) { this.category = category; }
    public boolean isCompleted() { return isCompleted; }
    public void setCompleted(boolean completed) { isCompleted = completed; }

    @Override
    public String toString() {
        return "Task{" +
                "id=" + id +
                ", description='" + description + '\'' +
                ", category=" + category +
                ", isCompleted=" + isCompleted +
                '}';
    }
}

This class implements Serializable, which allows tasks to be serialized and deserialized when saving to or loading from a file. We use an enum for categories to ensure all tasks conform to a predefined set of categories.
package net.javaguides.todo;

public enum Category {
    PERSONAL, WORK, HOBBY, OTHER
}

Step 2: Creating the TaskManager Class 

The TaskManager class is the heart of our application. It manages the tasks and interacts with the file system to persist tasks between sessions.

Let's create a TaskManager class and add the following code to it:
package net.javaguides.todo;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class TaskManager {
    private List<Task> tasks = new ArrayList<>();
    private final String filePath = "tasks.dat";

    public TaskManager() {
        loadTasks();
    }

    public void addTask(Task task) {
        tasks.add(task);
        saveTasks();
    }

    public void updateTask(int id, String description, Category category, boolean isCompleted) {
        tasks.stream()
                .filter(task -> task.getId() == id)
                .findFirst()
                .ifPresent(task -> {
                    task.setDescription(description);
                    task.setCategory(category);
                    task.setCompleted(isCompleted);
                    saveTasks();
                });
    }

    public void deleteTask(int id) {
        tasks.removeIf(task -> task.getId() == id);
        saveTasks();
    }

    public void listTasks() {
        tasks.forEach(System.out::println);
    }

    private void saveTasks() {
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filePath))) {
            out.writeObject(tasks);
        } catch (IOException e) {
            System.out.println("Error saving tasks.");
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unchecked")
    private void loadTasks() {
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath))) {
            tasks = (List<Task>) in.readObject();
        } catch (FileNotFoundException e) {
            System.out.println("No previous tasks found. Starting fresh.");
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("Error loading tasks.");
            e.printStackTrace();
        }
    }

    public int getNextId() {
        return tasks.isEmpty() ? 1 : tasks.get(tasks.size() - 1).getId() + 1;
    }
}
addTask(Task task): Adds a new task to the list and saves the updated list to a file. 

updateTask(int id, String description, Category category, boolean isCompleted): Updates an existing task based on its ID. 

deleteTask(int id): Removes a task from the list by its ID. 

listTasks(): Prints all tasks to the console. 

saveTasks(): Serializes the list of tasks to a file. 

loadTasks(): Deserializes the list of tasks from a file if it exists. 

Step 3: Implementing the Main Class 

The Main class provides a simple text-based user interface for interacting with the Todo application. It handles user input and calls the appropriate methods in TaskManager.
package net.javaguides.todo;

import java.util.Scanner;

public class Main {
    private static Scanner scanner = new Scanner(System.in);
    private static TaskManager taskManager = new TaskManager();

    public static void main(String[] args) {
        while (true) {
            System.out.println("\nTo-Do List Application");
            System.out.println("1. Add Task");
            System.out.println("2. Update Task");
            System.out.println("3. Delete Task");
            System.out.println("4. List Tasks");
            System.out.println("5. Exit");
            System.out.print("Enter your choice: ");
            int choice = scanner.nextInt();
            scanner.nextLine(); // Consume newline

            switch (choice) {
                case 1:
                    addTask();
                    break;
                case 2:
                    updateTask();
                    break;
                case 3:
                    deleteTask();
                    break;
                case 4:
                    taskManager.listTasks();
                    break;
                case 5:
                    System.out.println("Exiting...");
                    return;
                default:
                    System.out.println("Invalid choice. Please select again.");
                    break;
            }
        }
    }

    private static void addTask() {
        System.out.println("Adding a new task:");
        System.out.print("Enter task description: ");
        String description = scanner.nextLine();
        System.out.print("Enter task category (PERSONAL, WORK, HOBBY, OTHER): ");
        String categoryStr = scanner.nextLine().toUpperCase();
        Category category = Category.valueOf(categoryStr);
        Task task = new Task(taskManager.getNextId(), description, category);
        taskManager.addTask(task);
        System.out.println("Task added successfully.");
    }

    private static void updateTask() {
        System.out.println("Updating an existing task:");
        System.out.print("Enter task ID: ");
        int id = scanner.nextInt();
        scanner.nextLine(); // Consume newline
        System.out.print("Enter new description: ");
        String description = scanner.nextLine();
        System.out.print("Enter new category (PERSONAL, WORK, HOBBY, OTHER): ");
        String categoryStr = scanner.nextLine().toUpperCase();
        Category category = Category.valueOf(categoryStr);
        System.out.print("Is the task completed? (true/false): ");
        boolean isCompleted = scanner.nextBoolean();
        scanner.nextLine(); // Consume newline

        taskManager.updateTask(id, description, category, isCompleted);
        System.out.println("Task updated successfully.");
    }


    private static void deleteTask() {
        System.out.println("Deleting an existing task:");
        System.out.print("Enter task ID: ");
        int id = scanner.nextInt();
        scanner.nextLine(); // Consume newline
        taskManager.deleteTask(id);
        System.out.println("Task deleted successfully.");
    }
}
In the main method, we present the user with a menu of options. Depending on the user's choice, we call methods such as addTask(), updateTask(), deleteTask(), or listTasks()

Step 4: Running the Application 

To run the application, simply compile and execute the Main class. You'll be greeted with a menu of options to interact with your Todo list. 

Here is the sample output of this application:
To-Do List Application
1. Add Task
2. Update Task
3. Delete Task
4. List Tasks
5. Exit
Enter your choice: 1
Adding a new task:
Enter task description: Build Simple Java Project
Enter task category (PERSONAL, WORK, HOBBY, OTHER): WORK
Task added successfully.

To-Do List Application
1. Add Task
2. Update Task
3. Delete Task
4. List Tasks
5. Exit
Enter your choice: 2
Updating an existing task:
Enter task ID: 1
Enter new description: Build Simple Java Project
Enter new category (PERSONAL, WORK, HOBBY, OTHER): WORK
Is the task completed? (true/false): true
Task updated successfully.

To-Do List Application
1. Add Task
2. Update Task
3. Delete Task
4. List Tasks
5. Exit
Enter your choice: 4
Task{id=1, description='Build Simple Java Project', category=WORK, isCompleted=true}

To-Do List Application
1. Add Task
2. Update Task
3. Delete Task
4. List Tasks
5. Exit
Enter your choice: 3
Deleting an existing task:
Enter task ID: 1
Task deleted successfully.

To-Do List Application
1. Add Task
2. Update Task
3. Delete Task
4. List Tasks
5. Exit
Enter your choice: 5
Exiting...

The application saves your tasks to a file named tasks.dat, ensuring that your data persists across sessions. 

Conclusion 

This step-by-step guide has walked you through building a basic Todo application in Core Java. By following this tutorial, you've learned about object serialization, managing collections, and implementing a simple command-line interface. This application serves as a great starting point for diving deeper into Java programming and can be extended with additional features like setting task priorities or reminders. 

Happy coding, and enjoy managing your tasks more efficiently with your new Todo app!

Comments