Code Sketch
graphic_7325* food app
Category: Art
import javax.swing._
import javax.swing.border.EmptyBorder
import java.awt.{BorderLayout, Color, Dimension, Font, GridLayout, FlowLayout}
import java.awt.event.{ActionEvent, ActionListener}
import java.security.MessageDigest
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
// ================================================
// FOODIE RESTAURANT APP - KOJO 5 SCALA
// ================================================
val APP_NAME = "Foodie Restaurant"
val BG = new Color(250, 247, 240)
val GREEN = new Color(35, 125, 85)
val DARK = new Color(35, 45, 40)
val ORANGE = new Color(245, 145, 50)
val RED = new Color(210, 45, 45)
val WHITE = Color.WHITE
val PASSWORD_HASH =
"4737dbee8e213809434819134b80af8c7e2b726acef3aa70808233ae41dd82f6"
def sha256(value: String): String = {
val md = MessageDigest.getInstance("SHA-256")
md.digest(value.getBytes("UTF-8"))
.map(b => "%02x".format(b & 0xff))
.mkString
}
def makeButton(text: String): JButton = {
val b = new JButton(text)
b.setFont(new Font("SansSerif", Font.BOLD, 14))
b.setFocusPainted(false)
b.setBackground(GREEN)
b.setForeground(WHITE)
b.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR))
b
}
def makeLabel(text: String, size: Int): JLabel = {
val l = new JLabel(text)
l.setFont(new Font("SansSerif", Font.BOLD, size))
l.setForeground(DARK)
l
}
// Food database
case class Food(
name: String,
category: String,
price: Int,
emoji: String
)
val foods = Vector(
Food("Veg Pizza", "Pizza", 180, "?"),
Food("Paneer Pizza", "Pizza", 230, "?"),
Food("Cheese Burger", "Burger", 120, "?"),
Food("Veg Burger", "Burger", 90, "?"),
Food("Vada Pav", "Indian", 25, "?"),
Food("Misal Pav", "Indian", 80, "?"),
Food("Masala Dosa", "South Indian", 100, "?"),
Food("Idli Sambar", "South Indian", 70, "?"),
Food("Veg Biryani", "Rice", 150, "?"),
Food("Paneer Biryani", "Rice", 190, "?"),
Food("Hakka Noodles", "Chinese", 130, "?"),
Food("Manchurian", "Chinese", 140, "?"),
Food("French Fries", "Snacks", 80, "?"),
Food("Sandwich", "Snacks", 75, "?"),
Food("Chocolate Cake", "Dessert", 100, "?"),
Food("Ice Cream", "Dessert", 60, "?"),
Food("Cold Coffee", "Drinks", 90, "?"),
Food("Mango Juice", "Drinks", 60, "?")
)
val cart = mutable.LinkedHashMap[String, Int]()
val orderHistory = ArrayBuffer[String]()
val reviews = ArrayBuffer[String]()
var orderNumber = 1000
var currentStatus = "No active order"
var lastOrder = "No order yet"
// ================================================
// DASHBOARD AND NAVIGATION
// ================================================
def openDashboard(username: String): Unit = {
val frame = new JFrame("Foodie Restaurant App")
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
frame.setSize(950, 680)
frame.setMinimumSize(new Dimension(760, 560))
frame.setLocationRelativeTo(null)
val root = new JPanel(new BorderLayout(8, 8))
root.setBackground(BG)
val header = new JPanel(new BorderLayout())
header.setBackground(GREEN)
header.setBorder(new EmptyBorder(14, 18, 14, 18))
val logo = new JLabel("? FOODIE RESTAURANT")
logo.setForeground(WHITE)
logo.setFont(new Font("SansSerif", Font.BOLD, 24))
// User Profile & Logout Panel
val userPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0))
userPanel.setOpaque(false)
val welcome = new JLabel("Hello, " + username)
welcome.setForeground(WHITE)
welcome.setFont(new Font("SansSerif", Font.BOLD, 15))
val logoutButton = new JButton("LOGOUT")
logoutButton.setFont(new Font("SansSerif", Font.BOLD, 12))
logoutButton.setBackground(RED)
logoutButton.setForeground(WHITE)
logoutButton.setFocusPainted(false)
logoutButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR))
userPanel.add(welcome)
userPanel.add(logoutButton)
header.add(logo, BorderLayout.WEST)
header.add(userPanel, BorderLayout.EAST)
val tabs = new JTabbedPane()
tabs.setFont(new Font("SansSerif", Font.BOLD, 13))
// --- 1. Menu Tab UI ---
val menuPanel = new JPanel(new BorderLayout(8, 8))
menuPanel.setBackground(BG)
menuPanel.setBorder(new EmptyBorder(12, 12, 12, 12))
val searchField = new JTextField()
searchField.setFont(new Font("SansSerif", Font.PLAIN, 15))
val categories = new JComboBox[String](Array(
"All", "Pizza", "Burger", "Indian", "South Indian",
"Rice", "Chinese", "Snacks", "Dessert", "Drinks"
))
val searchRow = new JPanel(new GridLayout(1, 2, 8, 8))
searchRow.add(searchField)
searchRow.add(categories)
val menuModel = new DefaultListModel[String]()
val menuList = new JList[String](menuModel)
menuList.setFont(new Font("SansSerif", Font.PLAIN, 16))
menuList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION)
val menuScroll = new JScrollPane(menuList)
val addButton = makeButton("ADD TO CART")
val menuInfo = makeLabel("Select dish and click ADD TO CART.", 13)
val menuBottom = new JPanel(new FlowLayout(FlowLayout.LEFT))
menuBottom.setBackground(BG)
menuBottom.add(addButton)
menuBottom.add(menuInfo)
menuPanel.add(searchRow, BorderLayout.NORTH)
menuPanel.add(menuScroll, BorderLayout.CENTER)
menuPanel.add(menuBottom, BorderLayout.SOUTH)
// --- 2. Cart Tab UI ---
val cartPanel = new JPanel(new BorderLayout(8, 8))
cartPanel.setBackground(BG)
cartPanel.setBorder(new EmptyBorder(15, 15, 15, 15))
val cartArea = new JTextArea()
cartArea.setEditable(false)
cartArea.setFont(new Font("Monospaced", Font.PLAIN, 15))
cartArea.setBackground(WHITE)
val cartButtons = new JPanel(new FlowLayout(FlowLayout.LEFT))
cartButtons.setBackground(BG)
val removeButton = makeButton("REMOVE SELECTED")
val clearButton = makeButton("CLEAR CART")
val checkoutButton = makeButton("PLACE ORDER")
cartButtons.add(removeButton)
cartButtons.add(clearButton)
cartButtons.add(checkoutButton)
cartPanel.add(new JScrollPane(cartArea), BorderLayout.CENTER)
cartPanel.add(cartButtons, BorderLayout.SOUTH)
// --- 3. Order Tracking Tab UI (Real Live Tracking) ---
val trackingPanel = new JPanel(new BorderLayout(15, 15))
trackingPanel.setBackground(BG)
trackingPanel.setBorder(new EmptyBorder(30, 30, 30, 30))
val trackingTitle = makeLabel("LIVE ORDER TRACKING", 24)
val trackingCenter = new JPanel(new GridLayout(4, 1, 10, 10))
trackingCenter.setBackground(BG)
val orderIdLabel = makeLabel("Order ID: No active order", 18)
val trackingLabel = makeLabel("Status: No active order", 20)
val timerLabel = makeLabel("Estimated Delivery Time: --:--", 18)
timerLabel.setForeground(ORANGE)
val progressBar = new JProgressBar(0, 120)
progressBar.setValue(0)
progressBar.setStringPainted(true)
progressBar.setFont(new Font("SansSerif", Font.BOLD, 14))
trackingCenter.add(orderIdLabel)
trackingCenter.add(trackingLabel)
trackingCenter.add(timerLabel)
trackingCenter.add(progressBar)
trackingPanel.add(trackingTitle, BorderLayout.NORTH)
trackingPanel.add(trackingCenter, BorderLayout.CENTER)
// Timer Variables
var remainingSeconds = 120
var deliveryTimer: javax.swing.Timer = null
// --- 4. History Tab UI ---
val historyPanel = new JPanel(new BorderLayout(8, 8))
historyPanel.setBackground(BG)
historyPanel.setBorder(new EmptyBorder(15, 15, 15, 15))
val historyArea = new JTextArea()
historyArea.setEditable(false)
historyArea.setFont(new Font("Monospaced", Font.PLAIN, 14))
val historyRefreshButton = makeButton("REFRESH HISTORY")
historyPanel.add(new JScrollPane(historyArea), BorderLayout.CENTER)
historyPanel.add(historyRefreshButton, BorderLayout.SOUTH)
// --- 5. Reviews Tab UI ---
val reviewPanel = new JPanel(new BorderLayout(8, 8))
reviewPanel.setBackground(BG)
reviewPanel.setBorder(new EmptyBorder(15, 15, 15, 15))
val ratingBox = new JComboBox[String](Array(
"5 - Excellent", "4 - Very Good",
"3 - Good", "2 - Average", "1 - Poor"
))
val reviewInput = new JTextArea(4, 30)
reviewInput.setLineWrap(true)
reviewInput.setWrapStyleWord(true)
reviewInput.setFont(new Font("SansSerif", Font.PLAIN, 15))
val submitReview = makeButton("SUBMIT REVIEW")
val reviewArea = new JTextArea()
reviewArea.setEditable(false)
reviewArea.setFont(new Font("SansSerif", Font.PLAIN, 14))
val reviewTop = new JPanel(new BorderLayout(6, 6))
reviewTop.setBackground(BG)
reviewTop.add(makeLabel("Rate your experience", 16), BorderLayout.NORTH)
reviewTop.add(ratingBox, BorderLayout.CENTER)
val reviewEntry = new JPanel(new BorderLayout(6, 6))
reviewEntry.setBackground(BG)
reviewEntry.add(reviewTop, BorderLayout.NORTH)
reviewEntry.add(new JScrollPane(reviewInput), BorderLayout.CENTER)
reviewEntry.add(submitReview, BorderLayout.SOUTH)
reviewPanel.add(reviewEntry, BorderLayout.NORTH)
reviewPanel.add(new JScrollPane(reviewArea), BorderLayout.CENTER)
// ================= REFRESH FUNCTIONS =================
def refreshMenu(): Unit = {
menuModel.clear()
val query = searchField.getText.trim.toLowerCase
val category = categories.getSelectedItem.toString
foods.filter { f =>
(category == "All" || f.category == category) &&
(f.name.toLowerCase.contains(query) || f.category.toLowerCase.contains(query))
}.foreach { f =>
menuModel.addElement(f.emoji + " " + f.name + " | Rs. " + f.price + " | " + f.category)
}
}
def refreshCart(): Unit = {
val text = new StringBuilder()
text.append("YOUR SHOPPING CART\n")
text.append("==============================\n\n")
var total = 0
cart.foreach { case (name, quantity) =>
val food = foods.find(_.name == name).get
val subtotal = food.price * quantity
total += subtotal
text.append(name + " x " + quantity + " = Rs. " + subtotal + "\n")
}
text.append("\n==============================\n")
text.append("TOTAL: Rs. " + total + "\n")
if (cart.isEmpty) text.append("\nCart is empty.")
cartArea.setText(text.toString)
}
def refreshTracking(): Unit = {
orderIdLabel.setText("Order ID: " + lastOrder)
trackingLabel.setText("Status: " + currentStatus)
}
def refreshHistory(): Unit = {
historyArea.setText(
if (orderHistory.isEmpty) "No past orders yet."
else orderHistory.reverse.mkString("\n\n")
)
}
def startLiveTracking(): Unit = {
if (deliveryTimer != null && deliveryTimer.isRunning) {
deliveryTimer.stop()
}
remainingSeconds = 120
progressBar.setMaximum(120)
progressBar.setValue(0)
currentStatus = "Order Placed & Confirmed"
refreshTracking()
deliveryTimer = new javax.swing.Timer(1000, new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
remainingSeconds -= 1
val elapsed = 120 - remainingSeconds
progressBar.setValue(elapsed)
val mins = remainingSeconds / 60
val secs = remainingSeconds % 60
timerLabel.setText("Estimated Time: " + "%02d:%02d".format(mins, secs) + " mins")
if (remainingSeconds > 80) {
currentStatus = "? Chef is Preparing Your Food..."
} else if (remainingSeconds > 0) {
currentStatus = "? Out for Delivery! (Delivery partner on the way)"
} else {
deliveryTimer.stop()
currentStatus = "? Rider arrived at your doorstep!"
refreshTracking()
timerLabel.setText("Delivery Partner Arrived!")
progressBar.setString("Arrived!")
val deliveryOtp = "1234"
val userOtp = JOptionPane.showInputDialog(
frame,
"? Your Order has Arrived!\n\nGive this Delivery OTP to Rider:\nDelivery OTP: " + deliveryOtp + "\n\nEnter OTP to Confirm Delivery:",
"Delivery Verification",
JOptionPane.INFORMATION_MESSAGE
)
if (userOtp == deliveryOtp) {
currentStatus = "? Successfully Delivered! Enjoy your meal."
refreshTracking()
if (orderHistory.nonEmpty) {
orderHistory(orderHistory.length - 1) = "Order: " + lastOrder + " | " + currentStatus
refreshHistory()
}
JOptionPane.showMessageDialog(frame, "Order Delivered Successfully!\nThank you for ordering with Foodie Restaurant! ??")
} else {
currentStatus = "?? Delivery OTP Mismatch"
refreshTracking()
JOptionPane.showMessageDialog(frame, "Wrong OTP entered. Please verify with Rider.")
}
}
refreshTracking()
}
})
deliveryTimer.start()
}
// ================= ACTION LISTENERS =================
logoutButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
val confirm = JOptionPane.showConfirmDialog(
frame,
"Are you sure you want to Logout?",
"Logout Confirmation",
JOptionPane.YES_NO_OPTION
)
if (confirm == JOptionPane.YES_OPTION) {
if (deliveryTimer != null && deliveryTimer.isRunning) {
deliveryTimer.stop()
}
frame.dispose()
openLogin()
}
}
})
searchField.getDocument.addDocumentListener(new javax.swing.event.DocumentListener {
override def insertUpdate(e: javax.swing.event.DocumentEvent): Unit = refreshMenu()
override def removeUpdate(e: javax.swing.event.DocumentEvent): Unit = refreshMenu()
override def changedUpdate(e: javax.swing.event.DocumentEvent): Unit = refreshMenu()
})
categories.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = refreshMenu()
})
addButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
val selected = menuList.getSelectedValue
if (selected == null) {
JOptionPane.showMessageDialog(frame, "Please select an item first.")
} else {
foods.find(f => selected.contains(f.name)) match {
case Some(food) =>
cart(food.name) = cart.getOrElse(food.name, 0) + 1
menuInfo.setText(food.name + " added to cart!")
refreshCart()
case None =>
JOptionPane.showMessageDialog(frame, "Item not found.")
}
}
}
})
removeButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
if (cart.isEmpty) {
JOptionPane.showMessageDialog(frame, "Cart is already empty!")
} else {
val items = cart.keys.toArray
val selectedItem = JOptionPane.showInputDialog(
frame,
"Select item to remove:",
"Remove Item",
JOptionPane.QUESTION_MESSAGE,
null,
items.asInstanceOf[Array[Object]],
items(0)
)
if (selectedItem != null) {
val key = selectedItem.toString
if (cart(key) > 1) cart(key) -= 1
else cart.remove(key)
refreshCart()
}
}
}
})
clearButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
cart.clear()
refreshCart()
}
})
checkoutButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
if (cart.isEmpty) {
JOptionPane.showMessageDialog(frame, "Your cart is empty. Please add items.")
} else {
var total = 0
cart.foreach { case (name, qty) =>
total += foods.find(_.name == name).get.price * qty
}
val confirm = JOptionPane.showConfirmDialog(
frame,
"Total Bill: Rs. " + total + "\nConfirm order & start live tracking?",
"Confirm Order",
JOptionPane.YES_NO_OPTION
)
if (confirm == JOptionPane.YES_OPTION) {
orderNumber += 1
lastOrder = "FD" + orderNumber
currentStatus = "Order Placed"
val details = "Order: " + lastOrder + " | Rs. " + total + " | " + currentStatus
orderHistory += details
cart.clear()
refreshCart()
refreshHistory()
tabs.setSelectedIndex(2)
startLiveTracking()
JOptionPane.showMessageDialog(
frame,
"Order Confirmed!\nOrder ID: " + lastOrder + "\nEstimated Delivery: 2 Minutes.\nCheck Tracking Tab!"
)
}
}
}
})
historyRefreshButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = refreshHistory()
})
submitReview.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
val message = reviewInput.getText.trim
if (message.nonEmpty) {
val review = ratingBox.getSelectedItem.toString + " - " + message
reviews += review
reviewArea.setText(reviews.reverse.mkString("\n\n"))
reviewInput.setText("")
JOptionPane.showMessageDialog(frame, "Thank you! Review saved.")
} else {
JOptionPane.showMessageDialog(frame, "Please write a review before submitting.")
}
}
})
// ================= TABS ASSEMBLY =================
tabs.addTab("? Menu", menuPanel)
tabs.addTab("? Cart", cartPanel)
tabs.addTab("? Tracking", trackingPanel)
tabs.addTab("? History", historyPanel)
tabs.addTab("? Reviews", reviewPanel)
root.add(header, BorderLayout.NORTH)
root.add(tabs, BorderLayout.CENTER)
frame.setContentPane(root)
refreshMenu()
refreshCart()
refreshHistory()
refreshTracking()
frame.setVisible(true)
}
// ================================================
// MAIN LOGIN
// ================================================
def openLogin(): Unit = {
val frame = new JFrame("Foodie Restaurant - Login")
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
frame.setSize(460, 420)
frame.setLocationRelativeTo(null)
val root = new JPanel(new BorderLayout(12, 12))
root.setBackground(BG)
root.setBorder(new EmptyBorder(25, 30, 25, 30))
val title = makeLabel("? FOODIE RESTAURANT", 25)
title.setHorizontalAlignment(SwingConstants.CENTER)
val subtitle = makeLabel("Welcome! Login to order delicious food", 13)
subtitle.setHorizontalAlignment(SwingConstants.CENTER)
val top = new JPanel(new GridLayout(2, 1, 5, 5))
top.setBackground(BG)
top.add(title)
top.add(subtitle)
val form = new JPanel(new GridLayout(5, 1, 8, 8))
form.setBackground(BG)
val userField = new JTextField()
userField.setFont(new Font("SansSerif", Font.PLAIN, 16))
val passField = new JPasswordField()
passField.setFont(new Font("SansSerif", Font.PLAIN, 16))
passField.setEchoChar('\u2022')
form.add(makeLabel("Username", 14))
form.add(userField)
form.add(makeLabel("Password", 14))
form.add(passField)
val loginButton = makeButton("LOGIN")
form.add(loginButton)
loginButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
val password = new String(passField.getPassword)
val username = userField.getText.trim
if (username.nonEmpty && sha256(password) == PASSWORD_HASH) {
frame.dispose()
openDashboard(username)
} else {
JOptionPane.showMessageDialog(
frame,
"Please enter a valid Username and correct Password.",
"Login Failed",
JOptionPane.ERROR_MESSAGE
)
}
passField.setText("")
}
})
val footer = makeLabel("Fresh Food ? Happy Life", 14)
footer.setHorizontalAlignment(SwingConstants.CENTER)
root.add(top, BorderLayout.NORTH)
root.add(form, BorderLayout.CENTER)
root.add(footer, BorderLayout.SOUTH)
frame.setContentPane(root)
frame.setVisible(true)
}
// ================================================
// APP LOGO / SPLASH SCREEN
// ================================================
def openLogo(): Unit = {
val frame = new JFrame("Foodie Restaurant")
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
frame.setSize(500, 350)
frame.setLocationRelativeTo(null)
val panel = new JPanel(new BorderLayout(12, 12))
panel.setBackground(BG)
panel.setBorder(new EmptyBorder(30, 25, 30, 25))
val logo = makeLabel("?", 64)
logo.setHorizontalAlignment(SwingConstants.CENTER)
val title = makeLabel("FOODIE RESTAURANT", 27)
title.setHorizontalAlignment(SwingConstants.CENTER)
val slogan = makeLabel("Fresh Food ? Great Taste ? Happy Life", 14)
slogan.setHorizontalAlignment(SwingConstants.CENTER)
val startButton = makeButton("START ORDERING")
val center = new JPanel(new GridLayout(3, 1, 5, 5))
center.setBackground(BG)
center.add(logo)
center.add(title)
center.add(slogan)
panel.add(center, BorderLayout.CENTER)
panel.add(startButton, BorderLayout.SOUTH)
startButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
frame.dispose()
openLogin()
}
})
frame.setContentPane(panel)
frame.setVisible(true)
}
// Start app
SwingUtilities.invokeLater(new Runnable {
override def run(): Unit = openLogo()
})