added profile screen

This commit is contained in:
Sven Vogel 2023-06-22 17:19:43 +02:00
parent 8ebb4eef8c
commit c34895f92e
14 changed files with 348 additions and 33 deletions

View File

@ -1,19 +0,0 @@
import me.teridax.jcash.gui.login.LoginView;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
// Loader.load();
var window = new JFrame();
window.setTitle("Bankautomat");
window.setLocationByPlatform(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.add(new LoginView());
window.setVisible(true);
});
}
}

View File

@ -0,0 +1,61 @@
package me.teridax.jcash;
import me.teridax.jcash.gui.Loader;
import me.teridax.jcash.gui.account.AccountController;
import me.teridax.jcash.gui.login.LoginController;
import javax.swing.*;
public class Main {
private static Main instance;
private final JFrame window;
private Main() {
window = new JFrame();
window.setTitle("Bankautomat");
window.setLocationByPlatform(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
instance();
getInstance().popLoginScreen();
}
public static Main getInstance() {
return instance;
}
public static void instance() {
if (instance == null) {
instance = new Main();
return;
}
throw new IllegalStateException("me.teridax.jcash.Main is already initialized");
}
public void popLoginScreen() {
SwingUtilities.invokeLater(() -> {
var path = Loader.load();
var login = new LoginController(path);
login.addAccountSelectionListener(account -> {
var profileCont = new AccountController(account);
window.setContentPane(profileCont.getView());
window.pack();
});
window.setContentPane(login.getView());
window.pack();
window.setVisible(true);
});
}
public void logout() {
window.setContentPane(new JLabel("you're logged out"));
window.setVisible(false);
}
}

View File

@ -64,4 +64,8 @@ public abstract class Account {
return false; return false;
} }
public String getDescription() {
return String.format("%s (%s)", iban, getClass().getSimpleName());
}
} }

View File

@ -57,11 +57,11 @@ public final class Bank {
return blz; return blz;
} }
public Optional<Account> getAccount(int iban) { public Optional<Profile> getAccount(int iban) {
for (var owner : this.accounts.entrySet()) { for (var owner : this.accounts.entrySet()) {
for (var account : owner.getValue()) { for (var account : owner.getValue()) {
if (account.getIban() == iban) { if (account.getIban() == iban) {
return Optional.of(account); return Optional.of(new Profile(owner.getKey(), this, account, getAccountsOfOwner(owner.getKey())));
} }
} }
} }

View File

@ -56,6 +56,6 @@ public final class BankingManagementSystem {
} }
public Optional<Bank> getBank(String blz) { public Optional<Bank> getBank(String blz) {
return this.banks.stream().filter(b -> b.getBlz().equals(blz)).findFirst(); return this.banks.stream().filter(b -> !b.getBlz().equals(blz)).findFirst();
} }
} }

View File

@ -0,0 +1,41 @@
package me.teridax.jcash.banking;
public class Profile {
private Owner owner;
private Bank bank;
private Account primaryAccount;
private Account[] accounts;
public Profile(Owner owner, Bank bank, Account account, Account[] accounts) {
this.owner = owner;
this.bank = bank;
this.accounts = accounts;
this.primaryAccount = account;
}
public Account getPrimaryAccount() {
return primaryAccount;
}
public Owner getOwner() {
return owner;
}
public Bank getBank() {
return bank;
}
public Account[] getAccounts() {
return accounts;
}
public void setPrimaryAccount(String description) {
for (Account account : accounts) {
if (account.getDescription().equals(description)) {
this.primaryAccount = account;
break;
}
}
}
}

View File

@ -13,7 +13,7 @@ import static junit.framework.TestCase.assertEquals;
public class Decoder { public class Decoder {
private static final Locale LOCALE = Locale.GERMANY; private static final Locale LOCALE = Locale.GERMANY;
private static final NumberFormat LOCAL_NUMBER_FORMAT = NumberFormat.getInstance(LOCALE); public static final NumberFormat LOCAL_NUMBER_FORMAT = NumberFormat.getInstance(LOCALE);
public static double decodePercent(String number) throws IllegalArgumentException, NullPointerException { public static double decodePercent(String number) throws IllegalArgumentException, NullPointerException {
Objects.requireNonNull(number); Objects.requireNonNull(number);

View File

@ -4,6 +4,7 @@ import me.teridax.jcash.banking.BankingManagementSystem;
import javax.swing.*; import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import java.io.File;
public class Loader { public class Loader {
@ -16,6 +17,7 @@ public class Loader {
fileChooser.setFileFilter(FILE_FILTER); fileChooser.setFileFilter(FILE_FILTER);
fileChooser.setDialogType(JFileChooser.OPEN_DIALOG); fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
fileChooser.setAcceptAllFileFilterUsed(false); fileChooser.setAcceptAllFileFilterUsed(false);
fileChooser.setCurrentDirectory(new File("/home/teridax/IdeaProjects/JCash/res"));
if (fileChooser.showDialog(null, "Load database") == JFileChooser.APPROVE_OPTION) { if (fileChooser.showDialog(null, "Load database") == JFileChooser.APPROVE_OPTION) {
try { try {

View File

@ -0,0 +1,33 @@
package me.teridax.jcash.gui.account;
import me.teridax.jcash.Main;
import me.teridax.jcash.banking.Profile;
public class AccountController {
private final AccountView view;
public AccountController(Profile profile) {
this.view = new AccountView();
this.view.setProfile(profile);
createListeners(profile);
}
private void createListeners(Profile profile) {
this.view.getAccountSelection().addActionListener(e -> {
var description = ((String) this.view.getAccountSelection().getSelectedItem());
profile.setPrimaryAccount(description);
this.view.setProfile(profile);
});
this.view.getLogout().addActionListener(e -> {
Main.getInstance().logout();
Main.getInstance().popLoginScreen();
});
}
public AccountView getView() {
return view;
}
}

View File

@ -0,0 +1,169 @@
package me.teridax.jcash.gui.account;
import me.teridax.jcash.banking.*;
import me.teridax.jcash.decode.Decoder;
import javax.swing.*;
import java.awt.*;
public class AccountView extends JPanel {
private JTextField iban;
private JTextField name;
private JTextField address;
private JTextField bankName;
private JTextField blz;
private JTextField type;
private JTextField typeSpecialProperty;
private JTextField balance;
private JLabel typeSpecialLabel;
private JComboBox<String> accountSelection;
private JPanel content;
private JPanel buttonPanel;
private JButton logout;
private JButton transfer;
private JButton deposit;
private JButton takeoff;
public AccountView() {
createComponents();
createLayout();
setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
}
public void setProfile(Profile profile) {
var bank = profile.getBank();
var account = profile.getPrimaryAccount();
var owner = profile.getOwner();
this.blz.setText(bank.getBlz());
this.bankName.setText(bank.getName());
this.iban.setText(String.valueOf(account.getIban()));
this.name.setText(owner.getName() + " " + owner.getFamilyName());
this.address.setText(owner.getStreet() + " " + owner.getCity());
this.balance.setText(Decoder.LOCAL_NUMBER_FORMAT.format(account.getBalance()) + "");
this.type.setText(account.getClass().getSimpleName());
if (account instanceof Girokonto) {
this.typeSpecialLabel.setText("Überziehungsbetrag");
this.typeSpecialProperty.setText( Decoder.LOCAL_NUMBER_FORMAT.format(((Girokonto) account).getOverdraft()) + "");
} else if (account instanceof SavingsAccount) {
this.typeSpecialLabel.setText("Zinsbetrag");
this.typeSpecialProperty.setText( ((SavingsAccount) account).getInterest() + " %" );
}
this.accountSelection.removeAllItems();
for (var otherAccount : profile.getAccounts()) {
this.accountSelection.addItem(otherAccount.getDescription());
}
this.accountSelection.setSelectedItem(account.getDescription());
}
private void createLayout() {
setLayout(new BorderLayout(16, 16));
add(new JScrollPane(content), BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
content.setLayout(new GridBagLayout());
var constraints = new GridBagConstraints();
constraints.gridwidth = 4;
constraints.insets = new Insets(12,12,12,12);
var accountSelectionPanel = new JPanel(new BorderLayout(12, 0));
accountSelectionPanel.add(iban, BorderLayout.CENTER);
accountSelectionPanel.add(accountSelection, BorderLayout.EAST);
addInputRow(constraints, content, accountSelectionPanel, 1, new JLabel("Kontonummer", SwingConstants.RIGHT));
addInputRow(constraints, content, name, 2, new JLabel("Vorname/Nachname", SwingConstants.RIGHT));
addInputRow(constraints, content, address, 3, new JLabel("Adresse", SwingConstants.RIGHT));
addInputRow(constraints, content, bankName, 4, new JLabel("Bank", SwingConstants.RIGHT));
addInputRow(constraints, content, blz, 5, new JLabel("BLZ", SwingConstants.RIGHT));
addInputRow(constraints, content, type, 6, new JLabel("Konto", SwingConstants.RIGHT));
addInputRow(constraints, content, typeSpecialProperty, 7, typeSpecialLabel);
addInputRow(constraints, content, balance, 8, new JLabel("Kontostand", SwingConstants.RIGHT));
var buttonRightPanel = new JPanel();
buttonRightPanel.add(transfer);
buttonRightPanel.add(deposit);
buttonRightPanel.add(takeoff);
buttonPanel.add(logout, BorderLayout.LINE_START);
buttonPanel.add(buttonRightPanel, BorderLayout.LINE_END);
}
private void createComponents() {
this.blz = new JTextField();
this.iban = new JTextField();
this.address = new JTextField();
this.bankName = new JTextField();
this.name = new JTextField();
this.type = new JTextField();
this.balance = new JTextField();
this.typeSpecialProperty = new JTextField();
this.blz.setEditable(false);
this.iban.setEditable(false);
this.address.setEditable(false);
this.bankName.setEditable(false);
this.name.setEditable(false);
this.type.setEditable(false);
this.balance.setEditable(false);
this.typeSpecialProperty.setEditable(false);
this.typeSpecialLabel = new JLabel("", SwingConstants.RIGHT);
this.accountSelection = new JComboBox<>();
this.content = new JPanel();
this.buttonPanel = new JPanel(new BorderLayout());
this.logout = new JButton("Abmelden");
this.transfer = new JButton("Überweisen");
this.deposit = new JButton("Einzahlen");
this.takeoff = new JButton("Abheben");
}
private void addInputRow(GridBagConstraints constraints, JComponent target, JComponent comp, int row, JLabel label) {
constraints.gridwidth = 1;
constraints.gridx = 1;
constraints.gridy = row;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.HORIZONTAL;
target.add(label, constraints);
constraints.gridx = 2;
constraints.gridy = row;
constraints.weightx = 1;
constraints.fill = GridBagConstraints.HORIZONTAL;
target.add(comp, constraints);
}
public JComboBox<String> getAccountSelection() {
return accountSelection;
}
public JButton getLogout() {
return logout;
}
public JButton getTransfer() {
return transfer;
}
public JButton getDeposit() {
return deposit;
}
public JButton getTakeoff() {
return takeoff;
}
}

View File

@ -0,0 +1,8 @@
package me.teridax.jcash.gui.login;
import me.teridax.jcash.banking.Profile;
public interface AccountSelectionListener {
void onAccountSelected(Profile account);
}

View File

@ -3,6 +3,7 @@ package me.teridax.jcash.gui.login;
import me.teridax.jcash.banking.Account; import me.teridax.jcash.banking.Account;
import me.teridax.jcash.banking.BankingManagementSystem; import me.teridax.jcash.banking.BankingManagementSystem;
import javax.swing.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.util.Optional; import java.util.Optional;
@ -11,12 +12,11 @@ public class LoginController {
private LoginView view; private LoginView view;
private LoginData data; private LoginData data;
private Optional<Account> account; private AccountSelectionListener listener;
public LoginController(BankingManagementSystem bms) { public LoginController(BankingManagementSystem bms) {
this.view = new LoginView(); this.view = new LoginView();
this.data = new LoginData(bms); this.data = new LoginData(bms);
this.account = Optional.empty();
addActionListeners(); addActionListeners();
} }
@ -46,13 +46,28 @@ public class LoginController {
var blz = this.view.getBlz().getText(); var blz = this.view.getBlz().getText();
var iban = this.getIban(); var iban = this.getIban();
if (iban.isEmpty()) { if (iban.isEmpty()) {
JOptionPane.showMessageDialog(null, "invalid IBAN", "Faulty login attempt", JOptionPane.ERROR_MESSAGE);
return; return;
} }
var pin = this.getPin(); var pin = this.getPin();
if (pin.isEmpty()) { if (pin.isEmpty()) {
JOptionPane.showMessageDialog(null, "invalid pin", "Faulty login attempt", JOptionPane.ERROR_MESSAGE);
return; return;
} }
this.account = this.data.authenticateAccount(blz, iban.get(), pin.get()); var account = this.data.authenticateAccount(blz, iban.get(), pin.get());
if (account.isPresent()) {
this.listener.onAccountSelected(account.get());
} else {
JOptionPane.showMessageDialog(null, "invalid login credentials", "Faulty login attempt", JOptionPane.ERROR_MESSAGE);
}
}
public void addAccountSelectionListener(AccountSelectionListener listener) {
this.listener = listener;
}
public LoginView getView() {
return view;
} }
} }

View File

@ -2,6 +2,7 @@ package me.teridax.jcash.gui.login;
import me.teridax.jcash.banking.Account; import me.teridax.jcash.banking.Account;
import me.teridax.jcash.banking.BankingManagementSystem; import me.teridax.jcash.banking.BankingManagementSystem;
import me.teridax.jcash.banking.Profile;
import java.util.Optional; import java.util.Optional;
@ -13,12 +14,12 @@ public class LoginData {
this.bms = bms; this.bms = bms;
} }
public Optional<Account> authenticateAccount(String blz, int iban, int pin) { public Optional<Profile> authenticateAccount(String blz, int iban, int pin) {
var optionalBank = bms.getBank(blz); var optionalBank = bms.getBank(blz);
if (optionalBank.isEmpty()) if (optionalBank.isEmpty())
return Optional.empty(); return Optional.empty();
var account = optionalBank.get().getAccount(iban); var profile = optionalBank.get().getAccount(iban);
return account.filter(value -> value.getPin() == pin); return profile.filter(value -> value.getPrimaryAccount().getPin() == pin);
} }
} }

View File

@ -11,9 +11,9 @@ public class LoginView extends JPanel {
private final JButton login; private final JButton login;
public LoginView() { public LoginView() {
this.blz = new JTextField(); this.blz = new JTextField("MA2424");
this.iban = new JTextField(); this.iban = new JTextField("4711");
this.pin = new JPasswordField(); this.pin = new JPasswordField("1234");
this.login = new JButton("Login"); this.login = new JButton("Login");
setLayout(new BorderLayout(16, 16)); setLayout(new BorderLayout(16, 16));
@ -27,7 +27,6 @@ public class LoginView extends JPanel {
content.setLayout(layout); content.setLayout(layout);
constraints.gridwidth = 4; constraints.gridwidth = 4;
constraints.insets = new Insets(12,12,12,12); constraints.insets = new Insets(12,12,12,12);
addInputRow(constraints, content, blz, 1, "BLZ"); addInputRow(constraints, content, blz, 1, "BLZ");
@ -72,4 +71,5 @@ public class LoginView extends JPanel {
public JButton getLogin() { public JButton getLogin() {
return login; return login;
} }
} }