Simple To-Do List Project in Java

Introduction

A To-Do List application is a practical beginner-to-intermediate Java project that demonstrates core programming concepts such as collections, user input handling, file I/O, object-oriented design, and basic CRUD operations (Create, Read, Update, Delete). This console-based application allows users to manage tasks with descriptions, completion status, and persistence across sessions using file storage. The implementation emphasizes clean code structure, error handling, and user-friendly interaction.


Features

  • Add new tasks with descriptions
  • View all tasks (with completion status)
  • Mark tasks as completed
  • Delete tasks
  • Save tasks to a file (todo.txt) on exit
  • Load tasks from file on startup
  • Input validation and error handling
  • Menu-driven console interface

Complete Source Code

1. Task.java – Task Model Class

// Task.java
public class Task {
private String description;
private boolean completed;
public Task(String description) {
this.description = description;
this.completed = false;
}
public String getDescription() {
return description;
}
public boolean isCompleted() {
return completed;
}
public void setCompleted(boolean completed) {
this.completed = completed;
}
@Override
public String toString() {
return (completed ? "[✓] " : "[ ] ") + description;
}
}

2. TodoList.java – Core Logic Class

// TodoList.java
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public class TodoList {
private List<Task> tasks;
private static final String FILE_NAME = "todo.txt";
public TodoList() {
this.tasks = new ArrayList<>();
loadTasks();
}
public void addTask(String description) {
tasks.add(new Task(description));
}
public void viewTasks() {
if (tasks.isEmpty()) {
System.out.println("No tasks in the list.");
return;
}
for (int i = 0; i < tasks.size(); i++) {
System.out.println((i + 1) + ". " + tasks.get(i));
}
}
public void markTaskCompleted(int index) {
if (isValidIndex(index)) {
tasks.get(index).setCompleted(true);
System.out.println("Task marked as completed.");
} else {
System.out.println("Invalid task number.");
}
}
public void deleteTask(int index) {
if (isValidIndex(index)) {
tasks.remove(index);
System.out.println("Task deleted.");
} else {
System.out.println("Invalid task number.");
}
}
private boolean isValidIndex(int index) {
return index >= 0 && index < tasks.size();
}
public void saveTasks() {
try (PrintWriter writer = new PrintWriter(new FileWriter(FILE_NAME))) {
for (Task task : tasks) {
writer.println((task.isCompleted() ? "1" : "0") + "|" + task.getDescription());
}
System.out.println("Tasks saved to " + FILE_NAME);
} catch (IOException e) {
System.err.println("Error saving tasks: " + e.getMessage());
}
}
private void loadTasks() {
if (!Files.exists(Paths.get(FILE_NAME))) return;
try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
String line;
while ((line = reader.readLine()) != null) {
String[] parts = line.split("\\|", 2);
if (parts.length == 2) {
boolean completed = parts[0].equals("1");
Task task = new Task(parts[1]);
task.setCompleted(completed);
tasks.add(task);
}
}
System.out.println("Loaded " + tasks.size() + " tasks from " + FILE_NAME);
} catch (IOException e) {
System.err.println("Error loading tasks: " + e.getMessage());
}
}
}

3. Main.java – Application Entry Point

// Main.java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
TodoList todoList = new TodoList();
Scanner scanner = new Scanner(System.in);
boolean running = true;
System.out.println("=== Simple To-Do List ===");
while (running) {
System.out.println("\nChoose an option:");
System.out.println("1. Add Task");
System.out.println("2. View Tasks");
System.out.println("3. Mark Task as Completed");
System.out.println("4. Delete Task");
System.out.println("5. Exit");
System.out.print("Enter your choice: ");
String choice = scanner.nextLine().trim();
switch (choice) {
case "1":
System.out.print("Enter task description: ");
String description = scanner.nextLine().trim();
if (!description.isEmpty()) {
todoList.addTask(description);
System.out.println("Task added.");
} else {
System.out.println("Task description cannot be empty.");
}
break;
case "2":
todoList.viewTasks();
break;
case "3":
todoList.viewTasks();
if (!todoList.tasks.isEmpty()) {
System.out.print("Enter task number to mark as completed: ");
if (scanner.hasNextInt()) {
int index = scanner.nextInt() - 1;
scanner.nextLine(); // Consume newline
todoList.markTaskCompleted(index);
} else {
System.out.println("Invalid input. Please enter a number.");
scanner.nextLine(); // Clear invalid input
}
}
break;
case "4":
todoList.viewTasks();
if (!todoList.tasks.isEmpty()) {
System.out.print("Enter task number to delete: ");
if (scanner.hasNextInt()) {
int index = scanner.nextInt() - 1;
scanner.nextLine(); // Consume newline
todoList.deleteTask(index);
} else {
System.out.println("Invalid input. Please enter a number.");
scanner.nextLine(); // Clear invalid input
}
}
break;
case "5":
todoList.saveTasks();
System.out.println("Goodbye!");
running = false;
break;
default:
System.out.println("Invalid choice. Please enter 1-5.");
}
}
scanner.close();
}
}

How It Works

1. Data Model

  • The Task class encapsulates a task’s description and completion status.
  • The toString() method provides a user-friendly display (e.g., [✓] Buy groceries).

2. Core Logic

  • TodoList manages a list of tasks and handles:
  • CRUD operations (add, view, mark complete, delete)
  • File I/O (save/load tasks in todo.txt)
  • Tasks are stored in a List<Task> for dynamic sizing.

3. File Format

  • Each line in todo.txt uses the format: 0|Task description
  • 0 = not completed, 1 = completed
  • Example file content:
  0|Buy milk
1|Finish report
0|Call dentist

4. User Interaction

  • Menu-driven console interface with clear prompts.
  • Input validation for task numbers and descriptions.
  • Graceful handling of empty lists and invalid inputs.

Sample Output

=== Simple To-Do List ===
Loaded 2 tasks from todo.txt
Choose an option:
1. Add Task
2. View Tasks
3. Mark Task as Completed
4. Delete Task
5. Exit
Enter your choice: 2
1. [ ] Buy milk
2. [✓] Finish report
Choose an option:
1. Add Task
2. View Tasks
3. Mark Task as Completed
4. Delete Task
5. Exit
Enter your choice: 1
Enter task description: Schedule meeting
Task added.
Choose an option:
1. Add Task
2. View Tasks
3. Mark Task as Completed
4. Delete Task
5. Exit
Enter your choice: 5
Tasks saved to todo.txt
Goodbye!

Key Concepts Demonstrated

ConceptImplementation
Object-Oriented DesignTask class with encapsulation
CollectionsArrayList<Task> for dynamic storage
File I/OSave/load tasks using BufferedReader/PrintWriter
User InputScanner with validation
Error HandlingTry-catch for I/O, input validation
CRUD OperationsAdd, view, update (complete), delete
Menu SystemLoop with switch-case

Possible Enhancements

  • Due dates: Add LocalDateTime field to Task
  • Categories/Tags: Group tasks by project or priority
  • Search functionality: Find tasks by keyword
  • GUI version: Use JavaFX or Swing
  • Database storage: Replace file I/O with SQLite or H2
  • Task priorities: High/medium/low with sorting
  • Undo functionality: Command pattern with history

Best Practices Applied

  • Single Responsibility: Each class has one clear purpose
  • Input validation: Prevents crashes from bad user input
  • Resource management: Scanner and file streams properly closed
  • Meaningful names: Clear variable and method names
  • Persistence: Data survives application restarts
  • User feedback: Clear success/error messages

Conclusion

This Simple To-Do List project provides a solid foundation for learning Java fundamentals while building a functional application. It demonstrates how to structure code using OOP principles, manage data with collections, persist state with file I/O, and create an interactive user experience. The modular design makes it easy to extend with new features, and the error handling ensures robustness. Whether used as a learning exercise or a starting point for a more advanced task manager, this project reinforces core Java skills that are applicable to real-world development.

Leave a Reply

Your email address will not be published. Required fields are marked *


Macro Nepal Helper