Untitled
unknown
plain_text
20 days ago
13 kB
0
Indexable
import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.data.general.DefaultPieDataset; import org.jfree.data.category.DefaultCategoryDataset; import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.awt.*; import java.io.*; import java.text.DecimalFormat; import java.util.*; import java.util.List; public class ExpenseTracker { private JFrame frame; private JTabbedPane tabbedPane; private JTable spendingTable, transactionTable; private DefaultTableModel spendingModel, transactionModel; private JLabel totalExpenseLabel, balanceLabel, savingsLabel; private HashMap<String, HashMap<String, Double>> monthlySpendingData; private List<Object[]> transactionHistory; private double income = 0.0; private String currentUser = null; private String selectedMonth = "January"; // Default selected month private static final String DATA_FILE_PREFIX = "expense_data_"; // Prefix for saving per-user data file public ExpenseTracker() { monthlySpendingData = new HashMap<>(); transactionHistory = new ArrayList<>(); showLoginDialog(); } private void showLoginDialog() { JPanel loginPanel = new JPanel(); loginPanel.setLayout(new BoxLayout(loginPanel, BoxLayout.Y_AXIS)); JTextField usernameField = new JTextField(15); JPasswordField passwordField = new JPasswordField(15); JButton loginButton = new JButton("Login"); JButton registerButton = new JButton("Register"); loginPanel.add(new JLabel("Username:")); loginPanel.add(usernameField); loginPanel.add(new JLabel("Password:")); loginPanel.add(passwordField); loginPanel.add(loginButton); loginPanel.add(registerButton); loginButton.addActionListener(e -> { String username = usernameField.getText().trim(); String password = new String(passwordField.getPassword()).trim(); if (username.isEmpty() || password.isEmpty()) { JOptionPane.showMessageDialog(frame, "Please enter both username and password.", "Error", JOptionPane.ERROR_MESSAGE); return; } if (login(username, password)) { currentUser = username; loadData(); initialize(); JOptionPane.showMessageDialog(frame, "Login successful!"); frame.setVisible(true); } else { JOptionPane.showMessageDialog(frame, "Invalid credentials", "Error", JOptionPane.ERROR_MESSAGE); } }); registerButton.addActionListener(e -> { String username = usernameField.getText().trim(); String password = new String(passwordField.getPassword()).trim(); if (username.isEmpty() || password.isEmpty()) { JOptionPane.showMessageDialog(frame, "Please enter both username and password.", "Error", JOptionPane.ERROR_MESSAGE); return; } if (register(username, password)) { JOptionPane.showMessageDialog(frame, "Registration successful!"); } else { JOptionPane.showMessageDialog(frame, "Username already taken", "Error", JOptionPane.ERROR_MESSAGE); } }); frame = new JFrame("Login"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(300, 200); frame.add(loginPanel); frame.setLocationRelativeTo(null); // Center the frame on the screen frame.setVisible(true); } private boolean login(String username, String password) { try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user_data.dat"))) { HashMap<String, String> userData = (HashMap<String, String>) ois.readObject(); return userData.containsKey(username) && userData.get(username).equals(password); } catch (IOException | ClassNotFoundException e) { return false; // Error in loading data, assuming user doesn't exist } } private boolean register(String username, String password) { HashMap<String, String> userData; try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user_data.dat"))) { userData = (HashMap<String, String>) ois.readObject(); } catch (IOException | ClassNotFoundException e) { userData = new HashMap<>(); } if (userData.containsKey(username)) { return false; } userData.put(username, password); try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user_data.dat"))) { oos.writeObject(userData); } catch (IOException e) { e.printStackTrace(); } return true; } private void initialize() { frame = new JFrame("Expense Tracker"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(800, 600); tabbedPane = new JTabbedPane(); // Spending Tab JPanel spendingPanel = new JPanel(new BorderLayout()); spendingModel = new DefaultTableModel(new String[]{"Category", "Amount"}, 0); spendingTable = new JTable(spendingModel); updateSpendingTable(); spendingPanel.add(new JScrollPane(spendingTable), BorderLayout.CENTER); JPanel summaryPanel = new JPanel(new GridLayout(5, 1)); totalExpenseLabel = new JLabel(); balanceLabel = new JLabel(); savingsLabel = new JLabel(); JComboBox<String> monthSelector = new JComboBox<>(getMonths()); monthSelector.setSelectedItem(selectedMonth); monthSelector.addActionListener(e -> { selectedMonth = (String) monthSelector.getSelectedItem(); updateSpendingTable(); updateGraph((JPanel) tabbedPane.getComponentAt(1)); // Refresh graph updateTransactionTable(); }); summaryPanel.add(new JLabel("Select Month:")); summaryPanel.add(monthSelector); summaryPanel.add(totalExpenseLabel); summaryPanel.add(balanceLabel); summaryPanel.add(savingsLabel); spendingPanel.add(summaryPanel, BorderLayout.NORTH); JPanel spendingButtons = new JPanel(); JButton addIncomeButton = new JButton("+ Income"); addIncomeButton.addActionListener(e -> addIncome()); JButton addExpenseButton = new JButton("+ Expense"); addExpenseButton.addActionListener(e -> addExpense()); spendingButtons.add(addIncomeButton); spendingButtons.add(addExpenseButton); spendingPanel.add(spendingButtons, BorderLayout.SOUTH); tabbedPane.add("Spending", spendingPanel); // Graph Tab JPanel graphPanel = new JPanel(new BorderLayout()); updateAnnualGraph(graphPanel); // Initial graph update tabbedPane.add("Graph", graphPanel); // Transactions Tab JPanel transactionPanel = new JPanel(new BorderLayout()); transactionModel = new DefaultTableModel(new String[]{"Date", "Category", "Amount"}, 0); transactionTable = new JTable(transactionModel); updateTransactionTable(); transactionPanel.add(new JScrollPane(transactionTable), BorderLayout.CENTER); tabbedPane.add("Transactions", transactionPanel); frame.add(tabbedPane); frame.setVisible(true); } private void addIncome() { String incomeStr = JOptionPane.showInputDialog(frame, "Enter income amount:"); try { double amount = Double.parseDouble(incomeStr); income += amount; updateSummaryLabels(); saveData(); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(frame, "Invalid amount.", "Error", JOptionPane.ERROR_MESSAGE); } } private void addExpense() { String category = JOptionPane.showInputDialog(frame, "Enter category:"); String amountStr = JOptionPane.showInputDialog(frame, "Enter amount:"); try { double amount = Double.parseDouble(amountStr); HashMap<String, Double> monthData = monthlySpendingData.getOrDefault(selectedMonth, new HashMap<>()); monthData.put(category, monthData.getOrDefault(category, 0.0) + amount); monthlySpendingData.put(selectedMonth, monthData); updateSpendingTable(); updateSummaryLabels(); saveData(); updateGraph((JPanel) tabbedPane.getComponentAt(1)); // Automatically refresh graph addTransaction(category, amount); } catch (NumberFormatException ex) { JOptionPane.showMessageDialog(frame, "Invalid amount.", "Error", JOptionPane.ERROR_MESSAGE); } } private void updateSpendingTable() { spendingModel.setRowCount(0); HashMap<String, Double> monthData = monthlySpendingData.getOrDefault(selectedMonth, new HashMap<>()); for (Map.Entry<String, Double> entry : monthData.entrySet()) { spendingModel.addRow(new Object[]{entry.getKey(), entry.getValue()}); } } private void updateGraph(JPanel graphPanel) { DefaultPieDataset dataset = new DefaultPieDataset(); HashMap<String, Double> monthData = monthlySpendingData.getOrDefault(selectedMonth, new HashMap<>()); for (Map.Entry<String, Double> entry : monthData.entrySet()) { dataset.setValue(entry.getKey(), entry.getValue()); } JFreeChart chart = ChartFactory.createPieChart(selectedMonth + " Spending", dataset, true, true, false); ChartPanel chartPanel = new ChartPanel(chart); graphPanel.removeAll(); graphPanel.add(chartPanel, BorderLayout.CENTER); graphPanel.revalidate(); graphPanel.repaint(); } private void updateAnnualGraph(JPanel graphPanel) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); for (String month : getMonths()) { HashMap<String, Double> monthData = monthlySpendingData.getOrDefault(month, new HashMap<>()); double totalMonthSpending = monthData.values().stream().mapToDouble(Double::doubleValue).sum(); dataset.addValue(totalMonthSpending, "Expense", month); } JFreeChart chart = ChartFactory.createBarChart("Annual Spending", "Month", "Amount", dataset); ChartPanel chartPanel = new ChartPanel(chart); graphPanel.removeAll(); graphPanel.add(chartPanel, BorderLayout.CENTER); graphPanel.revalidate(); graphPanel.repaint(); } private void addTransaction(String category, double amount) { String date = new Date().toString(); transactionHistory.add(new Object[]{date, category, amount}); updateTransactionTable(); } private void updateTransactionTable() { transactionModel.setRowCount(0); for (Object[] transaction : transactionHistory) { transactionModel.addRow(transaction); } } private void updateSummaryLabels() { DecimalFormat df = new DecimalFormat("0.00"); double totalExpense = monthlySpendingData.getOrDefault(selectedMonth, new HashMap<>()).values().stream().mapToDouble(Double::doubleValue).sum(); double balance = income - totalExpense; totalExpenseLabel.setText("Total Expense: ৳" + df.format(totalExpense)); balanceLabel.setText("Balance: ৳" + df.format(balance)); } private void saveData() { String dataFileName = DATA_FILE_PREFIX + currentUser + ".dat"; try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(dataFileName))) { oos.writeObject(monthlySpendingData); oos.writeDouble(income); } catch (IOException e) { e.printStackTrace(); } } private void loadData() { String dataFileName = DATA_FILE_PREFIX + currentUser + ".dat"; try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(dataFileName))) { monthlySpendingData = (HashMap<String, HashMap<String, Double>>) ois.readObject(); income = ois.readDouble(); updateSummaryLabels(); } catch (IOException | ClassNotFoundException e) { monthlySpendingData = new HashMap<>(); income = 0.0; } } private String[] getMonths() { return new String[]{"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"}; } public static void main(String[] args) { SwingUtilities.invokeLater(ExpenseTracker::new); } }
Editor is loading...
Leave a Comment