Lesson 16 - Diary with a database in Java (finishing)
In the previous lesson, Diary with a database in Java, we programmed a part of a digital diary using ArrayList. In today's tutorial of our Java course, we're going to finish it.
We'll need methods which prompt the user to enter a date or a date and time and return the LocalDate, resp. LocalDateTime instance set to the entered value. The only problem here is validating the user's input (date formats depend on your OS regional settings).
As first, we'll add 2 public static fields. These will be date and time formatters. We make them static to make them available also for another classes in our application. Every class can use those fields and we have them all at one place.
public static DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("M/d/y HH:mm"); public static DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M/d/y");
The first formatter contains both date and time, the second one contains only a date. Let's move to the Entry.java class and modify the toString() method like this:
@Override public String toString() { return dateTime.format(Diary.dateTimeFormatter) + " " + text; }
If we created a formatter instance every time in every Entry, it would be impractical. Using static fields, we got them all at one place and if we ever decided to change the format, we do it only in the Diary class. However, be careful with static members, it's usualy not a good idea to use them.
Let's return to the Diary class and add 2 methods for retrieving date and time:
private LocalDateTime readDateTime() { System.out.println("Enter date and time as mm/dd/yyyy hh:mm"); LocalDateTime dateTime; try { dateTime = LocalDateTime.parse(scanner.nextLine(), dateTimeFormatter); } catch (DateTimeParseException e) { System.out.println("Error. Please try again."); return readDateTime(); } return dateTime; } private LocalDate readDate() { System.out.println("Enter date as mm/dd/yyyy"); LocalDate date; try { date = LocalDate.parse(scanner.nextLine(), dateFormatter); } catch (DateTimeParseException e) { System.out.println("Error. Please try again."); return readDate(); } return date; }
The methods return a LocalDateTime, resp. LocalDate instance. As first, we prepare the default value. Then, we try to parse a date and time entered by the user in a try block. We'll explain exceptions (try-catch blocks) later in the course about files. The only important thing now is that if any error occurs due parsing the value, the program falls into the catch block. It prints an error message and calls the method again. Calling the same method we're into is called recursions. It's quite common programmer technique. You might want to keep these methods, they can be useful for entering date and time in your other console applications.
Let's add a printEntries() method that will find entries for the given day and print them:
public void printEntries(LocalDate day) { ArrayList<Entry> entries = database.findEntries(day.atStartOfDay(), false); for (Entry entry : entries) { System.out.println(entry); } }
We will also need a method for prompting the user to enter a new entry and adding it to the database:
public void addEntry() { LocalDateTime dateTime = readDateTime(); System.out.println("Enter the entry text:"); String text = scanner.nextLine(); database.addEntry(dateTime, text); }
Also, we still have to add methods for searching and deleting entries. The searching method will return an ArrayList of found entries (we will only search by date, time doesn't matter). We'll prompt the user to enter the date and pass it to the database. Then we'll display the result.
public void searchEntries() { // Entering the date LocalDateTime dateTime = readDate().atStartOfDay(); // Searching for entries ArrayList<Entry> entries = database.findEntries(dateTime, false); // Printing entries if (entries.size() > 0) { System.out.println("Entries found: "); for (Entry entry : entries) { System.out.println(entry); } } else { // Nothing found System.out.println("No entries were found."); } scanner.nextLine(); // wait for enter }
Deleting entries is trivial:
public void deleteEntries() { System.out.println("Entries with the same exact date and time will be deleted"); LocalDateTime dateTime = readDateTime(); database.deleteEntries(dateTime); }
Last of all, we'll add a method for printing a home screen, showing the current date and time and entries for today and tomorrow.
public void printHomeScreen() { System.out.println(); System.out.println(); System.out.println("Welcome to your virtual diary!"); System.out.println("Today is: " + LocalDateTime.now().format(dateTimeFormatter)); System.out.println(); // printing the home screen System.out.println("Today:\n------"); printEntries(LocalDate.now()); System.out.println(); System.out.println("Tomorrow:\n---------"); printEntries(LocalDate.now().plusDays(1)); System.out.println(); }
Now we can proudly move to Journal.java and create an instance of the diary, knowing that everything will work as expected. We will add the main loop here including a response to the user's choice:
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // diary instance Diary diary = new Diary(); String choice = "0"; // main loop while (!choice.equals("4")) { diary.printHomeScreen(); System.out.println(); System.out.println("Choose an action:"); System.out.println("1 - Add an entry"); System.out.println("2 - Search for entries"); System.out.println("3 - Delete entries"); System.out.println("4 - End"); choice = scanner.nextLine(); System.out.println(); // reaction to the choice switch (choice) { case "1": diary.addEntry(); break; case "2": diary.searchEntries(); break; case "3": diary.deleteEntries(); break; case "4": System.out.println("Press any key to quit the program..."); break; default: System.out.println("Error. Press any key to choose another action."); break; } } }
The code above isn't complicated at this point since we've already made similar applications in previous lessons. I gave the finalized app to my girlfriend as a present, here's what it looks like
Console application
Welcome to diary!
Today is: 5/12/2016 11:34:55
Today:
-----
5/12/2016 10:00:00 Shopping - Pankrac Arcade
5/12/2016 7:30:00 PM - Pet my Yorkshire Terrier Fred
Tomorrow:
--------
5/13/2016 2:00:00 PM Go jogging
Choose an action:
1 - Add an entry
2 - Search for entries
3 - Delete entries
4 - End
2
Enter date and time as e.g. [1/13/2016 10:00]
5/15/2016
Found entries:
5/15/2016 9:30:00 Economy exam
Now you know how to use ArrayList and rest assured that it will suffice as data storage container for a quite a long time. In conclusion, I'd like to congratulate you in now being able to create in-memory databases. Use it for anything you want! You could, for example, use it on the User class from the Getters/setters lesson or pretty much anything else. You can store articles, tasks, elephants, anything you want to manage in the database. What's up next, you may ask? Next time, in Interfaces in Java, we'll be talking about interfaces. There's still a lot to learn about OOP
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 134x (23.53 kB)
Application includes source codes in language Java