public class Ingredient {
String name; // this is the name of the ingredient (ex. "milk")
Double amount; // this is the quantity of the ingredient (ex. 1.5)
String unit; // this is the unit in which the quantity is measured (ex. cups)
}
import java.awt.*;
import java.util.ArrayList;
public class Recipe {
String name; // this is the recipe name (ex. Chicken Parm)
ArrayList ingredients = new ArrayList(); // this is an arraylist of all the ingredients in the recipe, each with a name, quantity, and unit
Boolean vegetarian; // this boolean is set to true if the recipe is vegetarian and false if it is not
Boolean vegan; // this boolean is set to true if the recipe is vegan and false if it is not
Boolean glutenFree; // this boolean is set to true if the recipe is gluten-free and false if it is not
Boolean dairyFree; // this boolean is set to true if the recipe is dairy-free and false if it is not
Double healthScore; // each recipe is assigned a score based on how healthy it is
Double costEstimate; // this double is set to the estimated cost for a serving of the recipe (ex. 4.29)
long cookTime; // this is the time that the recipe should take in minutes (ex. 25)
long servings; // this is the number of servings that the recipe makes (ex. 8)
String sourceUrl; // this is the url where the recipe can be found
String summary; // this is a summary that the recipe provides
String instructions; // this is the actual recipe that the recipe provides
Image image; // this is an image of the food that the recipe is making
Rectangle rectangle; // this is the rectangle where the recipe content will be displayed
Rectangle expandButton; // this is where the button to expand the recipe will be placed
}
import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.imageio.ImageIO;
public class RecipeAPI {
static String apiKey = "70da24967b894794b336c07bbc2ab970"; //this is the API key that spoonacular provides
// this function loads the data attatched to the inputted recipeID into the recipe class
public static Recipe getRecipeData(long recipeID) throws IOException, ParseException {
// creates url for the specific recipe and connects to it
URL url = new URL("https://api.spoonacular.com/recipes/"+recipeID+"/information?includeNutrition=false&ranking=2&apiKey="+apiKey);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
// makes sure nothing is wrong, if spoonacular returns an error then it prints out information about the error
if (conn.getResponseCode() == 404) {
return null;
} else if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
// reads the json into a string
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
String totalJson="";
while ((output = br.readLine()) != null) {
totalJson += output;
}
conn.disconnect();
// parses the string created into a JSON object
JSONParser parser = new JSONParser();
org.json.simple.JSONObject recipeJson = (org.json.simple.JSONObject) parser.parse(totalJson);
// creates a new Recipe to load the data into
Recipe thisRecipe = new Recipe();
// parses the JSON object for each field
thisRecipe.name = (String)recipeJson.get("title");
thisRecipe.vegetarian = (Boolean)recipeJson.get("vegetarian");
thisRecipe.vegan = (Boolean)recipeJson.get("vegan");
thisRecipe.glutenFree = (Boolean)recipeJson.get("glutenFree");
thisRecipe.dairyFree = (Boolean)recipeJson.get("dairyFree");
thisRecipe.healthScore = (Double) recipeJson.get("healthScore");
thisRecipe.costEstimate = ((Double) (recipeJson.get("pricePerServing")))/100;
thisRecipe.cookTime = (long) recipeJson.get("readyInMinutes");
thisRecipe.servings = (long) recipeJson.get("servings");
thisRecipe.sourceUrl = (String) recipeJson.get("sourceUrl");
thisRecipe.summary = (String) recipeJson.get("summary");
thisRecipe.instructions = (String) recipeJson.get("instructions");
if(recipeJson.get("image")!=null) {
thisRecipe.image = ImageIO.read(new URL((String) recipeJson.get("image")));
}
// loads the list of ingredients into an arraylist of ingredients
org.json.simple.JSONArray ingredientsJson = (org.json.simple.JSONArray) recipeJson.get("extendedIngredients");
ArrayList thisRecipesIngredients = new ArrayList();
for (Object o : ingredientsJson) {
org.json.simple.JSONObject thisIngredientJson = (org.json.simple.JSONObject) o;
Ingredient thisIngredient = new Ingredient();
thisIngredient.name = (String)thisIngredientJson.get("name");
thisIngredient.amount = (Double)thisIngredientJson.get("amount");
thisIngredient.unit = (String)thisIngredientJson.get("unit");
thisRecipesIngredients.add(thisIngredient);
}
thisRecipe.ingredients = thisRecipesIngredients;
// returns the recipe with all of the information
return thisRecipe;
}
// this function returns an arraylist of recipes for any inputted list of ingredients
public static ArrayList searchForRecipes(ArrayList ingredients,int numberOfResults) throws IOException, ParseException {
// creates an empty arraylist
ArrayList recipes = new ArrayList();
// converts the inputted arraylist of ingredients into a string
StringBuilder ingredientString= new StringBuilder();
for(Object o:ingredients){
String toAddString = o +",+";
ingredientString.append(toAddString);
}
ingredientString = new StringBuilder(ingredientString.substring(0, ingredientString.length() - 2));
// generates the URL for the list of recipes with these ingredients and connects to it
URL url = new URL("https://api.spoonacular.com/recipes/findByIngredients?ingredients="+ingredientString+"&number="+numberOfResults+"&apiKey="+apiKey);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
// makes sure nothing is wrong, if spoonacular returns an error then it prints out information about the error
if (conn.getResponseCode() == 404) {
return null;
} else if (conn.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ conn.getResponseCode());
}
// reads the json into a string
BufferedReader br = new BufferedReader(new InputStreamReader(
(conn.getInputStream())));
String output;
String totalJson="";
while ((output = br.readLine()) != null) {
totalJson += output;
}
conn.disconnect();
// parses the string created into a JSON array
JSONParser parser = new JSONParser();
org.json.simple.JSONArray allRecipesJson = (org.json.simple.JSONArray) parser.parse(totalJson);
// loops through the array of JSON objects
for(Object o:allRecipesJson){
org.json.simple.JSONObject thisRecipe = (org.json.simple.JSONObject) o;
// gets the id for each recipe that Spoonacular provides and uses the getRecipeData function to return a recipe
Recipe recipeToAdd = getRecipeData((long)thisRecipe.get("id"));
// adds this recipe to the arraylist of recipes
recipes.add(recipeToAdd);
}
// returns the arraylist of recipes
return recipes;
}
}
import org.json.simple.parser.ParseException;
import org.w3c.dom.css.Rect;
import java.awt.Graphics2D;
import java.awt.event.*;
import java.awt.image.BufferStrategy;
import java.awt.*;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Locale;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;
public class Main implements Runnable, KeyListener, MouseListener {
//graphics
//parameters for our app window
final int WIDTH = 1000;
final int HEIGHT = 746;
public JFrame frame;
public Canvas canvas;
public JPanel panel;
public BufferStrategy bufferStrategy;
public String result;
public int renderscreen = 1;
public Recipe renderRecipe;
Graphics2D g;
//this is where we set all our backround images for our different screens
public Image basebackround;
public Image recipieBackground;
public Image fullRecipieBackground;
//names all clickable buttons
public Rectangle inputbut;
public Rectangle Linkbut;
//makes all button images
public Image Inputimg;
public Image Searchimg;
public Image Linkicon;
ArrayList showRecipes = new ArrayList();
//different allergen icon images
public Image veganicon;
public Image vegicon;
public Image DFicon;
public Image GFicon;
public static void main(String[] args) {
Main ex = new Main();
new Thread(ex).start();
}
//this function allows for the input of a link which will then automatically be opened
//in your prefered browser
public static void LinkOpener(String inputlink){
try {
URI uri= new URI(inputlink);
java.awt.Desktop.getDesktop().browse(uri);
} catch (Exception e) {
e.printStackTrace();
}
}
public Main() {
//this is where all the Images are assigned their respective Images
System.out.println("this is the super test");
//backgrounds
basebackround = Toolkit.getDefaultToolkit().getImage("correctBackground.png" ); //load the picture
recipieBackground = Toolkit.getDefaultToolkit().getImage("Untitled_Artwork.png");
fullRecipieBackground = Toolkit.getDefaultToolkit().getImage("basebackround.png");
//buttons
Searchimg = Toolkit.getDefaultToolkit().getImage("");
Inputimg = Toolkit.getDefaultToolkit().getImage("inputbutimg.png");
Linkicon = Toolkit.getDefaultToolkit().getImage("LinkIMG.png");
//allergin icons
veganicon = Toolkit.getDefaultToolkit().getImage("VeganIMG.png");
vegicon = Toolkit.getDefaultToolkit().getImage("VegIMG.png");
DFicon = Toolkit.getDefaultToolkit().getImage("DFIMG.png");
GFicon = Toolkit.getDefaultToolkit().getImage("GFIMG.png");
setUpGraphics();
g = (Graphics2D) bufferStrategy.getDrawGraphics();
}
public void printrec() {
}
//this is what runs whe you first open the aplication
public void run() {
while (true) {
render();
pause(20);
}
}
//this is a brief brake that helps the app run smootly
public void pause(int time ){
try {
Thread.sleep(time);
} catch (InterruptedException e) {
}
}
//this is where we give the names all of the information they need to draw the correct picture
private void setUpGraphics() {
//we gvie the image information to all of the names we set up at the top
frame = new JFrame("Application Template");
panel = (JPanel) frame.getContentPane();
panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
panel.setLayout(null);
//we make click-able rectangles to the buttons that have actions
inputbut = new Rectangle (300,50,400,400);
Linkbut = new Rectangle (820,10,128,96);
canvas = new Canvas();
canvas.setBounds(0, 0, WIDTH, HEIGHT);
canvas.setIgnoreRepaint(true);
panel.add(canvas);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setResizable(true);
frame.setVisible(true);
canvas.createBufferStrategy(2);
bufferStrategy = canvas.getBufferStrategy();
canvas.requestFocus();
canvas.addKeyListener(this);
canvas.addMouseListener(this);
frame.addComponentListener(new ComponentAdapter()
{
public void componentResized(ComponentEvent evt) {
Component c = (Component)evt.getSource();
canvas.setBounds(0,0,frame.getWidth(),frame.getHeight());
}
});
System.out.println("DONE graphic setup");
}
///this is where we draw the information that we gave to the names based on which screen you're on
private void render() {
//screen 1
if(renderscreen==1){
g.clearRect(0,0,canvas.getWidth(),canvas.getHeight());
//background for the first screen
g.drawImage(basebackround,0,0,1000,746,null);
g.drawImage(Inputimg,300,50,400,400,null);
}
//screen 0
else if (renderscreen==0){
g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
g.drawImage(recipieBackground,0,0,1000,746,null);
for (int i = 0; i<showRecipes.size();i++) {
Recipe thisRecipe = (Recipe) showRecipes.get(i);
thisRecipe.rectangle = new Rectangle(100,70*i+40,950,70);
Font myFont = new Font("Serif", Font.BOLD, 15);
g.setFont(myFont);
g.drawString(thisRecipe.name,thisRecipe.rectangle.x,thisRecipe.rectangle.y);
myFont = new Font("Serif", Font.PLAIN, 12);
g.setFont(myFont);
String ingredientList = "Ingredients: ";
for(Object o:thisRecipe.ingredients){
ingredientList+=((Ingredient)o).name.toLowerCase();
ingredientList+=", ";
}
ingredientList = ingredientList.substring(0,ingredientList.length()-2);
if(ingredientList.length()>150){
ingredientList = ingredientList.substring(0, ingredientList.lastIndexOf(','));
}
g.drawString(ingredientList,thisRecipe.rectangle.x,thisRecipe.rectangle.y+40);
g.drawString("Health Score: "+thisRecipe.healthScore+" | Cost per Serving: $"+((double)(java.lang.Math.round(thisRecipe.costEstimate*100)))/100+" | Cooktime: "+thisRecipe.cookTime+ " minutes | Servings: "+ thisRecipe.servings,thisRecipe.rectangle.x,thisRecipe.rectangle.y+20);
thisRecipe.expandButton = new Rectangle(thisRecipe.rectangle.x-65,thisRecipe.rectangle.y-10,50,50);
thisRecipe.expandButton2 = new Rectangle(thisRecipe.rectangle.x,thisRecipe.rectangle.y-10,600,70);
if(thisRecipe.vegan==true){
g.drawImage(veganicon,thisRecipe.expandButton.x-10,thisRecipe.expandButton.y-10,50,50,null);
}
if(thisRecipe.vegetarian==true&thisRecipe.vegan==false){
g.drawImage(vegicon,thisRecipe.expandButton.x-10,thisRecipe.expandButton.y-10,50,50,null);
}
if(thisRecipe.dairyFree==true&thisRecipe.vegan==false){
g.drawImage(DFicon,thisRecipe.expandButton.x+20,thisRecipe.expandButton.y-10,40,40,null);
}
if(thisRecipe.glutenFree==true){
g.drawImage(GFicon,thisRecipe.expandButton.x,thisRecipe.expandButton.y+20,40,40,null);
}
}
}
//screen 2
else if(renderscreen ==2){
g.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
g.drawImage(fullRecipieBackground,0,0,1000,746,null);
Font myFont = new Font("Serif", Font.BOLD, 20);
g.setFont(myFont);
g.drawString(renderRecipe.name,50,50);
g.drawImage(renderRecipe.image,50,75,renderRecipe.image.getWidth(null)/2,renderRecipe.image.getHeight(null)/2,null);
myFont = new Font("Serif", Font.PLAIN, 15);
g.setFont(myFont);
for(int i=0;i<renderRecipe.ingredients.size();i++){
Ingredient thisIngredient = (Ingredient) renderRecipe.ingredients.get(i);
g.drawString(thisIngredient.amount +" "+thisIngredient.unit+" "+thisIngredient.name,50,291+20*i);
}
myFont = new Font("Serif", Font.PLAIN, 17);
g.setFont(myFont);
g.drawString("Health Score: "+renderRecipe.healthScore+" | Cost per Serving: $"+((double)(java.lang.Math.round(renderRecipe.costEstimate*100)))/100+" | Cooktime: "+renderRecipe.cookTime+ " minutes | Servings: "+ renderRecipe.servings,200,700);
myFont = new Font("Serif", Font.BOLD, 17);
g.setFont(myFont);
//g.drawString(renderRecipe.sourceUrl,250,125);
g.drawImage(Linkicon,820,10,128,96,null);
String instructions = renderRecipe.instructions;
myFont = new Font("Serif", Font.PLAIN, 16);
g.setFont(myFont);
int cursorYpos = 150;
while(instructions.contains("<")) {
String setToInstructions = instructions.substring(0, instructions.indexOf('<'));
setToInstructions+= " "+instructions.substring(instructions.indexOf('>')+1);
instructions = setToInstructions;
}
while (instructions.length() > 0) {
if (instructions.length() > 70) {
String instructionsTooLong = instructions.substring(70);
instructions = instructions.substring(0, 70);
g.drawString(instructions.substring(0, instructions.lastIndexOf(' ')), 400, cursorYpos);
cursorYpos += 18;
instructions = instructions.substring(instructions.lastIndexOf(' ')) + instructionsTooLong;
} else {
g.drawString(instructions, 400, cursorYpos);
instructions = "";
}
}
//
}
bufferStrategy.show();
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
char key = e.getKeyChar();
int keyCode = e.getKeyCode();
System.out.println("Key Pressed: " + key + " Code: " + keyCode);
//
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
if (renderscreen == 0){
for (Object o : showRecipes) {
Recipe thisRecipe = (Recipe) o;
if (thisRecipe.expandButton2.contains(e.getPoint())) {
renderscreen = 2;
renderRecipe = thisRecipe;
}
}
Rectangle backButton = new Rectangle(900,0,100,100);
if(backButton.contains(e.getPoint())){
renderscreen = 1;
}
}
if(renderscreen == 1){
if(inputbut.contains(e.getPoint())){
result = (String)JOptionPane.showInputDialog(
frame,
"Input a Comma-Seperated List of Ingredients",
"Ingredients",
JOptionPane.PLAIN_MESSAGE,
null,
null,
"apples, lettuce, pasta, chicken"
);
//easter egg
if(result.equals("rick")){
LinkOpener("https://www.youtube.com/watch?v=dQw4w9WgXcQ");
//hey i need to have some fun if im staying up until 3
}
if(result != null && result.length() > 0){
System.out.println("your ingredients are:" + result);
ArrayList ingredientInput = new ArrayList();
while(result.indexOf(',')>0){
String thisIngredient = result.substring(0,result.indexOf(','));
result = result.substring(result.indexOf(',')+1);
ingredientInput.add(thisIngredient.trim());
}
ingredientInput.add(result.trim());
try {
showRecipes = RecipeAPI.searchForRecipes(ingredientInput,10);
} catch (IOException ex) {
ex.printStackTrace();
} catch (ParseException ex) {
ex.printStackTrace();
}
}else {
System.out.println("None selected");
}
renderscreen = 0;
}
}
if(renderscreen == 2){
if(Linkbut.contains(e.getPoint())){
LinkOpener(renderRecipe.sourceUrl);
}
Rectangle backButton = new Rectangle(10,600,100,100);
if(backButton.contains(e.getPoint())){
renderscreen = 0;
}
}
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}