Day 4 - NoteKeeper | #30Days30Projects


Introduction
What if I told you that you can build your own personal note-taking app, and all you need is Java and your terminal?
On Day 4 of #30DaysOfCode, I created NoteKeeperCLI
, a lightweight CLI-based notes manager using Java. No databases. No external libraries. Just pure Java, files, and your thoughts — stored neatly in a .txt
file.
Whether it’s raining outside or you’re sipping coffee inside, this app lets you jot down ideas with timestamps, edit them later, or clean up by deleting them. The best part? You’ll learn some core Java concepts in a hands-on and useful way.
Why This Project?
We all take notes — some on sticky pads, some on our phones. But building a command-line notes keeper helps you:
Understand Java File I/O
Work with
ArrayList
and string formattingHandle user inputs and terminal menus
Create a real-world utility with no external tools
What You’ll Learn
By the end of this blog, you’ll have learned:
How to read and write to files in Java
How to format timestamps for logging
How to build interactive menus in the terminal
How to store, edit, and delete data in-memory and persist it
How to organize code using static methods and utilities
Let’s dive in.
Project Features
Here’s what NoteKeeperCLI
can do:
Add a new note with a timestamp
View all saved notes
Edit any existing note
Delete a note
Automatically save to a file (
notes.txt
) on exit
Folder Structure
NoteKeeperCLI/
└── src/
└── NoteKeeper.java
└── notes.txt (auto-created)
Complete Code – NoteKeeper.java
import java.io.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
public class NoteKeeper {
private static final String FILE_NAME = "notes.txt";
private static ArrayList<String> notes = new ArrayList<>();
private static Scanner scanner = new Scanner(System.in);
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
public static void main(String[] args) {
loadNotes();
while (true) {
System.out.println("\n=== NoteKeeperCLI ===");
System.out.println("1. Create Note");
System.out.println("2. View Notes");
System.out.println("3. Edit Note");
System.out.println("4. Delete Note");
System.out.println("5. Exit");
System.out.print("Choose an option: ");
String input = scanner.nextLine();
switch (input) {
case "1" -> createNote();
case "2" -> viewNotes();
case "3" -> editNote();
case "4" -> deleteNote();
case "5" -> {
saveNotes();
System.out.println("Notes saved. Goodbye!");
return;
}
default -> System.out.println("Invalid option. Try again.");
}
}
}
private static void loadNotes() {
try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
String line;
while ((line = reader.readLine()) != null) {
notes.add(line);
}
} catch (IOException e) {
System.out.println("No previous notes found. Starting fresh.");
}
}
private static void saveNotes() {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_NAME))) {
for (String note : notes) {
writer.write(note);
writer.newLine();
}
} catch (IOException e) {
System.out.println("Error saving notes.");
}
}
private static void createNote() {
System.out.print("Enter your note: ");
String content = scanner.nextLine();
String timestamp = "[" + LocalDateTime.now().format(formatter) + "]";
notes.add(timestamp + " " + content);
System.out.println("Note added successfully!");
}
private static void viewNotes() {
if (notes.isEmpty()) {
System.out.println("No notes available.");
return;
}
System.out.println("\n--- All Notes ---");
for (int i = 0; i < notes.size(); i++) {
System.out.println((i + 1) + ". " + notes.get(i));
}
}
private static void editNote() {
if (notes.isEmpty()) {
System.out.println("No notes to edit.");
return;
}
viewNotes();
System.out.print("Enter note number to edit: ");
int index = Integer.parseInt(scanner.nextLine()) - 1;
if (index < 0 || index >= notes.size()) {
System.out.println("Invalid note number.");
return;
}
System.out.print("Enter new content: ");
String newContent = scanner.nextLine();
String newTimestamp = "[" + LocalDateTime.now().format(formatter) + "]";
notes.set(index, newTimestamp + " " + newContent);
System.out.println("Note updated.");
}
private static void deleteNote() {
if (notes.isEmpty()) {
System.out.println("No notes to delete.");
return;
}
viewNotes();
System.out.print("Enter note number to delete: ");
int index = Integer.parseInt(scanner.nextLine()) - 1;
if (index < 0 || index >= notes.size()) {
System.out.println("Invalid note number.");
return;
}
notes.remove(index);
System.out.println("Note deleted.");
}
}
🖥️ Sample Output
Launch Menu:
=== NoteKeeperCLI ===
1. Create Note
2. View Notes
3. Edit Note
4. Delete Note
5. Exit
Choose an option:
Adding a Note:
Enter your note: Weather is calming. Raining outside.
Note added successfully!
Viewing Notes:
--- All Notes ---
1. [2025-07-25 18:35] Weather is calming. Raining outside.
Editing a Note:
Enter note number to edit: 1
Enter new content: It's still raining, feels peaceful.
Note updated.
Deleting a Note:
Enter note number to delete: 1
Note deleted.
🧠 Concepts Explained
1. File I/O in Java
We use BufferedReader
and BufferedWriter
to read and write text efficiently to notes.txt
.
2. ArrayList
All notes are stored in an ArrayList<String>
, which makes it easy to add, edit, or delete dynamically.
3. Timestamps
The LocalDateTime
and DateTimeFormatter
APIs help generate timestamps like:
[2025-07-25 18:35]
4. Terminal Menu
The menu uses a simple loop and switch-case
to handle user choices.
🚀 Improvements You Can Try
Add color to terminal output (using external libraries like Jansi)
Categorize notes by tags or labels
Search for notes using keywords
Export notes in
.json
or.csv
formatBuild a GUI version with JavaFX or Swing
Final Thoughts
NoteKeeperCLI
was a joy to build. It’s a reminder that you don’t need complex tools to build something useful. Java, your logic, and a text editor are enough.
This project made me appreciate how powerful even a small CLI app can be. It also helped reinforce important concepts like file handling, lists, and user interaction — which are essential for any Java developer.
Stay tuned for Day 5, where I’ll build something new, exciting, and practical again.
Subscribe to my newsletter
Read articles from Rushikesh Unge directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
