Project Report: Billing App Enhanced
Submitted By: [Ali Mumtaz, Ahmad Rizwan, Mubashir]
Course: [OOP Project]
Submitted To: [Mam Tahira]
Institution: [NUML]
Date: June 30, 2025
So, I made this Billing App Enhanced, a desktop application in Java designed to help small
businesses with their billing tasks. It’s pretty user-friendly, letting folks create, view, search,
and delete bills without a hassle. I put this project together for my [Course Name] course to
show off what I can do with Java and make something that’s actually useful. Here’s a
rundown of what the project is about, what it aims to do, its features, the tools I used, how I
built it, some challenges I faced, and ideas on how to improve it.
The Billing App Enhanced is all about helping users stay on top of their customer bills. You
can create bills, check them out by customer or product, see all your bills, and delete the
ones you don’t need anymore. The app is simple to navigate, with buttons and text fields
that make it super easy. Plus, it saves bills in a text file so you can get back to them later.
When I set out to build this, I wanted to:
Make an easy-to-use app with a clear layout for managing bills.
Include features to create, view, search, and delete bills.
Follow good coding practices to keep everything neat.
Save bills in a file to keep the data secure.
Ensure the app can handle mistakes, like if someone accidentally types the wrong info,
without crashing.
As for features, the app has a few cool options:
Main Menu: A starting screen where users can jump into any task (create, view,
search, delete, or quit).
Create Bill: Users can enter customer info, add product details (like name, quantity,
and price), and save the bill.
Find Bill: Users can see bills for a specific customer.
View All Bills: Displays every bill saved in the app.
Search by Product: Lets you find bills with specific products in them.
Delete Bill: Removes a bill based on the customer’s name.
Input Checks: Makes sure users don’t mess up by checking for valid entries (like
making sure prices are numbers).
Data Saving: Bills are saved in a text file with details such as customer name, date,
and total amount.
To build this app, I used:
Java: The main coding language.
Java Swing: A tool for the app’s interface (like buttons and text fields).
IDE: [Your IDE, like IntelliJ IDEA or Eclipse] for writing and testing the code.
Text File: A file called bills.txt for saving bill info.
Java Libraries: Handy tools for file handling and adding dates to bills.
I designed the app to be straightforward:
Interface: It uses buttons, text fields, and lists, which makes it easy to navigate.
Logic: It takes care of tasks like adding items, calculating totals, and saving bills.
Data Storage: Bills are saved and retrieved from a text file.
There are separate screens for each task, like creating a bill or searching for one, making
everything flow smoothly.
Building the app was a step-by-step process:
I started by creating a main menu and screens for each task.
For bill creation, I added options for entering customer and item details, calculating
totals, and saving bills.
I built features to find, view, and delete bills using file reading and writing.
Error handling was a big part; I made sure the app wouldn’t crash if someone entered the
wrong info, and I included helpful error messages.
Finally, I tested the app to ensure everything worked well and was user-friendly.
I faced some challenges along the way:
It was tricky to ensure bills were saved properly and retrieved without issues, but I learned
to handle files effectively.
Switching between screens, like from the menu to the bill creation page, was a bit of a
puzzle too. I managed it by closing one screen before opening another.
I needed to make sure the app didn’t crash with wrong inputs, so I built in checks and error
messages.
Searching for bills by product was also tough, but I figured out how to match product names
correctly.
The Billing App Enhanced is a working application that makes billing tasks simpler for small
businesses. It’s hit all my goals with a user-friendly interface, solid features, and reliable bill
storage. Working on this project has helped me get better at Java, user interface design, and
problem-solving. The app’s good to go for basic billing needs, and there’s still room for
improvements.
Looking ahead, I could make the app even better by:
Using a database instead of a text file for storing bills more efficiently.
Adding a feature for generating PDF receipts.
Giving the interface a fresh, modern look.
Adding a login system for some extra security.
Letting users edit bills instead of just deleting them.
Program:
import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*;
import java.time.LocalDateTime; import java.util.*;
public class BillingAppEnhanced {
static final String BILL_FILE = "bills.txt"; static int billCounter = 1;
public static void main(String[] args) { new BillingAppEnhanced().mainMenu();
}
public void mainMenu() {
JFrame frame = new JFrame("Billing App - Main Menu"); frame.setSize(300, 300);
frame.setLayout(new GridLayout(6, 1, 10, 10));
JButton createBtn = new JButton("Create Bill");
JButton fetchBtn = new JButton("Fetch Bill by Customer"); JButton viewAllBtn = new
JButton("View All Bills");
JButton searchProductBtn = new JButton("Search by Product"); JButton deleteBtn = new
JButton("Delete Bill");
JButton exitBtn = new JButton("Exit");
createBtn.addActionListener(e -> { frame.dispose(); createBillPage();
});
fetchBtn.addActionListener(e -> { frame.dispose(); fetchBillPage();
});
viewAllBtn.addActionListener(e -> { frame.dispose(); viewAllBillsPage();
});
searchProductBtn.addActionListener(e -> { frame.dispose(); searchByProductPage();
});
deleteBtn.addActionListener(e -> {
frame.dispose();
deleteBillPage(); });
exitBtn.addActionListener(e -> System.exit(0));
frame.add(createBtn); frame.add(fetchBtn); frame.add(viewAllBtn);
frame.add(searchProductBtn); frame.add(deleteBtn); frame.add(exitBtn);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null); frame.setVisible(true);
}
public void createBillPage() {
JFrame frame = new JFrame("Create Bill"); frame.setSize(600, 400);
DefaultListModel<String> itemListModel = new DefaultListModel<>(); JList<String> itemList =
new JList<>(itemListModel);
JTextField nameField = new JTextField(); JTextField productField = new JTextField(); JTextField
quantityField = new JTextField(); JTextField priceField = new JTextField(); JLabel totalLabel =
new JLabel("0");
JButton addItemBtn = new JButton("Add Item"); JButton saveBtn = new JButton("Save Bill");
JButton backBtn = new JButton("Back");
JPanel inputPanel = new JPanel(new GridLayout(5, 2)); inputPanel.add(new
JLabel("Customer Name:")); inputPanel.add(nameField);
inputPanel.add(new JLabel("Product Name:")); inputPanel.add(productField);
inputPanel.add(new JLabel("Quantity:")); inputPanel.add(quantityField);
inputPanel.add(new JLabel("Price:")); inputPanel.add(priceField); inputPanel.add(new
JLabel("Total:")); inputPanel.add(totalLabel);
JPanel buttonPanel = new JPanel(); buttonPanel.add(addItemBtn);
buttonPanel.add(saveBtn); buttonPanel.add(backBtn);
frame.setLayout(new BorderLayout()); frame.add(inputPanel, BorderLayout.NORTH);
frame.add(new JScrollPane(itemList), BorderLayout.CENTER); frame.add(buttonPanel,
BorderLayout.SOUTH);
java.util.List<String> billItems = new ArrayList<>(); final int[] grandTotal = {0};
addItemBtn.addActionListener(e -> { try {
String prod = productField.getText();
int qty = Integer.parseInt(quantityField.getText()); int price =
Integer.parseInt(priceField.getText()); int total = qty * price;
String entry = prod + " | Qty: " + qty + " | Price: " + price + " | Total: " + total;
itemListModel.addElement(entry);
billItems.add(entry); grandTotal[0] += total;
totalLabel.setText(String.valueOf(grandTotal[0])); productField.setText("");
quantityField.setText("");
priceField.setText(""); } catch (Exception ex) {
JOptionPane.showMessageDialog(frame, "Enter valid numbers for quantity and price.");
} });
saveBtn.addActionListener(e -> { if (nameField.getText().isEmpty() || billItems.isEmpty()) {
JOptionPane.showMessageDialog(frame, "Enter customer name and at least one item.");
return; }
try (BufferedWriter writer = new BufferedWriter(new FileWriter(BILL_FILE, true))) { String id
= "Bill#" + (billCounter++);
writer.write(id + "\n");
writer.write("Customer: " + nameField.getText() + "\n"); writer.write("Date: " +
LocalDateTime.now() + "\n"); for (String item : billItems) writer.write(item + "\n");
writer.write("Grand Total: " + grandTotal[0] + "\n"); writer.write("---\n");
JOptionPane.showMessageDialog(frame, "Bill Saved!");
mainMenu(); frame.dispose();
} catch (IOException ex) { JOptionPane.showMessageDialog(frame, "Error saving bill.");
} });
backBtn.addActionListener(e -> { frame.dispose(); mainMenu();
});
frame.setLocationRelativeTo(null); frame.setVisible(true);
}
public void fetchBillPage() {
JFrame frame = new JFrame("Fetch Bill"); frame.setSize(400, 400);
JTextField nameField = new JTextField(); JTextArea outputArea = new JTextArea(); JButton
fetchBtn = new JButton("Fetch"); JButton backBtn = new JButton("Back");
frame.setLayout(new BorderLayout());
JPanel top = new JPanel(new GridLayout(2, 2)); top.add(new JLabel("Customer Name:"));
top.add(nameField);
top.add(fetchBtn); top.add(backBtn);
outputArea.setEditable(false); frame.add(top, BorderLayout.NORTH);
frame.add(new JScrollPane(outputArea), BorderLayout.CENTER);
fetchBtn.addActionListener(e -> {
try (BufferedReader reader = new BufferedReader(new FileReader(BILL_FILE))) { String line,
output = "";
boolean match = false;
while ((line = reader.readLine()) != null) {
if (line.startsWith("Customer: ") && line.contains(nameField.getText())) { match = true;
} if (match) {
output += line + "\n"; if (line.equals("---")) break;
}}
outputArea.setText(match ? output : "Bill not found.");
} catch (IOException ex) { outputArea.setText("Error reading file.");
} });
backBtn.addActionListener(e -> { frame.dispose(); mainMenu();
});
frame.setLocationRelativeTo(null); frame.setVisible(true);
}
public void viewAllBillsPage() {
JFrame frame = new JFrame("All Bills"); frame.setSize(500, 500);
JTextArea textArea = new JTextArea(); JButton backBtn = new JButton("Back");
try (BufferedReader reader = new BufferedReader(new FileReader(BILL_FILE))) { String line;
while ((line = reader.readLine()) != null) { textArea.append(line + "\n");
}
} catch (IOException ex) { textArea.setText("Could not read bills.");
}
textArea.setEditable(false); frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(textArea), BorderLayout.CENTER); frame.add(backBtn,
BorderLayout.SOUTH);
backBtn.addActionListener(e -> { frame.dispose(); mainMenu();
});
frame.setLocationRelativeTo(null); frame.setVisible(true);
}
public void searchByProductPage() {
JFrame frame = new JFrame("Search by Product"); frame.setSize(500, 500);
JTextField productField = new JTextField();
JTextArea resultArea = new JTextArea(); JButton searchBtn = new JButton("Search"); JButton
backBtn = new JButton("Back");
frame.setLayout(new BorderLayout());
JPanel top = new JPanel(new GridLayout(2, 2)); top.add(new JLabel("Product Name:"));
top.add(productField);
top.add(searchBtn); top.add(backBtn);
frame.add(top, BorderLayout.NORTH);
frame.add(new JScrollPane(resultArea), BorderLayout.CENTER);
searchBtn.addActionListener(e -> {
try (BufferedReader reader = new BufferedReader(new FileReader(BILL_FILE))) { String line,
output = "";
boolean collect = false;
while ((line = reader.readLine()) != null) { if (line.startsWith("Bill#")) collect = false;
if (line.toLowerCase().contains(productField.getText().toLowerCase())) { collect = true;
}
if (collect || line.startsWith("Customer:")) { output += line + "\n";
}
if (line.equals("---")) collect = false; }
resultArea.setText(output.isEmpty() ? "No bills found." : output);
} catch (IOException ex) { resultArea.setText("Error reading file.");
} });
backBtn.addActionListener(e -> { frame.dispose(); mainMenu();
});
frame.setLocationRelativeTo(null); frame.setVisible(true);
}
public void deleteBillPage() {
JFrame frame = new JFrame("Delete Bill"); frame.setSize(400, 300);
JTextField nameField = new JTextField();
JButton deleteBtn = new JButton("Delete"); JButton backBtn = new JButton("Back");
JTextArea resultArea = new JTextArea();
frame.setLayout(new BorderLayout());
JPanel top = new JPanel(new GridLayout(2, 2)); top.add(new JLabel("Customer Name:"));
top.add(nameField);
top.add(deleteBtn); top.add(backBtn);
frame.add(top, BorderLayout.NORTH);
frame.add(new JScrollPane(resultArea), BorderLayout.CENTER);
deleteBtn.addActionListener(e -> {
try (BufferedReader reader = new BufferedReader(new FileReader(BILL_FILE));
BufferedWriter writer = new BufferedWriter(new FileWriter("temp.txt"))) { String line;
boolean skip = false, found = false; while ((line = reader.readLine()) != null) {
if (line.startsWith("Customer: ") && line.contains(nameField.getText())) { skip = true;
found = true; }
if (!skip) writer.write(line + "\n"); if (line.equals("---")) skip = false;
} new File(BILL_FILE).delete();
new File("temp.txt").renameTo(new File(BILL_FILE)); resultArea.setText(found ? "Bill
deleted." : "Bill not found.");
} catch (IOException ex) { resultArea.setText("Error deleting bill.");
} });
backBtn.addActionListener(e -> { frame.dispose(); mainMenu();
});
frame.setLocationRelativeTo(null); frame.setVisible(true);
}}
OUTPUT: