Skip to content

Repository files navigation

Stock Management System (Java Swing + MySQL)

A desktop inventory / retail management system built with Java Swing and a MySQL backend via JDBC. It supports product inventory, point-of-sale style cart & billing, purchase requests with supplier approval, product returns, and sales tracking, with a hand-built modern UI in the style of commercial ERP software (see "UI / Design" below).

Built by Chatush Raj.

Features

  • Login — separate retailer and supplier login flows
  • Inventory management — add products, view current stock
  • Search & sell — case-insensitive partial search by Item ID or Name, live total-price calculation while typing, stock validation before adding to cart
  • Cart & checkout — multi-item cart, transactional checkout (stock deduction, bill generation, and cart clearing all happen atomically — if anything fails, nothing is changed)
  • Purchase requests — request more stock for a product; a supplier can review and approve requests, which restocks inventory
  • Returns — look up a bill by number and return an item, restocking it
  • Sales tracking — look up all sales for a given date
  • Invoice printing — print the most recent bill directly from the app

Tech stack

Layer Technology
UI Java Swing, hand-built layouts (see "UI / Design" below)
Database MySQL
Connectivity JDBC (MySQL Connector/J 8.0.33)
Build Ant (NetBeans project) — build.xml

Project structure

StockManagementSystem/
├── src/MainFiles/           # All application source (one class per screen)
│   ├── DBConnect.java           # Central JDBC connection helper
│   ├── AppTheme.java            # Shared UI theme (colors, fonts, cards, buttons, tables, motion)
│   ├── AppIcons.java            # Flat vector icon set (drawn with Graphics2D, no image assets)
│   ├── Login.java / Slogin.java # Retailer / supplier login
│   ├── mainFrame.java           # Main dashboard (sidebar nav + menu bar)
│   ├── addproduct.java          # Add product to inventory
│   ├── Inventory.java           # View current inventory
│   ├── Searchproduct.java       # Search products & add to cart
│   ├── addtocart.java           # View cart & checkout
│   ├── bill.java                # Invoice view / print
│   ├── Purchase.java            # Request a product restock
│   ├── supplierapprove.java     # Supplier approves pending purchase requests
│   ├── returnproduct.java       # Process a product return
│   └── Track.java               # Sales lookup by date
├── lib/mysql-connector-j-8.0.33.jar  # JDBC driver (project-relative, portable)
├── database_schema.sql     # MySQL schema + sample data (database name: fs)
├── build.xml               # Ant build script (NetBeans-generated)
└── nbproject/               # NetBeans project metadata

Getting started

1. Prerequisites

  • JDK 8 or later
  • MySQL Server (5.x or 8.x)
  • NetBeans IDE (optional — this project builds fine as a plain Ant project; NetBeans is convenient since the project already includes nbproject/ metadata), or any IDE/editor that can run an Ant build

2. Set up the database

mysql -u your_mysql_username -p -e "CREATE DATABASE fs"
mysql -u your_mysql_username -p fs < database_schema.sql

This creates the fs database with the inventory, cart, bill, and purchase tables (plus a little sample data to explore with).

3. Configure the database connection

The application reads the database credentials from environment variables.

Windows (PowerShell)

setx DB_USER "your_mysql_username"
setx DB_PASSWORD "your_mysql_password"

Restart your IDE or terminal after setting the variables.

The application will automatically use these values when connecting to MySQL.

4. Open and run

  1. Open the StockManagementSystem folder as a project in NetBeans (File → Open Project).
  2. Make sure lib/mysql-connector-j-8.0.33.jar (included in this repo) is on the project's classpath — it's already wired up via the NetBeans project properties.
  3. Run the project — it starts at Login.java.

Demo credentials (hardcoded for this project — see note below):

  • Retailer login: admin / 123
  • Supplier login: supplier / 123

Building/running from the command line (without NetBeans)

