In this project, you will build something like Instagram...except that it will be 1000 times more fun and cool because you made it, so we've appropriately named Instakilo! In the process you will make use of three major concepts: Interactors, HashMaps and ArrayLists.

The inital state of the app greets users with the friendly message: "Welcome to Instakilo!"" and loads profile data from a text file into the app. At this point and any point, the user has 3 core actions she/he can take:

  1. browse a profile with a given name
  2. post pictures on the current profile
  3. create a new profile associated with a given name

Bellow is an example of the app running. It is showing the profile for the user "Chris Piech" and associated photos.

When the program is closed and opened again, previously created profiles, and posted photos should still exist (Whenever a profile is created or picture is posted to a profile, a data file is updated to reflect the current state of all profiles). Each profile consists of a unique name and a list of file names of images that have been posted to that profile.

Milestone 1: Welcome

As a warm-up to displaying a profile with images, you should first implement a method displayMessage that takes a string as a parameter and displays it to the user in the center of the screen. This method will be useful for displaying the welcome message on application start, as well as later when you respond to user input via the interactors. The message should be centered and be given the font MESSAGE_FONT defined in IKConstants. In other words, the method should look something like the following:

private void displayMessage(String message) {
   removeAll(); // clear the screen
   // create text graphics object with the given message
   // set the font and location of the graphics object
   // display the message!
}

As a reminder you can use getWidth() to get the width of the applicaiton window. Now call this method to display "Welcome to Instakilo!" when the application starts.

Milestone 2: Interactors

The next part of this assignment is to add the necessary interactors. Create the panel shown bellow with the appropriate combination of JLabel, JButton, and JTextField objects. Don't forget to call addActionListeners()



Next we want to make sure that we can respond to button clicks. To test that your iteractors are connected correctly display a message, using the displayMessage method you wrote in the first milestone when a user clicks a button. For now show this message when someone hits the "display" button:

"display profile: profileName"
For example if we type in Bob Marley and hit display message your program should show the following screen:

Similarly, show this message when someone hits the create button,
"create profile: profileName"
And show this message when someone hits the post button
"post profile: profileName"

Later we will replace showing a message with the actual funcitonality!

Milestone 3: Database

Now that we have our interactors set up, our next step is to create the appropriate datastructure to store all profiles. For this project, you should use a HashMap<String, ArrayList<String>> to map from profile names to the list of file names for the photos associated with each profile.

Create the HashMap when the program starts and for now lets put some prefabricated data into it. Make a profile with the name "Bob Marley" who has four image file names (they should be strings): ["bob.jpg", "bobFamily.jpg" "bobYoung.jpg" and "bobSinging.jpg"]

Bob Marley was one of the most successful singers around the world... so it seems appropriate that he would have a profile on Instakilo

Milestone 4: Display Profile

It's now time to start showing profiles. If a profile exists in our HashMap with the name entered in the profile text field, then Instakilo should display that profile name and images associated with it; otherwise, you should display the message "No profile exists with that name".

At the moment our HashMap only contains one profile Bob Marley. When we display Bob Marley's profile it should look like this (we no longer show the message "display profile: Bob Marley"):

Images from filenames

If you have a filename, it is very simple to create the corresponding GImage (A GImage is like a GRect, except that instead of displaying a rectangle it displays an image)

GImage myImage = new GImage(fileName);

Scaling images

The images you display should all be of the height ROW_HEIGHT, but when you load them from file, they could be any size! In order to make them the right size you are going to have to use the GImage scale method.

image.scale(fraction);
For example if you wrote image.scale(0.5) it would make both the width and the heigh of your image half the size. You can get the height of your image using image.getHeight(); How much should you scale your image by so that it is ROW_HEIGHT?

Layout

Add images one by one starting from the top left. Add images to the current row until you reach the point where adding a new image would extend the image past the right side of the screen. When an image would extend past the right side of the screen, change to placing images on the next row.

There is a margin that is size MARGIN pixels between everything.

Milestone 4: Create a Profile

when the user clicks "Create", you should first check if a profile already exists with that name. If a profile exists, then display a message to the user ("A profile already exists for that name"). Otherwise, you want to create a new entry in your data hashmap to store this new profile and display it for the user.

For example if you type in Julia Lee in the profileName field and hit the Create button you should end up displaying the new, empty profile for Julia.

Milestone 5: Post Photo

To post a new photo on the current profile, the user will enter an image name in the lower text area (labeled "New photo name:"") and click "Post". 1) If no profile is currently displayed, then display the message "Please select a profile before posting a picture" 2) If a profile is displayed, first check that an image exists with the given name using the provided method FileSystem.imageFileExists. If true, add the photo name to the ArrayList of photos associated with that profile, redisplay the current profile.

If we post the photo julia1.jpg to Julia's profile, it should get displayed!

Instakilo finds images from the img folder in the Instakilo project. We put a lot of photos there for you to play with. Add your own photos to the img folder so you can create a profile for yourself!

Milestone 6: Load and Save

You can save your HashMap to file using the method:

FileSystem.saveMap(myMap, fileName);
And you can load a hash map from file using the method:
HashMap<String, <ArrayList<String>> myMap = FileSystem.loadMap(fileName);
If no hashMap exists with the given fileName, loadMap will return null.

Your final milestone is to make changes to your instakilo hashMap persist between runs. Any time you change your hashMap save it to file! When you start the program, load the hashMap from file.

Thats it! You are done with Instakilo.

Extensions

One feature that made Instagram so popular was that users could apply filters to their photos. Create a feature where a user can click on an image (which will select it) and then hit a button to make the image black and white. Ask the staff for more instructions if you are interested!