Skip to content

๐Ÿ’ธ This Java Expense Tracker Will Save Your Wallet! (With CSV Export & Category Totals!) ๐Ÿ“Š

Want a real-world Java project that teaches Swing, file I/O, table management, and more? Build this beautiful Java Expense Tracker and manage your daily spending like a pro!


๐Ÿ”ง What You’ll Build

โœ… Add daily expenses (amount, category, note)
โœ… View them in a table
โœ… See total expense by category
โœ… Export all entries to CSV
โœ… 100% Java, beginner-friendly, no frameworks!


๐Ÿ’ป Let’s Build: ExpenseTracker.java

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

public class ExpenseTracker extends JFrame {
    private DefaultTableModel tableModel;
    private JTable expenseTable;
    private JTextField amountField, noteField;
    private JComboBox<String> categoryBox;

    public ExpenseTracker() {
        setTitle("๐Ÿ’ธ Expense Tracker");
        setSize(700, 400);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // Top panel for input
        JPanel inputPanel = new JPanel(new GridLayout(2, 4, 10, 10));

        amountField = new JTextField();
        noteField = new JTextField();
        categoryBox = new JComboBox<>(new String[]{"Food", "Transport", "Bills", "Entertainment", "Other"});
        JButton addButton = new JButton("Add Expense");

        inputPanel.add(new JLabel("Amount:"));
        inputPanel.add(new JLabel("Category:"));
        inputPanel.add(new JLabel("Note:"));
        inputPanel.add(new JLabel(""));

        inputPanel.add(amountField);
        inputPanel.add(categoryBox);
        inputPanel.add(noteField);
        inputPanel.add(addButton);

        // Table for expenses
        tableModel = new DefaultTableModel(new String[]{"Amount", "Category", "Note", "Date"}, 0);
        expenseTable = new JTable(tableModel);
        JScrollPane tableScroll = new JScrollPane(expenseTable);

        // Buttons
        JButton totalButton = new JButton("View Totals");
        JButton exportButton = new JButton("Export to CSV");

        JPanel buttonPanel = new JPanel();
        buttonPanel.add(totalButton);
        buttonPanel.add(exportButton);

        // Add components to frame
        setLayout(new BorderLayout());
        add(inputPanel, BorderLayout.NORTH);
        add(tableScroll, BorderLayout.CENTER);
        add(buttonPanel, BorderLayout.SOUTH);

        // Action listeners
        addButton.addActionListener(e -> addExpense());
        totalButton.addActionListener(e -> showTotals());
        exportButton.addActionListener(e -> exportToCSV());

        setVisible(true);
    }

    private void addExpense() {
        try {
            double amount = Double.parseDouble(amountField.getText());
            String category = categoryBox.getSelectedItem().toString();
            String note = noteField.getText();
            String date = new java.util.Date().toString();

            tableModel.addRow(new Object[]{amount, category, note, date});
            amountField.setText("");
            noteField.setText("");
        } catch (NumberFormatException e) {
            JOptionPane.showMessageDialog(this, "Enter a valid amount.");
        }
    }

    private void showTotals() {
        Map<String, Double> totals = new HashMap<>();

        for (int i = 0; i < tableModel.getRowCount(); i++) {
            String category = tableModel.getValueAt(i, 1).toString();
            double amount = (double) tableModel.getValueAt(i, 0);

            totals.put(category, totals.getOrDefault(category, 0.0) + amount);
        }

        StringBuilder result = new StringBuilder("Total Expenses by Category:\n");
        for (String cat : totals.keySet()) {
            result.append(cat).append(": โ‚น").append(totals.get(cat)).append("\n");
        }

        JOptionPane.showMessageDialog(this, result.toString());
    }

    private void exportToCSV() {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("Save as CSV");

        int option = fileChooser.showSaveDialog(this);
        if (option == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();

            try (PrintWriter writer = new PrintWriter(file)) {
                // Write header
                for (int i = 0; i < tableModel.getColumnCount(); i++) {
                    writer.print(tableModel.getColumnName(i) + (i < tableModel.getColumnCount() - 1 ? "," : ""));
                }
                writer.println();

                // Write rows
                for (int row = 0; row < tableModel.getRowCount(); row++) {
                    for (int col = 0; col < tableModel.getColumnCount(); col++) {
                        writer.print(tableModel.getValueAt(row, col) + (col < tableModel.getColumnCount() - 1 ? "," : ""));
                    }
                    writer.println();
                }

                JOptionPane.showMessageDialog(this, "Data exported successfully!");
            } catch (IOException e) {
                JOptionPane.showMessageDialog(this, "Error saving file.");
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(ExpenseTracker::new);
    }
}

๐Ÿ“˜ Code Breakdown

๐ŸŽฏ addExpense()

double amount = Double.parseDouble(amountField.getText());

Takes user input and adds a new row to the table with the current timestamp.

๐Ÿ“Š showTotals()

Map<String, Double> totals = new HashMap<>();

Loops through table rows, aggregates expenses by category using a map.


๐Ÿ“ exportToCSV()

PrintWriter writer = new PrintWriter(file);

Saves the table data to a .csv file you can open in Excel/Google Sheets.


๐Ÿงต Table Model

tableModel = new DefaultTableModel(new String[]{"Amount", "Category", "Note", "Date"}, 0);

Core of the data: dynamic table that updates in real time.


โœ… Extra Challenge Ideas

  • Add a monthly filter
  • Add a login screen
  • Generate charts with JFreeChart
  • Add delete/edit functionality for rows
  • Save/load data with serialization

๐Ÿ’ก Why This Project is a Game-Changer

  • Teaches practical Swing use
  • Uses real-world data structures (Map, TableModel)
  • Covers file export skills
  • Shows date handling and input validation

Tags:

Leave a Reply

Your email address will not be published. Required fields are marked *