minor fixes

This commit is contained in:
Sven Vogel 2023-07-18 21:24:49 +02:00
parent 64f0b7d0c8
commit 97bafa3fa5
7 changed files with 78 additions and 17 deletions

View File

@ -21,6 +21,10 @@ public final class Logging {
* Folder the log files are stored in, relative to the file containing the class * Folder the log files are stored in, relative to the file containing the class
*/ */
private static final String LOG_FOLDER_NAME = "logs/"; private static final String LOG_FOLDER_NAME = "logs/";
/**
* Format for the date time used for log files
*/
private static final String DATE_TIME_FORMAT = "yyyy-MM-dd_HH-mm-ss";
/** /**
* Initialize the global system logger. * Initialize the global system logger.
@ -35,17 +39,30 @@ public final class Logging {
LOGGER.setLevel(level); LOGGER.setLevel(level);
} }
/**
* Add a console log handler writing to the applications stderr
* @param level the level to set the handler to
*/
private static void createConsoleLogger(Level level) { private static void createConsoleLogger(Level level) {
var ch = new ConsoleHandler(); var ch = new ConsoleHandler();
ch.setLevel(level); ch.setLevel(level);
LOGGER.addHandler(ch); LOGGER.addHandler(ch);
} }
/**
* Create a log handler writing to a file.
* The file will be located in a folder directly besides the application
* with the name LOG_FOLDER_NAME. The name will follow the format DATE_TIME_FORMAT plus "log" as
* file extension.
* @param level the log level to set the handler to
*/
private static void createFileLogger(Level level) { private static void createFileLogger(Level level) {
// setup log file name
var now = LocalDateTime.now(); var now = LocalDateTime.now();
var dateTime = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss").format(now); var dateTime = DateTimeFormatter.ofPattern(DATE_TIME_FORMAT).format(now);
var logFileName = LOG_FOLDER_NAME + dateTime + ".log"; var logFileName = LOG_FOLDER_NAME + dateTime + ".log";
// setup the folder for the logs
initializeLogFolder(); initializeLogFolder();
try { try {
@ -57,6 +74,10 @@ public final class Logging {
} }
} }
/**
* Checks if the folder containing log files is present.
* If the folder does not exist, the function will create a new folder.
*/
private static void initializeLogFolder() { private static void initializeLogFolder() {
var folderPath = Path.of(LOG_FOLDER_NAME); var folderPath = Path.of(LOG_FOLDER_NAME);

View File

@ -47,6 +47,13 @@ public final class Main {
getInstance().showLoginScreen(); getInstance().showLoginScreen();
} }
/**
* Set the look and feel via the ui manager.
* This function will select a look and feel so that the application will
* look most like a native application.
* It will select the systems look and feel for Windows and MacOS
* and GTK for unix based systems.
*/
private static void setPlatformDependingTheme() { private static void setPlatformDependingTheme() {
// default look and feel // default look and feel
var laf = UIManager.getCrossPlatformLookAndFeelClassName(); var laf = UIManager.getCrossPlatformLookAndFeelClassName();

View File

@ -2,7 +2,6 @@ package me.teridax.jcash.gui;
import me.teridax.jcash.Logging; import me.teridax.jcash.Logging;
import me.teridax.jcash.banking.management.BankingManagementSystem; import me.teridax.jcash.banking.management.BankingManagementSystem;
import me.teridax.jcash.lang.Translator;
import javax.swing.*; import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;

View File

@ -5,6 +5,7 @@ import me.teridax.jcash.banking.management.Profile;
/** /**
* Listens for changes in a selected account. * Listens for changes in a selected account.
*/ */
@FunctionalInterface
public interface AccountSelectionListener { public interface AccountSelectionListener {
/** /**

View File

@ -1,14 +1,22 @@
package me.teridax.jcash.gui.login; package me.teridax.jcash.gui.login;
import javax.swing.*; import javax.swing.*;
import javax.swing.text.NumberFormatter; import javax.swing.text.*;
import java.awt.*; import java.awt.*;
import java.text.NumberFormat; import java.text.NumberFormat;
import static java.awt.BorderLayout.NORTH;
import static javax.swing.SwingConstants.CENTER;
import static me.teridax.jcash.lang.Translator.translate; import static me.teridax.jcash.lang.Translator.translate;
public class LoginView extends JPanel { public class LoginView extends JPanel {
/**
* Maximum number of decimal digits that can be stored lossless by a 32-bit signed integer.
* N = log10(2^32-1) = 9,632959861146281
*/
private static final int MAX_PIN_DECIMAL_DIGITS = 9;
private JFormattedTextField blz; private JFormattedTextField blz;
private JFormattedTextField iban; private JFormattedTextField iban;
private JPasswordField pin; private JPasswordField pin;
@ -25,7 +33,7 @@ public class LoginView extends JPanel {
this.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8)); this.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
this.setLayout(new BorderLayout(16, 16)); this.setLayout(new BorderLayout(16, 16));
this.add(new JScrollPane(content), BorderLayout.CENTER); this.add(new JScrollPane(content), BorderLayout.CENTER);
this.add(new JLabel(translate("Cashmachine")), BorderLayout.NORTH); this.add(new JLabel("<html><h1>" + translate("Cashmachine") + "</b></html>", CENTER), NORTH);
var constraints = new GridBagConstraints(); var constraints = new GridBagConstraints();
@ -49,6 +57,26 @@ public class LoginView extends JPanel {
this.iban = new JFormattedTextField(getNumberFormat()); this.iban = new JFormattedTextField(getNumberFormat());
this.pin = new JPasswordField(); this.pin = new JPasswordField();
this.login = new JButton(translate("Login")); this.login = new JButton(translate("Login"));
restrictPasswordToDigits();
}
/**
* Adds a document filter onto {@link #pin} that filters out everything that is not a digit.
* The filter also restricts the amount of digits that can be entered to {@link #MAX_PIN_DECIMAL_DIGITS}
*/
private void restrictPasswordToDigits() {
((AbstractDocument) this.pin.getDocument()).setDocumentFilter(new DocumentFilter() {
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
throws BadLocationException {
String newText = fb.getDocument().getText(0, fb.getDocument().getLength()) + text;
if (newText.matches(String.format("\\d{1,%s}", MAX_PIN_DECIMAL_DIGITS))) {
super.replace(fb, offset, length, text, attrs);
}
}
});
} }
private NumberFormatter getNumberFormat() { private NumberFormatter getNumberFormat() {

View File

@ -20,12 +20,14 @@ public class TransferData {
* @throws IllegalArgumentException if the bank or the account do not exist * @throws IllegalArgumentException if the bank or the account do not exist
*/ */
public void transferValue(double amount, String blz, String ibanString) throws IllegalArgumentException { public void transferValue(double amount, String blz, String ibanString) throws IllegalArgumentException {
// get bank to transfer to
var bank = bms.getBank(blz); var bank = bms.getBank(blz);
if (bank.isEmpty()) { if (bank.isEmpty()) {
Logging.LOGGER.warning("Bank not found: " + blz); Logging.LOGGER.warning("Bank not found: " + blz);
throw new IllegalArgumentException("Bank not found: " + blz); throw new IllegalArgumentException("Bank not found: " + blz);
} }
// validate iban of target account
var iban = 0; var iban = 0;
try { try {
iban = StringDecoder.decodeUniqueIdentificationNumber(ibanString); iban = StringDecoder.decodeUniqueIdentificationNumber(ibanString);
@ -34,6 +36,7 @@ public class TransferData {
throw new IllegalArgumentException("IBAN has invalid format: " + ibanString); throw new IllegalArgumentException("IBAN has invalid format: " + ibanString);
} }
// get account to transfer value to
var account = bank.get().getAccount(iban); var account = bank.get().getAccount(iban);
if (account.isEmpty()) { if (account.isEmpty()) {
Logging.LOGGER.warning("Account not found: " + iban); Logging.LOGGER.warning("Account not found: " + iban);

View File

@ -3,12 +3,14 @@ package me.teridax.jcash.gui.transfer;
import me.teridax.jcash.Logging; import me.teridax.jcash.Logging;
import me.teridax.jcash.banking.accounts.Account; import me.teridax.jcash.banking.accounts.Account;
import me.teridax.jcash.banking.management.BankingManagementSystem; import me.teridax.jcash.banking.management.BankingManagementSystem;
import me.teridax.jcash.lang.Translator;
import static javax.swing.JOptionPane.ERROR_MESSAGE; import static javax.swing.JOptionPane.ERROR_MESSAGE;
import static javax.swing.JOptionPane.showMessageDialog; import static javax.swing.JOptionPane.showMessageDialog;
import static me.teridax.jcash.lang.Translator.translate; import static me.teridax.jcash.lang.Translator.translate;
/**
* Dialog class for transferring some value from one account to another
*/
public class TransferDialog { public class TransferDialog {
private final Account account; private final Account account;
@ -20,21 +22,21 @@ public class TransferDialog {
this.account = account; this.account = account;
this.onDeposit = onDeposit; this.onDeposit = onDeposit;
transferView = new TransferView(); this.transferView = new TransferView();
transferData = new TransferData(bms); this.transferData = new TransferData(bms);
transferView.getTransfer().addActionListener(e -> transfer()); this.transferView.getTransfer().addActionListener(e -> transfer());
transferView.getCancel().addActionListener(e -> transferView.dispose()); this.transferView.getCancel().addActionListener(e -> transferView.dispose());
transferView.showDialog(); this.transferView.showDialog();
} }
private void transfer() { private void transfer() {
try { try {
var amount = transferView.getAmount(); var amount = transferView.getAmount();
account.takeoff(amount); this.account.takeoff(amount);
transferData.transferValue(amount, transferView.getBlz(), transferView.getIban()); this.transferData.transferValue(amount, transferView.getBlz(), transferView.getIban());
onDeposit.run(); this.onDeposit.run();
transferView.dispose(); this.transferView.dispose();
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
Logging.LOGGER.severe("Could not transfer: " + ex.getMessage()); Logging.LOGGER.severe("Could not transfer: " + ex.getMessage());
showMessageDialog(null, translate("Invalid account"), translate("Could not transfer"), ERROR_MESSAGE); showMessageDialog(null, translate("Invalid account"), translate("Could not transfer"), ERROR_MESSAGE);