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.