Get up to 80 % extra points for free! More info:

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 133x (23.53 kB)
Application includes source codes in language Java

 

Previous article
Diary with a database in Java
All articles in this section
Object-Oriented Programming in Java
Skip article
(not recommended)
Interfaces in Java
Article has been written for you by David Capka Hartinger
Avatar
User rating:
No one has rated this quite yet, be the first one!
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities