Explorar o código

Less mutable state and more Java 8 ::-notation.

Tankernn %!s(int64=8) %!d(string=hai) anos
pai
achega
482d3a2614

+ 6 - 24
src/main/java/eu/tankernn/accounts/Account.java

@@ -4,17 +4,16 @@ import java.math.BigInteger;
 import java.security.SecureRandom;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.stream.Stream;
 
 public class Account {
 
-	private String firstName, lastName, accountNumber;
-	private List<AccountEvent> history;
+	public final String firstName, lastName, accountNumber;
+	public final List<AccountEvent> history;
 
 	public Account(String firstName, String lastName) {
 		// Generate a random, unique account id
-		do {
-			accountNumber = new BigInteger(20, new SecureRandom()).toString();
-		} while (AccountManager.getAccountByNumber(accountNumber).isPresent());
+		accountNumber = Stream.generate(() -> new BigInteger(20, new SecureRandom()).toString()).limit(AccountManager.getAccounts().size() + 1).filter(num -> AccountManager.getAccountByNumber(num).isPresent()).findFirst().orElseThrow(() -> new ArrayIndexOutOfBoundsException());
 		this.firstName = firstName;
 		this.lastName = lastName;
 		this.history = new ArrayList<AccountEvent>();
@@ -27,29 +26,12 @@ public class Account {
 		this.history = history;
 	}
 
-	public String getFirstName() {
-		return firstName;
-	}
-
-	public String getLastName() {
-		return lastName;
-	}
-
-	public List<AccountEvent> getHistory() {
-		return history;
-	}
-
-	public String getAccountNumber() {
-		return accountNumber;
-	}
-
 	@Override
 	public boolean equals(Object obj) {
 		if (!(obj instanceof Account))
 			return false;
 		Account other = (Account) obj;
-		return firstName.equals(other.firstName) && lastName.equals(other.lastName)
-				&& accountNumber.equals(other.accountNumber);
+		return firstName.equals(other.firstName) && lastName.equals(other.lastName) && accountNumber.equals(other.accountNumber);
 	}
 
 	public String toString() {
@@ -57,7 +39,7 @@ public class Account {
 	}
 
 	public double calculateBalance() {
-		return history.stream().mapToDouble(a -> a.getBalanceChange()).sum();
+		return history.stream().mapToDouble(a -> a.balanceChange).sum();
 	}
 
 }

+ 31 - 39
src/main/java/eu/tankernn/accounts/AccountEvent.java

@@ -1,39 +1,31 @@
-package eu.tankernn.accounts;
-
-/**
- * Describes an event in an account's history.
- * 
- * @author frans
- *
- */
-public class AccountEvent {
-
-	private final double balanceChange;
-	private final String description;
-
-	/**
-	 * Creates a new account event.
-	 * 
-	 * @param balanceChange The change in account balance.
-	 * @param descriptionFormat
-	 *            A string that will be used for a <code>String.format()</code>
-	 *            call, along with the absolute balance change value.
-	 */
-	public AccountEvent(double balanceChange, String descriptionFormat) {
-		this.balanceChange = balanceChange;
-		this.description = String.format(descriptionFormat, Math.abs(balanceChange));
-	}
-
-	public double getBalanceChange() {
-		return balanceChange;
-	}
-
-	public String getDescription() {
-		return description;
-	}
-
-	public String toString() {
-		return description;
-	}
-
-}
+package eu.tankernn.accounts;
+
+/**
+ * Describes an event in an account's history.
+ * 
+ * @author frans
+ *
+ */
+public class AccountEvent {
+
+	public final double balanceChange;
+	public final String description;
+
+	/**
+	 * Creates a new account event.
+	 * 
+	 * @param balanceChange The change in account balance.
+	 * @param descriptionFormat
+	 *            A string that will be used for a <code>String.format()</code>
+	 *            call, along with the absolute balance change value.
+	 */
+	public AccountEvent(double balanceChange, String descriptionFormat) {
+		this.balanceChange = balanceChange;
+		this.description = String.format(descriptionFormat, Math.abs(balanceChange));
+	}
+
+	public String toString() {
+		return description;
+	}
+
+}

+ 2 - 2
src/main/java/eu/tankernn/accounts/AccountManager.java

@@ -175,7 +175,7 @@ public class AccountManager {
 	 * @return The list of matching accounts
 	 */
 	public static List<Account> search(String s) {
-		return accounts.stream().filter(a -> a.getAccountNumber().toLowerCase().contains(s.toLowerCase())
+		return accounts.stream().filter(a -> a.accountNumber.toLowerCase().contains(s.toLowerCase())
 				|| a.toString().toLowerCase().contains(s.toLowerCase())).collect(Collectors.toList());
 
 	}
@@ -191,7 +191,7 @@ public class AccountManager {
 	 * @return The account, if it was found
 	 */
 	public static Optional<Account> getAccountByNumber(String accountNumber) {
-		return accounts.stream().filter(a -> a.getAccountNumber().equals(accountNumber)).findFirst();
+		return accounts.stream().filter(accountNumber::equals).findFirst();
 	}
 
 	public static boolean isSavingWithEncryption() {

+ 118 - 118
src/main/java/eu/tankernn/accounts/DBManager.java

@@ -1,118 +1,118 @@
-package eu.tankernn.accounts;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.List;
-
-public class DBManager {
-	// JDBC driver name and database URL
-	private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
-	private static final String DB_URL = "jdbc:mysql://localhost/AccountManager";
-
-	// Database credentials
-	private static final String USER = "root";
-	private static final String PASS = "password";
-
-	private static Connection conn = null;
-	private static Statement stmt = null;
-
-	public static void init() {
-		if (inited()) // Already inited
-			return;
-		try {
-			Class.forName(JDBC_DRIVER);
-			conn = DriverManager.getConnection(DB_URL, USER, PASS);
-
-			// Check if table exists and create it otherwise
-			stmt = conn.createStatement();
-			conn.createStatement().executeUpdate(
-					"CREATE TABLE IF NOT EXISTS Accounts (FirstName varchar(255), LastName varchar(255), AccountNumber varchar(30) NOT NULL UNIQUE, PRIMARY KEY (AccountNumber))");
-			conn.createStatement().executeUpdate(
-					"CREATE TABLE IF NOT EXISTS Events (uid int AUTO_INCREMENT UNIQUE, account varchar(255), balanceChange double, description varchar(512), PRIMARY KEY (uid))");
-		} catch (SQLException | ClassNotFoundException e) {
-			e.printStackTrace();
-			return;
-		}
-	}
-
-	public static void saveAccounts(List<Account> accounts) {
-		try {
-			conn.createStatement().executeUpdate("DELETE FROM Events");
-		} catch (SQLException e1) {
-			e1.printStackTrace();
-		}
-		for (Account a : accounts) {
-			try {
-				PreparedStatement ps = conn.prepareStatement(
-						"INSERT IGNORE INTO Accounts (firstName, lastName, accountNumber) VALUES (?, ?, ?)");
-				ps.setString(1, a.getFirstName());
-				ps.setString(2, a.getLastName());
-				ps.setString(3, a.getAccountNumber());
-				saveAccountEvents(a.getAccountNumber(), a.getHistory());
-				ps.executeUpdate();
-			} catch (SQLException e) {
-				e.printStackTrace();
-			}
-		}
-	}
-
-	private static List<AccountEvent> getAccountEvents(String accountNumber) {
-		try {
-			PreparedStatement ps = conn.prepareStatement("SELECT * FROM Events WHERE account=?");
-			ps.setString(1, accountNumber);
-			ResultSet set = ps.executeQuery();
-			List<AccountEvent> events = new ArrayList<AccountEvent>();
-			while (set.next()) {
-				events.add(new AccountEvent(set.getDouble("balanceChange"), set.getString("description")));
-			}
-			return events;
-		} catch (SQLException e) {
-			e.printStackTrace();
-		}
-		return null;
-	}
-
-	private static void saveAccountEvents(String accountNumber, List<AccountEvent> events) {
-		for (AccountEvent e : events)
-			try {
-				PreparedStatement ps = conn.prepareStatement(
-						"INSERT INTO Events (account, balanceChange, description) VALUES (?, ?, ?)");
-				ps.setString(1, accountNumber);
-				ps.setDouble(2, e.getBalanceChange());
-				ps.setString(3, e.getDescription());
-				ps.executeUpdate();
-			} catch (SQLException ex) {
-				ex.printStackTrace();
-			}
-	}
-
-	private static Account accountFromResultSet(ResultSet set) throws SQLException {
-		String num = set.getString("accountNumber");
-		return new Account(set.getString("firstName"), set.getString("lastName"), num, getAccountEvents(num));
-	}
-
-	public static List<Account> readAccounts() {
-		List<Account> accounts = new ArrayList<Account>();
-		try {
-			stmt = conn.createStatement();
-			stmt.executeQuery("SELECT * FROM Accounts");
-			ResultSet set = stmt.getResultSet();
-			while (set.next()) {
-				accounts.add(accountFromResultSet(set));
-			}
-
-		} catch (SQLException e) {
-			e.printStackTrace();
-		}
-		return accounts;
-	}
-
-	public static boolean inited() {
-		return conn != null;
-	}
-}
+package eu.tankernn.accounts;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+public class DBManager {
+	// JDBC driver name and database URL
+	private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
+	private static final String DB_URL = "jdbc:mysql://localhost/AccountManager";
+
+	// Database credentials
+	private static final String USER = "root";
+	private static final String PASS = "password";
+
+	private static Connection conn = null;
+	private static Statement stmt = null;
+
+	public static void init() {
+		if (inited()) // Already inited
+			return;
+		try {
+			Class.forName(JDBC_DRIVER);
+			conn = DriverManager.getConnection(DB_URL, USER, PASS);
+
+			// Check if table exists and create it otherwise
+			stmt = conn.createStatement();
+			conn.createStatement().executeUpdate(
+					"CREATE TABLE IF NOT EXISTS Accounts (FirstName varchar(255), LastName varchar(255), AccountNumber varchar(30) NOT NULL UNIQUE, PRIMARY KEY (AccountNumber))");
+			conn.createStatement().executeUpdate(
+					"CREATE TABLE IF NOT EXISTS Events (uid int AUTO_INCREMENT UNIQUE, account varchar(255), balanceChange double, description varchar(512), PRIMARY KEY (uid))");
+		} catch (SQLException | ClassNotFoundException e) {
+			e.printStackTrace();
+			return;
+		}
+	}
+
+	public static void saveAccounts(List<Account> accounts) {
+		try {
+			conn.createStatement().executeUpdate("DELETE FROM Events");
+		} catch (SQLException e1) {
+			e1.printStackTrace();
+		}
+		for (Account a : accounts) {
+			try {
+				PreparedStatement ps = conn.prepareStatement(
+						"INSERT IGNORE INTO Accounts (firstName, lastName, accountNumber) VALUES (?, ?, ?)");
+				ps.setString(1, a.firstName);
+				ps.setString(2, a.lastName);
+				ps.setString(3, a.accountNumber);
+				saveAccountEvents(a.accountNumber, a.history);
+				ps.executeUpdate();
+			} catch (SQLException e) {
+				e.printStackTrace();
+			}
+		}
+	}
+
+	private static List<AccountEvent> getAccountEvents(String accountNumber) {
+		try {
+			PreparedStatement ps = conn.prepareStatement("SELECT * FROM Events WHERE account=?");
+			ps.setString(1, accountNumber);
+			ResultSet set = ps.executeQuery();
+			List<AccountEvent> events = new ArrayList<AccountEvent>();
+			while (set.next()) {
+				events.add(new AccountEvent(set.getDouble("balanceChange"), set.getString("description")));
+			}
+			return events;
+		} catch (SQLException e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+	private static void saveAccountEvents(String accountNumber, List<AccountEvent> events) {
+		for (AccountEvent e : events)
+			try {
+				PreparedStatement ps = conn.prepareStatement(
+						"INSERT INTO Events (account, balanceChange, description) VALUES (?, ?, ?)");
+				ps.setString(1, accountNumber);
+				ps.setDouble(2, e.balanceChange);
+				ps.setString(3, e.description);
+				ps.executeUpdate();
+			} catch (SQLException ex) {
+				ex.printStackTrace();
+			}
+	}
+
+	private static Account accountFromResultSet(ResultSet set) throws SQLException {
+		String num = set.getString("accountNumber");
+		return new Account(set.getString("firstName"), set.getString("lastName"), num, getAccountEvents(num));
+	}
+
+	public static List<Account> readAccounts() {
+		List<Account> accounts = new ArrayList<Account>();
+		try {
+			stmt = conn.createStatement();
+			stmt.executeQuery("SELECT * FROM Accounts");
+			ResultSet set = stmt.getResultSet();
+			while (set.next()) {
+				accounts.add(accountFromResultSet(set));
+			}
+
+		} catch (SQLException e) {
+			e.printStackTrace();
+		}
+		return accounts;
+	}
+
+	public static boolean inited() {
+		return conn != null;
+	}
+}

+ 180 - 180
src/main/java/eu/tankernn/accounts/frame/AccountPanel.java

@@ -1,180 +1,180 @@
-package eu.tankernn.accounts.frame;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.GridLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.DefaultListModel;
-import javax.swing.JButton;
-import javax.swing.JComboBox;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.border.TitledBorder;
-
-import eu.tankernn.accounts.Account;
-import eu.tankernn.accounts.AccountEvent;
-import eu.tankernn.accounts.AccountManager;
-import eu.tankernn.accounts.util.GUIUtils;
-
-public class AccountPanel extends JPanel implements ActionListener {
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 1L;
-
-	private Account currentAccount;
-
-	private DecimalFormat format;
-
-	private JPanel infoPanel = new JPanel();
-	private JLabel lName = new JLabel("Name: "), lBalance = new JLabel("Balance: "),
-			lAccountNumber = new JLabel("Account number: ");
-	private JButton transferFrom = new JButton("Transfer from this account..."),
-			deposit = new JButton("Deposit to this account..."),
-			withdraw = new JButton("Withdraw from this account...");
-
-	private JList<AccountEvent> history = new JList<AccountEvent>();
-	private JScrollPane scrollPane = new JScrollPane(history);
-
-	private JComboBox<Account> otherAccounts = new JComboBox<Account>();
-
-	/**
-	 * Create the panel.
-	 */
-	public AccountPanel() {
-		this.setLayout(new BorderLayout());
-
-		format = new DecimalFormat("### ##0.00");
-		format.setGroupingUsed(true);
-		format.setGroupingSize(3);
-
-		infoPanel.setLayout(new GridLayout(6, 1));
-		add(infoPanel, BorderLayout.WEST);
-		infoPanel.add(lName);
-		infoPanel.add(lBalance);
-		infoPanel.add(lAccountNumber);
-
-		infoPanel.add(transferFrom);
-		infoPanel.add(deposit);
-		infoPanel.add(withdraw);
-
-		transferFrom.addActionListener(this);
-		deposit.addActionListener(this);
-		withdraw.addActionListener(this);
-
-		add(scrollPane, BorderLayout.EAST);
-
-		this.setBorder(new TitledBorder("Account panel"));
-	}
-
-	public void updatePanel(Account a) {
-		this.currentAccount = a;
-
-		if (a == null) {
-			lName.setText("Name: ");
-			lBalance.setText("Balance: ");
-			lAccountNumber.setText("Account number: ");
-			history.setModel(new DefaultListModel<AccountEvent>());
-
-			transferFrom.setEnabled(false);
-			deposit.setEnabled(false);
-			withdraw.setEnabled(false);
-		} else {
-			lName.setText("Name: " + a.toString());
-			lBalance.setText("Balance: " + AccountManager.CURRENCY + " " + format.format(a.calculateBalance()));
-			lAccountNumber.setText("Account number: " + a.getAccountNumber());
-			history.setModel(GUIUtils.listModelFromList(a.getHistory()));
-
-			// "Clone" account list
-			List<Account> accounts = new ArrayList<Account>(AccountManager.getAccounts());
-			// Can't transfer to self
-			accounts.remove(a);
-			otherAccounts.setModel(GUIUtils.comboBoxModelFromList(accounts));
-
-			transferFrom.setEnabled(true);
-			deposit.setEnabled(true);
-			withdraw.setEnabled(true);
-		}
-
-		// Fix history list width.
-		Dimension d = scrollPane.getPreferredSize();
-		d.width = infoPanel.getWidth(); // Same as infopanel
-		scrollPane.setPreferredSize(d);
-	}
-
-	@Override
-	public void actionPerformed(ActionEvent e) {
-		Object src = e.getSource();
-
-		if (src.equals(transferFrom)) {
-			double amount = showAmountDialog("transfer");
-
-			if (amount <= 0) {
-				return;
-			} else if (amount > currentAccount.calculateBalance()) {
-				JOptionPane.showMessageDialog(null, "Invalid amount.");
-				return;
-			}
-
-			int result = JOptionPane.showConfirmDialog(null,
-					new JComponent[] { new JLabel("Please select receiver account."), otherAccounts },
-					"Select account.", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
-			
-			if (result != JOptionPane.OK_OPTION)
-				return;
-			
-			Account sender = currentAccount, receiver = (Account) otherAccounts.getSelectedItem();
-
-			sender.getHistory().add(new AccountEvent(-amount, "Transferred %.2f to " + receiver + "."));
-			receiver.getHistory().add(new AccountEvent(amount, "Received %.2f from " + sender + "."));
-		} else if (src.equals(deposit)) {
-			double amount = showAmountDialog("deposit");
-
-			if (amount < 0) {
-				JOptionPane.showMessageDialog(this, "Please enter a positive value.");
-				return;
-			}
-
-			currentAccount.getHistory().add(new AccountEvent(amount, "User deposited %.2f."));
-		} else if (src.equals(withdraw)) {
-			double amount = showAmountDialog("withdraw");
-
-			if (amount < 0) {
-				JOptionPane.showMessageDialog(this, "Please enter a positive value.");
-				return;
-			} else if (amount > currentAccount.calculateBalance()) {
-				JOptionPane.showMessageDialog(this, "You do not have enough balance to withdraw that amount.");
-				return;
-			}
-
-			currentAccount.getHistory().add(new AccountEvent(-amount, "User withdrew %.2f."));
-		}
-
-		this.updatePanel(currentAccount);
-	}
-
-	private double showAmountDialog(String action) {
-		String amountStr;
-		double amount = -1;
-		while (amount == -1)
-			try {
-				amountStr = JOptionPane.showInputDialog("Amount to " + action + ":");
-				amount = Double.parseDouble(amountStr);
-			} catch (NumberFormatException ex) {
-				JOptionPane.showMessageDialog(null, "Please enter a valid number value.");
-			} catch (NullPointerException ex) {
-				break;
-			}
-		return amount;
-	}
-}
+package eu.tankernn.accounts.frame;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.border.TitledBorder;
+
+import eu.tankernn.accounts.Account;
+import eu.tankernn.accounts.AccountEvent;
+import eu.tankernn.accounts.AccountManager;
+import eu.tankernn.accounts.util.GUIUtils;
+
+public class AccountPanel extends JPanel implements ActionListener {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private Account currentAccount;
+
+	private DecimalFormat format;
+
+	private JPanel infoPanel = new JPanel();
+	private JLabel lName = new JLabel("Name: "), lBalance = new JLabel("Balance: "),
+			lAccountNumber = new JLabel("Account number: ");
+	private JButton transferFrom = new JButton("Transfer from this account..."),
+			deposit = new JButton("Deposit to this account..."),
+			withdraw = new JButton("Withdraw from this account...");
+
+	private JList<AccountEvent> history = new JList<AccountEvent>();
+	private JScrollPane scrollPane = new JScrollPane(history);
+
+	private JComboBox<Account> otherAccounts = new JComboBox<Account>();
+
+	/**
+	 * Create the panel.
+	 */
+	public AccountPanel() {
+		this.setLayout(new BorderLayout());
+
+		format = new DecimalFormat("### ##0.00");
+		format.setGroupingUsed(true);
+		format.setGroupingSize(3);
+
+		infoPanel.setLayout(new GridLayout(6, 1));
+		add(infoPanel, BorderLayout.WEST);
+		infoPanel.add(lName);
+		infoPanel.add(lBalance);
+		infoPanel.add(lAccountNumber);
+
+		infoPanel.add(transferFrom);
+		infoPanel.add(deposit);
+		infoPanel.add(withdraw);
+
+		transferFrom.addActionListener(this);
+		deposit.addActionListener(this);
+		withdraw.addActionListener(this);
+
+		add(scrollPane, BorderLayout.EAST);
+
+		this.setBorder(new TitledBorder("Account panel"));
+	}
+
+	public void updatePanel(Account a) {
+		this.currentAccount = a;
+
+		if (a == null) {
+			lName.setText("Name: ");
+			lBalance.setText("Balance: ");
+			lAccountNumber.setText("Account number: ");
+			history.setModel(new DefaultListModel<AccountEvent>());
+
+			transferFrom.setEnabled(false);
+			deposit.setEnabled(false);
+			withdraw.setEnabled(false);
+		} else {
+			lName.setText("Name: " + a.toString());
+			lBalance.setText("Balance: " + AccountManager.CURRENCY + " " + format.format(a.calculateBalance()));
+			lAccountNumber.setText("Account number: " + a.accountNumber);
+			history.setModel(GUIUtils.listModelFromList(a.history));
+
+			// "Clone" account list
+			List<Account> accounts = new ArrayList<Account>(AccountManager.getAccounts());
+			// Can't transfer to self
+			accounts.remove(a);
+			otherAccounts.setModel(GUIUtils.comboBoxModelFromList(accounts));
+
+			transferFrom.setEnabled(true);
+			deposit.setEnabled(true);
+			withdraw.setEnabled(true);
+		}
+
+		// Fix history list width.
+		Dimension d = scrollPane.getPreferredSize();
+		d.width = infoPanel.getWidth(); // Same as infopanel
+		scrollPane.setPreferredSize(d);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		Object src = e.getSource();
+
+		if (src.equals(transferFrom)) {
+			double amount = showAmountDialog("transfer");
+
+			if (amount <= 0) {
+				return;
+			} else if (amount > currentAccount.calculateBalance()) {
+				JOptionPane.showMessageDialog(null, "Invalid amount.");
+				return;
+			}
+
+			int result = JOptionPane.showConfirmDialog(null,
+					new JComponent[] { new JLabel("Please select receiver account."), otherAccounts },
+					"Select account.", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
+			
+			if (result != JOptionPane.OK_OPTION)
+				return;
+			
+			Account sender = currentAccount, receiver = (Account) otherAccounts.getSelectedItem();
+
+			sender.history.add(new AccountEvent(-amount, "Transferred %.2f to " + receiver + "."));
+			receiver.history.add(new AccountEvent(amount, "Received %.2f from " + sender + "."));
+		} else if (src.equals(deposit)) {
+			double amount = showAmountDialog("deposit");
+
+			if (amount < 0) {
+				JOptionPane.showMessageDialog(this, "Please enter a positive value.");
+				return;
+			}
+
+			currentAccount.history.add(new AccountEvent(amount, "User deposited %.2f."));
+		} else if (src.equals(withdraw)) {
+			double amount = showAmountDialog("withdraw");
+
+			if (amount < 0) {
+				JOptionPane.showMessageDialog(this, "Please enter a positive value.");
+				return;
+			} else if (amount > currentAccount.calculateBalance()) {
+				JOptionPane.showMessageDialog(this, "You do not have enough balance to withdraw that amount.");
+				return;
+			}
+
+			currentAccount.history.add(new AccountEvent(-amount, "User withdrew %.2f."));
+		}
+
+		this.updatePanel(currentAccount);
+	}
+
+	private double showAmountDialog(String action) {
+		String amountStr;
+		double amount = -1;
+		while (amount == -1)
+			try {
+				amountStr = JOptionPane.showInputDialog("Amount to " + action + ":");
+				amount = Double.parseDouble(amountStr);
+			} catch (NumberFormatException ex) {
+				JOptionPane.showMessageDialog(null, "Please enter a valid number value.");
+			} catch (NullPointerException ex) {
+				break;
+			}
+		return amount;
+	}
+}

+ 21 - 21
src/main/java/eu/tankernn/accounts/util/GUIUtils.java

@@ -1,21 +1,21 @@
-package eu.tankernn.accounts.util;
-
-import java.util.List;
-
-import javax.swing.ComboBoxModel;
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.DefaultListModel;
-
-public class GUIUtils {
-	public static <T> DefaultListModel<T> listModelFromList(List<T> list) {
-		DefaultListModel<T> model = new DefaultListModel<T>();
-		list.forEach(t -> model.addElement(t));
-		return model;
-	}
-	
-	public static <T> ComboBoxModel<T> comboBoxModelFromList(List<T> list) {
-		DefaultComboBoxModel<T> model = new DefaultComboBoxModel<T>();
-		list.forEach(t -> model.addElement(t));
-		return model;
-	}
-}
+package eu.tankernn.accounts.util;
+
+import java.util.List;
+
+import javax.swing.ComboBoxModel;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.DefaultListModel;
+
+public class GUIUtils {
+	public static <T> DefaultListModel<T> listModelFromList(List<T> list) {
+		DefaultListModel<T> model = new DefaultListModel<T>();
+		list.forEach(model::addElement);
+		return model;
+	}
+	
+	public static <T> ComboBoxModel<T> comboBoxModelFromList(List<T> list) {
+		DefaultComboBoxModel<T> model = new DefaultComboBoxModel<T>();
+		list.forEach(model::addElement);
+		return model;
+	}
+}

+ 4 - 4
src/test/java/eu/tankernn/accounts/test/AccountManagerTest.java

@@ -25,9 +25,9 @@ public class AccountManagerTest {
 	public void testSearch() {
 		List<Account> aList = new ArrayList<>();
 		aList.add(a);
-		Assert.assertEquals(aList, AccountManager.search(a.getAccountNumber()));
-		Assert.assertEquals(aList, AccountManager.search(a.getFirstName()));
-		Assert.assertEquals(aList, AccountManager.search(a.getLastName()));
-		Assert.assertEquals(a, AccountManager.getAccountByNumber(a.getAccountNumber()));
+		Assert.assertEquals(aList, AccountManager.search(a.accountNumber));
+		Assert.assertEquals(aList, AccountManager.search(a.firstName));
+		Assert.assertEquals(aList, AccountManager.search(a.lastName));
+		Assert.assertEquals(a, AccountManager.getAccountByNumber(a.accountNumber));
 	}
 }