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
Taskclass encapsulates a task’s description and completion status. - The
toString()method provides a user-friendly display (e.g.,[✓] Buy groceries).
2. Core Logic
TodoListmanages 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.txtuses 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
| Concept | Implementation |
|---|---|
| Object-Oriented Design | Task class with encapsulation |
| Collections | ArrayList<Task> for dynamic storage |
| File I/O | Save/load tasks using BufferedReader/PrintWriter |
| User Input | Scanner with validation |
| Error Handling | Try-catch for I/O, input validation |
| CRUD Operations | Add, view, update (complete), delete |
| Menu System | Loop with switch-case |
Possible Enhancements
- Due dates: Add
LocalDateTimefield toTask - 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:
Scannerand 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.