Kr Younger пре 6 година
комит
9ee2dd9060

+ 24
- 0
.gitignore Прегледај датотеку

@@ -0,0 +1,24 @@
1
+*.class
2
+
3
+# Package Files #
4
+*.war
5
+*.ear
6
+
7
+# Eclipse #
8
+.classpath
9
+.project
10
+.settings/
11
+bin/
12
+
13
+# IDEA #
14
+.idea/
15
+*.iml
16
+out/
17
+
18
+# Maven #
19
+dependency-reduced-pom.xml
20
+target/
21
+
22
+# logs #
23
+*.log
24
+logs/

+ 26
- 0
.vscode/launch.json Прегледај датотеку

@@ -0,0 +1,26 @@
1
+{
2
+    "configurations": [
3
+        {
4
+            "type": "java",
5
+            "name": "CodeLens (Launch) - CashMachineApp",
6
+            "request": "launch",
7
+            "cwd": "${workspaceFolder}",
8
+            "console": "internalConsole",
9
+            "stopOnEntry": false,
10
+            "mainClass": "rocks.zipcode.atm.CashMachineApp",
11
+            "args": "",
12
+            "projectName": "CashMachine"
13
+        },
14
+        {
15
+            "type": "java",
16
+            "name": "CodeLens (Launch) - CashMachineApp",
17
+            "request": "launch",
18
+            "cwd": "${workspaceFolder}",
19
+            "console": "internalConsole",
20
+            "stopOnEntry": false,
21
+            "mainClass": "com.almasb.atm.CashMachineApp",
22
+            "args": "",
23
+            "projectName": "CashMachine"
24
+        }
25
+    ]
26
+}

+ 18
- 0
Account.ctxt Прегледај датотеку

@@ -0,0 +1,18 @@
1
+#BlueJ class context
2
+comment0.target=Account
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+comment1.params=accountData
5
+comment1.target=Account(AccountData)
6
+comment2.params=
7
+comment2.target=AccountData\ getAccountData()
8
+comment3.params=amount
9
+comment3.target=void\ deposit(int)
10
+comment4.params=amount
11
+comment4.target=boolean\ withdraw(int)
12
+comment5.params=amount
13
+comment5.target=boolean\ canWithdraw(int)
14
+comment6.params=
15
+comment6.target=int\ getBalance()
16
+comment7.params=newBalance
17
+comment7.target=void\ updateBalance(int)
18
+numComments=8

+ 43
- 0
Account.java Прегледај датотеку

@@ -0,0 +1,43 @@
1
+ 
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public abstract class Account {
7
+
8
+    private AccountData accountData;
9
+
10
+    public Account(AccountData accountData) {
11
+        this.accountData = accountData;
12
+    }
13
+
14
+    public AccountData getAccountData() {
15
+        return accountData;
16
+    }
17
+
18
+    public void deposit(int amount) {
19
+        updateBalance(getBalance() + amount);
20
+    }
21
+
22
+    public boolean withdraw(int amount) {
23
+        if (canWithdraw(amount)) {
24
+            updateBalance(getBalance() - amount);
25
+            return true;
26
+        } else {
27
+            return false;
28
+        }
29
+    }
30
+
31
+    protected boolean canWithdraw(int amount) {
32
+        return getBalance() >= amount;
33
+    }
34
+
35
+    public int getBalance() {
36
+        return accountData.getBalance();
37
+    }
38
+
39
+    private void updateBalance(int newBalance) {
40
+        accountData = new AccountData(accountData.getId(), accountData.getName(), accountData.getEmail(),
41
+                newBalance);
42
+    }
43
+}

+ 16
- 0
AccountData.ctxt Прегледај датотеку

@@ -0,0 +1,16 @@
1
+#BlueJ class context
2
+comment0.target=AccountData
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+comment1.params=id\ name\ email\ balance
5
+comment1.target=AccountData(int,\ java.lang.String,\ java.lang.String,\ int)
6
+comment2.params=
7
+comment2.target=int\ getId()
8
+comment3.params=
9
+comment3.target=java.lang.String\ getName()
10
+comment4.params=
11
+comment4.target=java.lang.String\ getEmail()
12
+comment5.params=
13
+comment5.target=int\ getBalance()
14
+comment6.params=
15
+comment6.target=java.lang.String\ toString()
16
+numComments=7

+ 44
- 0
AccountData.java Прегледај датотеку

@@ -0,0 +1,44 @@
1
+ 
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public final class AccountData {
7
+
8
+    private final int id;
9
+    private final String name;
10
+    private final String email;
11
+
12
+    private final int balance;
13
+
14
+    AccountData(int id, String name, String email, int balance) {
15
+        this.id = id;
16
+        this.name = name;
17
+        this.email = email;
18
+        this.balance = balance;
19
+    }
20
+
21
+    public int getId() {
22
+        return id;
23
+    }
24
+
25
+    public String getName() {
26
+        return name;
27
+    }
28
+
29
+    public String getEmail() {
30
+        return email;
31
+    }
32
+
33
+    public int getBalance() {
34
+        return balance;
35
+    }
36
+
37
+    @Override
38
+    public String toString() {
39
+        return "Account id: " + id + '\n' +
40
+                "Name: " + name + '\n' +
41
+                "Email: " + email + '\n' +
42
+                "Balance: " + balance;
43
+    }
44
+}

+ 18
- 0
ActionResult.ctxt Прегледај датотеку

@@ -0,0 +1,18 @@
1
+#BlueJ class context
2
+comment0.target=ActionResult
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+comment1.params=data
5
+comment1.target=ActionResult(java.lang.Object)
6
+comment2.params=errorMessage
7
+comment2.target=ActionResult(java.lang.String)
8
+comment3.params=
9
+comment3.target=java.lang.Object\ getData()
10
+comment4.params=
11
+comment4.target=java.lang.String\ getErrorMessage()
12
+comment5.params=
13
+comment5.target=boolean\ isSuccess()
14
+comment6.params=data
15
+comment6.target=rocks.zipcode.atm.ActionResult\ success(java.lang.Object)
16
+comment7.params=errorMessage
17
+comment7.target=rocks.zipcode.atm.ActionResult\ fail(java.lang.String)
18
+numComments=8

+ 38
- 0
ActionResult.java Прегледај датотеку

@@ -0,0 +1,38 @@
1
+ 
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public class ActionResult<T> {
7
+
8
+    private T data;
9
+    private String errorMessage;
10
+
11
+    private ActionResult(T data) {
12
+        this.data = data;
13
+    }
14
+
15
+    private ActionResult(String errorMessage) {
16
+        this.errorMessage = errorMessage;
17
+    }
18
+
19
+    public T getData() {
20
+        return data;
21
+    }
22
+
23
+    public String getErrorMessage() {
24
+        return errorMessage;
25
+    }
26
+
27
+    public boolean isSuccess() {
28
+        return data != null;
29
+    }
30
+
31
+    public static <E> ActionResult<E> success(E data) {
32
+        return new ActionResult<E>(data);
33
+    }
34
+
35
+    public static <E> ActionResult<E> fail(String errorMessage) {
36
+        return new ActionResult<E>(errorMessage);
37
+    }
38
+}

+ 12
- 0
Bank.ctxt Прегледај датотеку

@@ -0,0 +1,12 @@
1
+#BlueJ class context
2
+comment0.target=Bank
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+comment1.params=
5
+comment1.target=Bank()
6
+comment2.params=id
7
+comment2.target=ActionResult\ getAccountById(int)
8
+comment3.params=accountData\ amount
9
+comment3.target=ActionResult\ deposit(AccountData,\ int)
10
+comment4.params=accountData\ amount
11
+comment4.target=ActionResult\ withdraw(AccountData,\ int)
12
+numComments=5

+ 52
- 0
Bank.java Прегледај датотеку

@@ -0,0 +1,52 @@
1
+ 
2
+
3
+//import rocks.zipcode.atm.ActionResult;
4
+
5
+import java.util.HashMap;
6
+import java.util.Map;
7
+
8
+/**
9
+ * @author ZipCodeWilmington
10
+ */
11
+public class Bank {
12
+
13
+    private Map<Integer, Account> accounts = new HashMap<>();
14
+
15
+    public Bank() {
16
+        accounts.put(1000, new BasicAccount(new AccountData(
17
+                1000, "Example 1", "example1@gmail.com", 500
18
+        )));
19
+
20
+        accounts.put(2000, new PremiumAccount(new AccountData(
21
+                2000, "Example 2", "example2@gmail.com", 200
22
+        )));
23
+    }
24
+
25
+    public ActionResult<AccountData> getAccountById(int id) {
26
+        Account account = accounts.get(id);
27
+
28
+        if (account != null) {
29
+            return ActionResult.success(account.getAccountData());
30
+        } else {
31
+            return ActionResult.fail("No account with id: " + id + "\nTry account 1000 or 2000");
32
+        }
33
+    }
34
+
35
+    public ActionResult<AccountData> deposit(AccountData accountData, int amount) {
36
+        Account account = accounts.get(accountData.getId());
37
+        account.deposit(amount);
38
+
39
+        return ActionResult.success(account.getAccountData());
40
+    }
41
+
42
+    public ActionResult<AccountData> withdraw(AccountData accountData, int amount) {
43
+        Account account = accounts.get(accountData.getId());
44
+        boolean ok = account.withdraw(amount);
45
+
46
+        if (ok) {
47
+            return ActionResult.success(account.getAccountData());
48
+        } else {
49
+            return ActionResult.fail("Withdraw failed: " + amount + ". Account has: " + account.getBalance());
50
+        }
51
+    }
52
+}

+ 4
- 0
BasicAccount.ctxt Прегледај датотеку

@@ -0,0 +1,4 @@
1
+#BlueJ class context
2
+comment0.target=BasicAccount
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+numComments=1

+ 11
- 0
BasicAccount.java Прегледај датотеку

@@ -0,0 +1,11 @@
1
+ 
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public class BasicAccount extends Account {
7
+
8
+    public BasicAccount(AccountData accountData) {
9
+        super(accountData);
10
+    }
11
+}

+ 18
- 0
CashMachine.ctxt Прегледај датотеку

@@ -0,0 +1,18 @@
1
+#BlueJ class context
2
+comment0.target=CashMachine
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+comment1.params=bank
5
+comment1.target=CashMachine(Bank)
6
+comment2.params=id
7
+comment2.target=void\ login(int)
8
+comment3.params=amount
9
+comment3.target=void\ deposit(int)
10
+comment4.params=amount
11
+comment4.target=void\ withdraw(int)
12
+comment5.params=
13
+comment5.target=void\ exit()
14
+comment6.params=
15
+comment6.target=java.lang.String\ toString()
16
+comment7.params=action\ postAction
17
+comment7.target=void\ tryCall(java.util.function.Supplier,\ java.util.function.Consumer)
18
+numComments=8

+ 75
- 0
CashMachine.java Прегледај датотеку

@@ -0,0 +1,75 @@
1
+ 
2
+
3
+//import rocks.zipcode.atm.bank.AccountData;
4
+//import rocks.zipcode.atm.bank.Bank;
5
+
6
+import java.util.function.Consumer;
7
+import java.util.function.Supplier;
8
+
9
+/**
10
+ * @author ZipCodeWilmington
11
+ */
12
+public class CashMachine {
13
+
14
+    private final Bank bank;
15
+    private AccountData accountData = null;
16
+
17
+    public CashMachine(Bank bank) {
18
+        this.bank = bank;
19
+    }
20
+
21
+    private Consumer<AccountData> update = data -> {
22
+        accountData = data;
23
+    };
24
+
25
+    public void login(int id) {
26
+        tryCall(
27
+                () -> bank.getAccountById(id),
28
+                update
29
+        );
30
+    }
31
+
32
+    public void deposit(int amount) {
33
+        if (accountData != null) {
34
+            tryCall(
35
+                    () -> bank.deposit(accountData, amount),
36
+                    update
37
+            );
38
+        }
39
+    }
40
+
41
+    public void withdraw(int amount) {
42
+        if (accountData != null) {
43
+            tryCall(
44
+                    () -> bank.withdraw(accountData, amount),
45
+                    update
46
+            );
47
+        }
48
+    }
49
+
50
+    public void exit() {
51
+        if (accountData != null) {
52
+            accountData = null;
53
+        }
54
+    }
55
+
56
+    @Override
57
+    public String toString() {
58
+        return accountData != null ? accountData.toString() : "Try account 1000 or 2000 and click submit.";
59
+    }
60
+
61
+    private <T> void tryCall(Supplier<ActionResult<T> > action, Consumer<T> postAction) {
62
+        try {
63
+            ActionResult<T> result = action.get();
64
+            if (result.isSuccess()) {
65
+                T data = result.getData();
66
+                postAction.accept(data);
67
+            } else {
68
+                String errorMessage = result.getErrorMessage();
69
+                throw new RuntimeException(errorMessage);
70
+            }
71
+        } catch (Exception e) {
72
+            System.out.println("Error: " + e.getMessage());
73
+        }
74
+    }
75
+}

+ 10
- 0
CashMachineApp.ctxt Прегледај датотеку

@@ -0,0 +1,10 @@
1
+#BlueJ class context
2
+comment0.target=CashMachineApp
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+comment1.params=
5
+comment1.target=javafx.scene.Parent\ createContent()
6
+comment2.params=stage
7
+comment2.target=void\ start(javafx.stage.Stage)
8
+comment3.params=args
9
+comment3.target=void\ main(java.lang.String[])
10
+numComments=4

+ 78
- 0
CashMachineApp.java Прегледај датотеку

@@ -0,0 +1,78 @@
1
+ 
2
+
3
+
4
+import javafx.application.Application;
5
+import javafx.scene.Parent;
6
+import javafx.scene.Scene;
7
+import javafx.scene.control.Button;
8
+import javafx.scene.control.TextArea;
9
+import javafx.scene.control.TextField;
10
+import javafx.scene.layout.VBox;
11
+import javafx.stage.Stage;
12
+import javafx.scene.layout.FlowPane;
13
+
14
+/**
15
+ * @author ZipCodeWilmington
16
+ */
17
+public class CashMachineApp extends Application {
18
+
19
+    private TextField field = new TextField();
20
+    private CashMachine cashMachine = new CashMachine(new Bank());
21
+
22
+    private Parent createContent() {
23
+        VBox vbox = new VBox(10);
24
+        vbox.setPrefSize(600, 600);
25
+
26
+        TextArea areaInfo = new TextArea();
27
+
28
+        Button btnSubmit = new Button("Set Account ID");
29
+        btnSubmit.setOnAction(e -> {
30
+            int id = Integer.parseInt(field.getText());
31
+            cashMachine.login(id);
32
+
33
+            areaInfo.setText(cashMachine.toString());
34
+        });
35
+
36
+        Button btnDeposit = new Button("Deposit");
37
+        btnDeposit.setOnAction(e -> {
38
+            int amount = Integer.parseInt(field.getText());
39
+            cashMachine.deposit(amount);
40
+
41
+            areaInfo.setText(cashMachine.toString());
42
+        });
43
+
44
+        Button btnWithdraw = new Button("Withdraw");
45
+        btnWithdraw.setOnAction(e -> {
46
+            int amount = Integer.parseInt(field.getText());
47
+            cashMachine.withdraw(amount);
48
+
49
+            areaInfo.setText(cashMachine.toString());
50
+        });
51
+
52
+        Button btnExit = new Button("Exit");
53
+        btnExit.setOnAction(e -> {
54
+            cashMachine.exit();
55
+
56
+            areaInfo.setText(cashMachine.toString());
57
+        });
58
+
59
+        FlowPane flowpane = new FlowPane();
60
+
61
+        flowpane.getChildren().add(btnSubmit);
62
+        flowpane.getChildren().add(btnDeposit);
63
+        flowpane.getChildren().add(btnWithdraw);
64
+        flowpane.getChildren().add(btnExit);
65
+        vbox.getChildren().addAll(field, flowpane, areaInfo);
66
+        return vbox;
67
+    }
68
+
69
+    @Override
70
+    public void start(Stage stage) throws Exception {
71
+        stage.setScene(new Scene(createContent()));
72
+        stage.show();
73
+    }
74
+
75
+    public static void main(String[] args) {
76
+        launch(args);
77
+    }
78
+}

+ 21
- 0
LICENSE Прегледај датотеку

@@ -0,0 +1,21 @@
1
+MIT License
2
+
3
+Copyright (c) 2017 Almas Baimagambetov
4
+
5
+Permission is hereby granted, free of charge, to any person obtaining a copy
6
+of this software and associated documentation files (the "Software"), to deal
7
+in the Software without restriction, including without limitation the rights
8
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+copies of the Software, and to permit persons to whom the Software is
10
+furnished to do so, subject to the following conditions:
11
+
12
+The above copyright notice and this permission notice shall be included in all
13
+copies or substantial portions of the Software.
14
+
15
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+SOFTWARE.

+ 6
- 0
PremiumAccount.ctxt Прегледај датотеку

@@ -0,0 +1,6 @@
1
+#BlueJ class context
2
+comment0.target=PremiumAccount
3
+comment0.text=\n\ @author\ ZipCodeWilmington\n
4
+comment1.params=amount
5
+comment1.target=boolean\ canWithdraw(int)
6
+numComments=2

+ 18
- 0
PremiumAccount.java Прегледај датотеку

@@ -0,0 +1,18 @@
1
+ 
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public class PremiumAccount extends Account {
7
+
8
+    private static final int OVERDRAFT_LIMIT = 100;
9
+
10
+    public PremiumAccount(AccountData accountData) {
11
+        super(accountData);
12
+    }
13
+
14
+    @Override
15
+    protected boolean canWithdraw(int amount) {
16
+        return getBalance() + OVERDRAFT_LIMIT >= amount;
17
+    }
18
+}

+ 92
- 0
README.TXT Прегледај датотеку

@@ -0,0 +1,92 @@
1
+****************
2
+CashMachineBlueJ
3
+****************
4
+
5
+An simple cash account <-> bank system implementation (very loosely modelled!)
6
+
7
+This project uses JavaFX for the user interface toolkit. JavaFX is a software platform for creating 
8
+and delivering desktop applications, as well as rich Internet applications (RIAs) 
9
+that can run across a wide variety of devices. It is part of the standard Java distribution.
10
+
11
+Welcome to your first App. "ZipCloudBank", a local Wilmington fintech startup, has a minimally
12
+viable product in CashMachine. The response from customers has been, shall we say, underwhelming.
13
+The original coder has gone off to another startup, in Thailand, where they code on surfboards
14
+all day long.
15
+The Board of Directors of ZipCloudBank have empowered me to let you take a crack at "upping their game"
16
+and improving their app over this weekend. Impressed that you are a ZipCode student, they are
17
+expecting great things. Don't panic: we think you can do this.
18
+
19
+The point of this lab is to read thru some existing code, in this case, a program/app that 
20
+launches a window on your computer and lets you play with a couple of "banking accounts".
21
+You should run the app, learn how to use it, so you understand what it does. It is not,
22
+shall we say, user-friendly. So you may find what you have to do to make it work somewhat
23
+awkward. 
24
+
25
+Then, you should read thru the code seeing how the code actually implements the things you 
26
+see when you run the code. Find the "main" routine, which is where the app starts up. Trace from there
27
+to see what code gets called where and when. Trace how the operations of the code work.
28
+
29
+Finally, you are to add some new functionality to the app, to make it "more useful, powerful &
30
+more rewarding for the user". 
31
+Your effort will be met with promotions, parades, and stock options. (no, just kidding).
32
+
33
+Lab Brief
34
+=========
35
+
36
+Notice the structure of the current project before you start. 
37
+Read thru the code. READ THRU THE CODE.
38
+READ THRU THE CODE.
39
+==================
40
+
41
+- Find the 2 Account Classes: Basic, Premium
42
+- Find the superclass of the 2 account classes.
43
+- Find the other classes including Bank, Account, CashMachine. Read thru them all.
44
+
45
+Read them all, trying to get an idea of how it all goes together.
46
+
47
+Notice when reading the code...
48
+
49
+- Each account has: id, name, email, balance
50
+- What does Premium account do that Basic does not?
51
+- What are the two starter account already built into the project?
52
+- Trace how the Cash machine sets the account
53
+-- enter account id to "login to account"
54
+- Trace how a deposit happens
55
+-- enter a number then click deposit
56
+- Trace how a withdrawal happens
57
+-- enter a number then click withdraw
58
+- How does "exit" log out of the account?
59
+
60
+
61
+Things to Change for the Lab
62
+============================
63
+
64
+* Add more accounts to the default constructor of the Bank class.
65
+when you overdraft an account, print an alert message to the areaInfo object
66
+
67
+Additional things to add
68
+------------------------
69
+
70
+* make the account display more user friendly
71
+
72
+* add a Form layout that has separate TextFields for each piece of account info. 
73
+* You'll probablyfind a layout that lets you do this, a little like the FlowPane.
74
+make the login stuff more clear
75
+
76
+  * disable the three buttons that operate on an account until a login happens 
77
+  * and then enable them. add another TextField for the amount entries. 
78
+  * make it different from the fieldwhere you set the account ID.
79
+
80
+* enable the amount entries to be floating point numbers instead of 
81
+  just integers when doing deposits and withdrawals.
82
+
83
+* add a menu with a list of accounts in it and the menu action switched 
84
+  to that account. You may find that JavaFX already has such a thing.
85
+
86
+**** Add a New Account Window(!) that takes in the info required thru 
87
+     TextFields and creates the correct objects so that is can be changed 
88
+     like the pre-wired accounts.
89
+
90
+NB: When googling for information on how to do all this, 
91
+be sure you start every query with "javafx " and your other search terms. 
92
+That will limit the results to things that probably are closer to what you need.

+ 43
- 0
README.md Прегледај датотеку

@@ -0,0 +1,43 @@
1
+# CashMachine
2
+An example cash machine &lt;-> bank system implementation
3
+
4
+uses JavaFX for the user interface.
5
+
6
+## Lab Brief
7
+
8
+Notice the structure of the current project before you start. Read thru the code. READ THRU THE CODE.
9
+* 2 Account Classes: Basic, Premium
10
+* Other Classes include Bank, Account, CashMachine.
11
+
12
+Read them all, trying to get an idea of how it all goes together.
13
+
14
+### Notice when reading the code...
15
+* Each account has: id, name, email, balance
16
+  * What does Premium account do that Basic does not?
17
+* What are the two starter account already built into the project?
18
+* Cash machine: enter account id to "login to account"
19
+* enter a number then click deposit
20
+* enter a number then click withdraw
21
+* exit logs out of the account
22
+
23
+## Things to Change for the Lab
24
+
25
+* Add more accounts to the default constructor of the Bank class.
26
+* when you overdraft an account, print an alert message to the areaInfo object
27
+
28
+### Additional things to add
29
+
30
+* make the account display more user friendly
31
+  * add a Form layout that has separate TextFields for each piece of account info. You'll probablyfind a layout that lets you do this, a little like the FlowPane.
32
+* make the login stuff more clear
33
+  * disable the three buttons that operate on an account until a login happens and then enable them.
34
+  * add another TextField for the amount entries. make it different from the fieldwhere you set the account ID.
35
+* enable the amount entries to be floating point numbers instead of just integers when doing deposits and withdrawals.
36
+* add a menu with a list of accounts in it and the menu action switched to that account. You may find that JavaFX already has such a thing.
37
+
38
+* Add a New Account Window(!) that takes in the info required thru TextFields and creates the correct objects so that is can be changed like the pre-wired accounts.
39
+
40
+___
41
+
42
+NB:
43
+When googling for information on how to do all this, be sure you start every query with "javafx " and your other search terms. That will limit the results to things that probably are closer to what you need.

+ 115
- 0
package.bluej Прегледај датотеку

@@ -0,0 +1,115 @@
1
+#BlueJ package file
2
+dependency1.from=Account
3
+dependency1.to=AccountData
4
+dependency1.type=UsesDependency
5
+dependency10.from=Bank
6
+dependency10.to=PremiumAccount
7
+dependency10.type=UsesDependency
8
+dependency11.from=Bank
9
+dependency11.to=ActionResult
10
+dependency11.type=UsesDependency
11
+dependency2.from=CashMachineApp
12
+dependency2.to=CashMachine
13
+dependency2.type=UsesDependency
14
+dependency3.from=CashMachineApp
15
+dependency3.to=Bank
16
+dependency3.type=UsesDependency
17
+dependency4.from=CashMachine
18
+dependency4.to=Bank
19
+dependency4.type=UsesDependency
20
+dependency5.from=CashMachine
21
+dependency5.to=AccountData
22
+dependency5.type=UsesDependency
23
+dependency6.from=CashMachine
24
+dependency6.to=ActionResult
25
+dependency6.type=UsesDependency
26
+dependency7.from=Bank
27
+dependency7.to=Account
28
+dependency7.type=UsesDependency
29
+dependency8.from=Bank
30
+dependency8.to=BasicAccount
31
+dependency8.type=UsesDependency
32
+dependency9.from=Bank
33
+dependency9.to=AccountData
34
+dependency9.type=UsesDependency
35
+editor.fx.0.height=722
36
+editor.fx.0.width=800
37
+editor.fx.0.x=788
38
+editor.fx.0.y=119
39
+objectbench.height=101
40
+objectbench.width=461
41
+package.divider.horizontal=0.6
42
+package.divider.vertical=0.8007380073800738
43
+package.editor.height=427
44
+package.editor.width=674
45
+package.editor.x=664
46
+package.editor.y=27
47
+package.frame.height=600
48
+package.frame.width=800
49
+package.numDependencies=11
50
+package.numTargets=8
51
+package.showExtends=true
52
+package.showUses=true
53
+project.charset=UTF-8
54
+project.invoke.thread=FX
55
+readme.height=58
56
+readme.name=@README
57
+readme.width=47
58
+readme.x=10
59
+readme.y=10
60
+target1.height=50
61
+target1.name=Account
62
+target1.showInterface=false
63
+target1.type=AbstractTarget
64
+target1.width=80
65
+target1.x=450
66
+target1.y=70
67
+target2.height=50
68
+target2.name=Bank
69
+target2.showInterface=false
70
+target2.type=ClassTarget
71
+target2.width=80
72
+target2.x=280
73
+target2.y=20
74
+target3.height=50
75
+target3.name=CashMachine
76
+target3.showInterface=false
77
+target3.type=ClassTarget
78
+target3.width=110
79
+target3.x=50
80
+target3.y=110
81
+target4.height=50
82
+target4.name=ActionResult
83
+target4.showInterface=false
84
+target4.type=ClassTarget
85
+target4.width=130
86
+target4.x=150
87
+target4.y=180
88
+target5.height=50
89
+target5.name=AccountData
90
+target5.showInterface=false
91
+target5.type=ClassTarget
92
+target5.width=110
93
+target5.x=550
94
+target5.y=290
95
+target6.height=50
96
+target6.name=PremiumAccount
97
+target6.showInterface=false
98
+target6.type=ClassTarget
99
+target6.width=130
100
+target6.x=510
101
+target6.y=200
102
+target7.height=50
103
+target7.name=BasicAccount
104
+target7.showInterface=false
105
+target7.type=ClassTarget
106
+target7.width=110
107
+target7.x=370
108
+target7.y=160
109
+target8.height=50
110
+target8.name=CashMachineApp
111
+target8.showInterface=false
112
+target8.type=ClassTarget
113
+target8.width=130
114
+target8.x=70
115
+target8.y=10

+ 56
- 0
pom.xml Прегледај датотеку

@@ -0,0 +1,56 @@
1
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3
+    <modelVersion>4.0.0</modelVersion>
4
+
5
+    <groupId>com.almasb</groupId>
6
+    <artifactId>CashMachine</artifactId>
7
+    <version>0.1-SNAPSHOT</version>
8
+    <packaging>jar</packaging>
9
+
10
+    <properties>
11
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
12
+        <source.version>1.8</source.version>
13
+
14
+        <!-- plugins -->
15
+        <maven.compiler.version>3.3</maven.compiler.version>
16
+        <maven.shade.version>2.4.2</maven.shade.version>
17
+
18
+        <!-- dependencies -->
19
+    </properties>
20
+
21
+    <build>
22
+        <plugins>
23
+            <plugin>
24
+                <artifactId>maven-compiler-plugin</artifactId>
25
+                <version>${maven.compiler.version}</version>
26
+                <configuration>
27
+                    <source>${source.version}</source>
28
+                    <target>${source.version}</target>
29
+                </configuration>
30
+            </plugin>
31
+
32
+            <plugin>
33
+                <groupId>org.apache.maven.plugins</groupId>
34
+                <artifactId>maven-shade-plugin</artifactId>
35
+                <version>${maven.shade.version}</version>
36
+                <executions>
37
+                    <execution>
38
+                        <phase>package</phase>
39
+                        <goals>
40
+                            <goal>shade</goal>
41
+                        </goals>
42
+                        <configuration>
43
+                            <transformers>
44
+                                <transformer
45
+                                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
46
+                                    <mainClass>com.almasb.atm.CashMachineApp</mainClass>
47
+                                </transformer>
48
+                            </transformers>
49
+                        </configuration>
50
+                    </execution>
51
+                </executions>
52
+            </plugin>
53
+        </plugins>
54
+    </build>
55
+
56
+</project>

+ 38
- 0
src/main/java/rocks/zipcode/atm/ActionResult.java Прегледај датотеку

@@ -0,0 +1,38 @@
1
+package rocks.zipcode.atm;
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public class ActionResult<T> {
7
+
8
+    private T data;
9
+    private String errorMessage;
10
+
11
+    private ActionResult(T data) {
12
+        this.data = data;
13
+    }
14
+
15
+    private ActionResult(String errorMessage) {
16
+        this.errorMessage = errorMessage;
17
+    }
18
+
19
+    public T getData() {
20
+        return data;
21
+    }
22
+
23
+    public String getErrorMessage() {
24
+        return errorMessage;
25
+    }
26
+
27
+    public boolean isSuccess() {
28
+        return data != null;
29
+    }
30
+
31
+    public static <E> ActionResult<E> success(E data) {
32
+        return new ActionResult<E>(data);
33
+    }
34
+
35
+    public static <E> ActionResult<E> fail(String errorMessage) {
36
+        return new ActionResult<E>(errorMessage);
37
+    }
38
+}

+ 75
- 0
src/main/java/rocks/zipcode/atm/CashMachine.java Прегледај датотеку

@@ -0,0 +1,75 @@
1
+package rocks.zipcode.atm;
2
+
3
+import rocks.zipcode.atm.bank.AccountData;
4
+import rocks.zipcode.atm.bank.Bank;
5
+
6
+import java.util.function.Consumer;
7
+import java.util.function.Supplier;
8
+
9
+/**
10
+ * @author ZipCodeWilmington
11
+ */
12
+public class CashMachine {
13
+
14
+    private final Bank bank;
15
+    private AccountData accountData = null;
16
+
17
+    public CashMachine(Bank bank) {
18
+        this.bank = bank;
19
+    }
20
+
21
+    private Consumer<AccountData> update = data -> {
22
+        accountData = data;
23
+    };
24
+
25
+    public void login(int id) {
26
+        tryCall(
27
+                () -> bank.getAccountById(id),
28
+                update
29
+        );
30
+    }
31
+
32
+    public void deposit(int amount) {
33
+        if (accountData != null) {
34
+            tryCall(
35
+                    () -> bank.deposit(accountData, amount),
36
+                    update
37
+            );
38
+        }
39
+    }
40
+
41
+    public void withdraw(int amount) {
42
+        if (accountData != null) {
43
+            tryCall(
44
+                    () -> bank.withdraw(accountData, amount),
45
+                    update
46
+            );
47
+        }
48
+    }
49
+
50
+    public void exit() {
51
+        if (accountData != null) {
52
+            accountData = null;
53
+        }
54
+    }
55
+
56
+    @Override
57
+    public String toString() {
58
+        return accountData != null ? accountData.toString() : "Try account 1000 or 2000 and click submit.";
59
+    }
60
+
61
+    private <T> void tryCall(Supplier<ActionResult<T> > action, Consumer<T> postAction) {
62
+        try {
63
+            ActionResult<T> result = action.get();
64
+            if (result.isSuccess()) {
65
+                T data = result.getData();
66
+                postAction.accept(data);
67
+            } else {
68
+                String errorMessage = result.getErrorMessage();
69
+                throw new RuntimeException(errorMessage);
70
+            }
71
+        } catch (Exception e) {
72
+            System.out.println("Error: " + e.getMessage());
73
+        }
74
+    }
75
+}

+ 78
- 0
src/main/java/rocks/zipcode/atm/CashMachineApp.java Прегледај датотеку

@@ -0,0 +1,78 @@
1
+package rocks.zipcode.atm;
2
+
3
+import rocks.zipcode.atm.bank.Bank;
4
+import javafx.application.Application;
5
+import javafx.scene.Parent;
6
+import javafx.scene.Scene;
7
+import javafx.scene.control.Button;
8
+import javafx.scene.control.TextArea;
9
+import javafx.scene.control.TextField;
10
+import javafx.scene.layout.VBox;
11
+import javafx.stage.Stage;
12
+import javafx.scene.layout.FlowPane;
13
+
14
+/**
15
+ * @author ZipCodeWilmington
16
+ */
17
+public class CashMachineApp extends Application {
18
+
19
+    private TextField field = new TextField();
20
+    private CashMachine cashMachine = new CashMachine(new Bank());
21
+
22
+    private Parent createContent() {
23
+        VBox vbox = new VBox(10);
24
+        vbox.setPrefSize(600, 600);
25
+
26
+        TextArea areaInfo = new TextArea();
27
+
28
+        Button btnSubmit = new Button("Set Account ID");
29
+        btnSubmit.setOnAction(e -> {
30
+            int id = Integer.parseInt(field.getText());
31
+            cashMachine.login(id);
32
+
33
+            areaInfo.setText(cashMachine.toString());
34
+        });
35
+
36
+        Button btnDeposit = new Button("Deposit");
37
+        btnDeposit.setOnAction(e -> {
38
+            int amount = Integer.parseInt(field.getText());
39
+            cashMachine.deposit(amount);
40
+
41
+            areaInfo.setText(cashMachine.toString());
42
+        });
43
+
44
+        Button btnWithdraw = new Button("Withdraw");
45
+        btnWithdraw.setOnAction(e -> {
46
+            int amount = Integer.parseInt(field.getText());
47
+            cashMachine.withdraw(amount);
48
+
49
+            areaInfo.setText(cashMachine.toString());
50
+        });
51
+
52
+        Button btnExit = new Button("Exit");
53
+        btnExit.setOnAction(e -> {
54
+            cashMachine.exit();
55
+
56
+            areaInfo.setText(cashMachine.toString());
57
+        });
58
+
59
+        FlowPane flowpane = new FlowPane();
60
+
61
+        flowpane.getChildren().add(btnSubmit);
62
+        flowpane.getChildren().add(btnDeposit);
63
+        flowpane.getChildren().add(btnWithdraw);
64
+        flowpane.getChildren().add(btnExit);
65
+        vbox.getChildren().addAll(field, flowpane, areaInfo);
66
+        return vbox;
67
+    }
68
+
69
+    @Override
70
+    public void start(Stage stage) throws Exception {
71
+        stage.setScene(new Scene(createContent()));
72
+        stage.show();
73
+    }
74
+
75
+    public static void main(String[] args) {
76
+        launch(args);
77
+    }
78
+}

+ 43
- 0
src/main/java/rocks/zipcode/atm/bank/Account.java Прегледај датотеку

@@ -0,0 +1,43 @@
1
+package rocks.zipcode.atm.bank;
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public abstract class Account {
7
+
8
+    private AccountData accountData;
9
+
10
+    public Account(AccountData accountData) {
11
+        this.accountData = accountData;
12
+    }
13
+
14
+    public AccountData getAccountData() {
15
+        return accountData;
16
+    }
17
+
18
+    public void deposit(int amount) {
19
+        updateBalance(getBalance() + amount);
20
+    }
21
+
22
+    public boolean withdraw(int amount) {
23
+        if (canWithdraw(amount)) {
24
+            updateBalance(getBalance() - amount);
25
+            return true;
26
+        } else {
27
+            return false;
28
+        }
29
+    }
30
+
31
+    protected boolean canWithdraw(int amount) {
32
+        return getBalance() >= amount;
33
+    }
34
+
35
+    public int getBalance() {
36
+        return accountData.getBalance();
37
+    }
38
+
39
+    private void updateBalance(int newBalance) {
40
+        accountData = new AccountData(accountData.getId(), accountData.getName(), accountData.getEmail(),
41
+                newBalance);
42
+    }
43
+}

+ 44
- 0
src/main/java/rocks/zipcode/atm/bank/AccountData.java Прегледај датотеку

@@ -0,0 +1,44 @@
1
+package rocks.zipcode.atm.bank;
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public final class AccountData {
7
+
8
+    private final int id;
9
+    private final String name;
10
+    private final String email;
11
+
12
+    private final int balance;
13
+
14
+    AccountData(int id, String name, String email, int balance) {
15
+        this.id = id;
16
+        this.name = name;
17
+        this.email = email;
18
+        this.balance = balance;
19
+    }
20
+
21
+    public int getId() {
22
+        return id;
23
+    }
24
+
25
+    public String getName() {
26
+        return name;
27
+    }
28
+
29
+    public String getEmail() {
30
+        return email;
31
+    }
32
+
33
+    public int getBalance() {
34
+        return balance;
35
+    }
36
+
37
+    @Override
38
+    public String toString() {
39
+        return "Account id: " + id + '\n' +
40
+                "Name: " + name + '\n' +
41
+                "Email: " + email + '\n' +
42
+                "Balance: " + balance;
43
+    }
44
+}

+ 52
- 0
src/main/java/rocks/zipcode/atm/bank/Bank.java Прегледај датотеку

@@ -0,0 +1,52 @@
1
+package rocks.zipcode.atm.bank;
2
+
3
+import rocks.zipcode.atm.ActionResult;
4
+
5
+import java.util.HashMap;
6
+import java.util.Map;
7
+
8
+/**
9
+ * @author ZipCodeWilmington
10
+ */
11
+public class Bank {
12
+
13
+    private Map<Integer, Account> accounts = new HashMap<>();
14
+
15
+    public Bank() {
16
+        accounts.put(1000, new BasicAccount(new AccountData(
17
+                1000, "Example 1", "example1@gmail.com", 500
18
+        )));
19
+
20
+        accounts.put(2000, new PremiumAccount(new AccountData(
21
+                2000, "Example 2", "example2@gmail.com", 200
22
+        )));
23
+    }
24
+
25
+    public ActionResult<AccountData> getAccountById(int id) {
26
+        Account account = accounts.get(id);
27
+
28
+        if (account != null) {
29
+            return ActionResult.success(account.getAccountData());
30
+        } else {
31
+            return ActionResult.fail("No account with id: " + id + "\nTry account 1000 or 2000");
32
+        }
33
+    }
34
+
35
+    public ActionResult<AccountData> deposit(AccountData accountData, int amount) {
36
+        Account account = accounts.get(accountData.getId());
37
+        account.deposit(amount);
38
+
39
+        return ActionResult.success(account.getAccountData());
40
+    }
41
+
42
+    public ActionResult<AccountData> withdraw(AccountData accountData, int amount) {
43
+        Account account = accounts.get(accountData.getId());
44
+        boolean ok = account.withdraw(amount);
45
+
46
+        if (ok) {
47
+            return ActionResult.success(account.getAccountData());
48
+        } else {
49
+            return ActionResult.fail("Withdraw failed: " + amount + ". Account has: " + account.getBalance());
50
+        }
51
+    }
52
+}

+ 11
- 0
src/main/java/rocks/zipcode/atm/bank/BasicAccount.java Прегледај датотеку

@@ -0,0 +1,11 @@
1
+package rocks.zipcode.atm.bank;
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public class BasicAccount extends Account {
7
+
8
+    public BasicAccount(AccountData accountData) {
9
+        super(accountData);
10
+    }
11
+}

+ 18
- 0
src/main/java/rocks/zipcode/atm/bank/PremiumAccount.java Прегледај датотеку

@@ -0,0 +1,18 @@
1
+package rocks.zipcode.atm.bank;
2
+
3
+/**
4
+ * @author ZipCodeWilmington
5
+ */
6
+public class PremiumAccount extends Account {
7
+
8
+    private static final int OVERDRAFT_LIMIT = 100;
9
+
10
+    public PremiumAccount(AccountData accountData) {
11
+        super(accountData);
12
+    }
13
+
14
+    @Override
15
+    protected boolean canWithdraw(int amount) {
16
+        return getBalance() + OVERDRAFT_LIMIT >= amount;
17
+    }
18
+}