cd StockManagementSystem/src
javac -encoding UTF-8 -cp /path/to/mysql-connector-j-8.0.33.jar -d ../build MainFiles/*.java
java -cp ../build:/path/to/mysql-connector-j-8.0.33.jar MainFiles.Login

UI / Design

Every screen has been rebuilt with a genuine layout redesign rather than just colors — modern spacing, card-based sections, a sidebar-navigation dashboard, and consistent typography, in the style of commercial ERP/inventory software:

  • AppTheme.java — shared slate-and-blue color palette, typography, a RoundedPanel card component, styled tables (striped rows, dark header), styled primary/secondary/sidebar buttons with hover feedback, and a small window fade-in animation (AppTheme.fadeIn) used when each screen opens.
  • AppIcons.java — a set of flat icons (search, cart, add, back, logout, inventory, purchase, return, track, home, approve, user, lock) drawn directly with Graphics2D. No external icon pack or image assets are needed, so there's nothing to go missing or break across machines.
  • mainFrame.java — redesigned as a proper dashboard: a header bar, an icon-based sidebar for navigation, a welcome card, and a Modules/File/Help menu bar that mirrors the sidebar.
  • Login.java / Slogin.java — redesigned as a branded split panel (colored brand panel + white form card), and the password field is now a real JPasswordField (previously it was a plain text field that showed the password as you typed).
  • Every other screen (Search, Cart/Checkout, Purchase, Return, Track, Inventory, Add Product, Supplier Approve, Invoice) follows the same toolbar → card → form/table pattern for visual consistency across the whole app.

Trade-off: NetBeans GUI Builder compatibility

To do a genuine layout redesign (not just recoloring), these 12 screens were rewritten by hand using standard Swing layout managers (BorderLayout, GridBagLayout, BoxLayout) instead of NetBeans's auto-generated GroupLayout. Every original component field, button, and event handler was preserved exactly, so all functionality is unchanged — only the visual arrangement changed.

The one consequence: these screens no longer have a paired .form file, so they can no longer be edited via the NetBeans drag-and-drop GUI Builder. The .java files still open, compile, and run perfectly fine in NetBeans (or any IDE) — you'd just edit the layout code directly rather than dragging components around, the same as any hand-written Swing application.

Notes on the codebase

This started as a college project and has been substantially cleaned up:

  • Fixed a critical bug where DBConnect.java tried to load a driver class (com.mysql.cj.jdbc.Driver) that doesn't exist in the connector jar actually bundled with the project — meaning every database call would silently fail. It now relies on standard JDBC 4 driver auto-registration, which works correctly with the connector jar included in lib/.
  • Fixed a broken classpath reference in the NetBeans project (it pointed to an absolute path on one machine's Downloads folder). The MySQL connector jar now lives in lib/ inside the repo and is referenced relatively, so the project opens correctly on any machine.
  • All SQL queries that included user input now use PreparedStatement instead of string concatenation (fixes SQL injection vulnerabilities that existed in the original search/lookup screens).
  • Checkout, purchase-approval, and return flows now validate stock levels and use transactions so a failure partway through can't leave the database in an inconsistent state.
  • Fixed a business-logic bug where approving a purchase request restocked inventory but never removed the request, meaning a request could be approved multiple times.
  • Fixed a bug where approving a purchase order on the buyer side actually decreased stock instead of increasing it.
  • Replaced hardcoded, machine-specific Windows image paths with a hand-drawn vector icon set (AppIcons.java) — there are no image assets left in the project at all, so there's nothing that can go missing across machines.
  • Fixed a mislabeled button in the Purchase screen ("Purchase Return") that actually approved and restocked inventory — renamed to "Approve Purchase" to match what it does.
  • Live total-price calculation while typing (instead of only recalculating when a field loses focus).
  • Fixed a data-model bug in the bill table: biilno is a per-row auto-increment id, not a shared invoice number, so checking out a multi-item cart produced multiple unrelated "bill numbers" and the Invoice screen had no way to show just one transaction — it showed the entire bill history instead. Added an invoice_no column that's stamped once per checkout, and updated the Invoice screen, sales Track screen, and Return screen to use it consistently as "the bill number." (If you already have an existing fs database from before this fix, run ALTER TABLE bill ADD COLUMN invoice_no INT NOT NULL DEFAULT 0, ADD KEY invoice_no (invoice_no); and backfill it, e.g. UPDATE bill SET invoice_no = biilno WHERE invoice_no = 0;, or just re-import database_schema.sql on a fresh database.)
  • Added a product_return table so processed returns are permanently logged with a system-generated timestamp, the same way bills and purchases already were — previously a return only silently adjusted inventory quantity with no record the return ever happened. (Existing databases: run CREATE TABLE IF NOT EXISTS product_return (id int(10) NOT NULL AUTO_INCREMENT, invoice_no int(30) NOT NULL, item_id varchar(10) NOT NULL, item_name varchar(30) NOT NULL, quantity int(20) NOT NULL, price double NOT NULL, totprice double NOT NULL, date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id)) ENGINE=MyISAM DEFAULT CHARSET=latin1; or just re-import database_schema.sql on a fresh database.)
  • The purchase table already recorded a system timestamp on every request, but it was never shown anywhere — the supplier's "Approve Purchase Requests" screen now displays a "Requested On" column sourced from it.
  • Fixed a subtler bug introduced during an earlier cleanup pass: several screens opened the database connection and checked it for null inside a try-with-resources block that also opened a PreparedStatement/Statement in the same parentheses. Since try-with-resources initializes every resource before the body runs, a failed connection (null) caused an unhandled NullPointerException instead of the friendly "could not connect" message the null-check was supposed to show. The connection is now opened and checked before entering the try-with-resources for the statement.

Known limitations (kept as-is, since this is a learning/portfolio project rather than a production system):

  • Login credentials are hardcoded rather than stored/hashed in the database.
  • Single-user desktop application — no multi-user session handling.
  • This project is intended for learning and portfolio purposes. For production deployments, additional improvements such as secure authentication, role-based authorization, comprehensive input validation, logging, and automated testing would be recommended.

License

This project is provided for educational/portfolio purposes.

About

Modern Java Swing + MySQL desktop inventory and billing management system.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages