Skip to content

πŸ’Έ You Won’t Believe This Java App Manages Your Budget Like a Pro (With Full Code!) πŸ”₯

Are you ready to take control of your finances and learn Java in the process? Today, I’m going to walk you through creating a Personal Budget Manager desktop application using Java Swing and File I/O β€” and yes, it’s beginner-friendly, but powerful enough to impress your friends or ace that portfolio project. 😎

Let’s dive into how you can build this app from scratch, with every line of code explained.


🧠 What You’ll Learn:

  • Java OOP design
  • GUI with Java Swing
  • File I/O for persistent data
  • Budget calculations
  • Error handling and clean code practices

πŸ“ Project Structure:

com.budgetmanager
β”‚
β”œβ”€β”€ BudgetManager.java // GUI & main entry point
β”œβ”€β”€ Transaction.java // Represents each entry
β”œβ”€β”€ BudgetService.java // Business logic
β”œβ”€β”€ FileManager.java // File read/write
└── data/
└── budget_data.csv // Saved transaction data

βœ… Features:

  • Add income and expenses
  • Categorize transactions
  • View total income, expenses, and remaining balance
  • Save/load data from a CSV file

πŸš€ Step-by-Step Code (With Explanations)


1️⃣ Transaction.java: Model Class

import java.time.LocalDate;

public class Transaction {
    private String type; // Income or Expense
    private String category;
    private double amount;
    private LocalDate date;

    public Transaction(String type, String category, double amount, LocalDate date) {
        this.type = type;
        this.category = category;
        this.amount = amount;
        this.date = date;
    }

    public String getType() { return type; }
    public String getCategory() { return category; }
    public double getAmount() { return amount; }
    public LocalDate getDate() { return date; }

    @Override
    public String toString() {
        return type + "," + category + "," + amount + "," + date;
    }
}

πŸ’‘ Explanation: This class represents one budget entry, storing its type (income/expense), category, amount, and date.


2️⃣ BudgetService.java: Budget Logic

import java.util.ArrayList;
import java.util.List;

public class BudgetService {
    private List<Transaction> transactions = new ArrayList<>();

    public void addTransaction(Transaction t) {
        transactions.add(t);
    }

    public double getTotalIncome() {
        return transactions.stream()
            .filter(t -> t.getType().equalsIgnoreCase("Income"))
            .mapToDouble(Transaction::getAmount).sum();
    }

    public double getTotalExpense() {
        return transactions.stream()
            .filter(t -> t.getType().equalsIgnoreCase("Expense"))
            .mapToDouble(Transaction::getAmount).sum();
    }

    public double getRemainingBudget() {
        return getTotalIncome() - getTotalExpense();
    }

    public List<Transaction> getTransactions() {
        return transactions;
    }

    public void setTransactions(List<Transaction> transactions) {
        this.transactions = transactions;
    }
}

πŸ’‘ Explanation: Core service to manage and calculate the totals for income, expenses, and balance.


3️⃣ FileManager.java: Data Persistence

import java.io.*;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

public class FileManager {
    private static final String FILE_PATH = "data/budget_data.csv";

    public static void save(List<Transaction> transactions) throws IOException {
        BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_PATH));
        for (Transaction t : transactions) {
            writer.write(t.toString());
            writer.newLine();
        }
        writer.close();
    }

    public static List<Transaction> load() throws IOException {
        List<Transaction> transactions = new ArrayList<>();
        File file = new File(FILE_PATH);
        if (!file.exists()) return transactions;

        BufferedReader reader = new BufferedReader(new FileReader(FILE_PATH));
        String line;
        while ((line = reader.readLine()) != null) {
            String[] parts = line.split(",");
            Transaction t = new Transaction(
                parts[0],
                parts[1],
                Double.parseDouble(parts[2]),
                LocalDate.parse(parts[3])
            );
            transactions.add(t);
        }
        reader.close();
        return transactions;
    }
}

πŸ’‘ Explanation: Reads and writes all transactions to a CSV file. Automatically creates an empty list if the file doesn’t exist.


4️⃣ BudgetManager.java: Main GUI App

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.time.LocalDate;
import java.util.List;

public class BudgetManager extends JFrame {
    private BudgetService budgetService = new BudgetService();
    private DefaultTableModel tableModel;

    public BudgetManager() {
        setTitle("Java Budget Manager");
        setSize(700, 400);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        initComponents();
        loadExistingData();
    }

    private void initComponents() {
        JPanel inputPanel = new JPanel(new GridLayout(2, 5, 10, 10));
        String[] types = { "Income", "Expense" };
        JComboBox<String> typeBox = new JComboBox<>(types);
        JTextField categoryField = new JTextField();
        JTextField amountField = new JTextField();
        JTextField dateField = new JTextField(LocalDate.now().toString());

        JButton addButton = new JButton("Add Transaction");

        inputPanel.add(new JLabel("Type"));
        inputPanel.add(new JLabel("Category"));
        inputPanel.add(new JLabel("Amount"));
        inputPanel.add(new JLabel("Date (YYYY-MM-DD)"));
        inputPanel.add(new JLabel("")); // Spacer

        inputPanel.add(typeBox);
        inputPanel.add(categoryField);
        inputPanel.add(amountField);
        inputPanel.add(dateField);
        inputPanel.add(addButton);

        add(inputPanel, BorderLayout.NORTH);

        String[] columns = { "Type", "Category", "Amount", "Date" };
        tableModel = new DefaultTableModel(columns, 0);
        JTable table = new JTable(tableModel);
        add(new JScrollPane(table), BorderLayout.CENTER);

        JLabel summaryLabel = new JLabel();
        updateSummary(summaryLabel);
        add(summaryLabel, BorderLayout.SOUTH);

        addButton.addActionListener(e -> {
            try {
                String type = typeBox.getSelectedItem().toString();
                String category = categoryField.getText();
                double amount = Double.parseDouble(amountField.getText());
                LocalDate date = LocalDate.parse(dateField.getText());

                Transaction t = new Transaction(type, category, amount, date);
                budgetService.addTransaction(t);
                tableModel.addRow(new Object[]{ type, category, amount, date });
                updateSummary(summaryLabel);
                FileManager.save(budgetService.getTransactions());

                categoryField.setText("");
                amountField.setText("");
                dateField.setText(LocalDate.now().toString());
            } catch (Exception ex) {
                JOptionPane.showMessageDialog(this, "Invalid input. Please check your values.");
            }
        });
    }

    private void loadExistingData() {
        try {
            List<Transaction> transactions = FileManager.load();
            budgetService.setTransactions(transactions);
            for (Transaction t : transactions) {
                tableModel.addRow(new Object[]{ t.getType(), t.getCategory(), t.getAmount(), t.getDate() });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void updateSummary(JLabel summaryLabel) {
        double income = budgetService.getTotalIncome();
        double expense = budgetService.getTotalExpense();
        double remaining = budgetService.getRemainingBudget();
        summaryLabel.setText("πŸ’° Total Income: β‚Ή" + income +
                " | πŸ’Έ Total Expenses: β‚Ή" + expense +
                " | πŸ’Ό Remaining: β‚Ή" + remaining);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new BudgetManager().setVisible(true));
    }
}

πŸ’‘ Explanation:

  • Builds the main app window
  • Takes user input for new transactions
  • Displays all transactions in a table
  • Shows a real-time summary of income, expense, and balance

🎁 Bonus Idea:

Want to go next level? Add:

  • A pie chart to visualize expenses by category (with JFreeChart)
  • Export as PDF/Excel
  • Monthly budget reports
  • Cloud sync using Firebase or MySQL

🎯 Final Thoughts

This app may be simple, but it covers everything: OOP, GUI, file handling, and real-world problem-solving. If you’re learning Java or building a portfolio, this project is perfect.


πŸ™Œ Like the project?

Subscribe to my blog for more Java + Spring Boot tutorials!

Share it with your friends!

Leave a comment below if you’d like me to add graphing support πŸ“Š

Tags:

Leave a Reply

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