java 3
unknown
plain_text
9 months ago
13 kB
6
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