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
*/
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.
@ -35,17 +39,30 @@ public final class Logging {
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) {
var ch = new ConsoleHandler();
ch.setLevel(level);
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) {
// setup log file name
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";
// setup the folder for the logs
initializeLogFolder();
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() {
var folderPath = Path.of(LOG_FOLDER_NAME);

View File

@ -47,6 +47,13 @@ public final class Main {
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() {
// default look and feel
var laf = UIManager.getCrossPlatformLookAndFeelClassName();

View File

@ -2,7 +2,6 @@ package me.teridax.jcash.gui;
import me.teridax.jcash.Logging;
import me.teridax.jcash.banking.management.BankingManagementSystem;
import me.teridax.jcash.lang.Translator;
import javax.swing.*;
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.
*/
@FunctionalInterface
public interface AccountSelectionListener {
/**

View File

@ -1,14 +1,22 @@
package me.teridax.jcash.gui.login;
import javax.swing.*;
import javax.swing.text.NumberFormatter;
import javax.swing.text.*;
import java.awt.*;
import java.text.NumberFormat;
import static java.awt.BorderLayout.NORTH;
import static javax.swing.SwingConstants.CENTER;
import static me.teridax.jcash.lang.Translator.translate;
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 iban;
private JPasswordField pin;
@ -22,15 +30,15 @@ public class LoginView extends JPanel {
private void layoutComponents() {
var content = new JPanel(new GridBagLayout());
this.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
this.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
this.setLayout(new BorderLayout(16, 16));
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();
constraints.gridwidth = 4;
constraints.insets = new Insets(12,12,12,12);
constraints.insets = new Insets(12, 12, 12, 12);
addInputRow(constraints, content, blz, 1, translate("BLZ"));
addInputRow(constraints, content, iban, 2, translate("IBAN"));
@ -40,7 +48,7 @@ public class LoginView extends JPanel {
constraints.anchor = GridBagConstraints.PAGE_END;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(12,12,12,12);
constraints.insets = new Insets(12, 12, 12, 12);
content.add(login, constraints);
}
@ -49,6 +57,26 @@ public class LoginView extends JPanel {
this.iban = new JFormattedTextField(getNumberFormat());
this.pin = new JPasswordField();
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() {

View File

@ -20,12 +20,14 @@ public class TransferData {
* @throws IllegalArgumentException if the bank or the account do not exist
*/
public void transferValue(double amount, String blz, String ibanString) throws IllegalArgumentException {
// get bank to transfer to
var bank = bms.getBank(blz);
if (bank.isEmpty()) {
Logging.LOGGER.warning("Bank not found: " + blz);
throw new IllegalArgumentException("Bank not found: " + blz);
}
// validate iban of target account
var iban = 0;
try {
iban = StringDecoder.decodeUniqueIdentificationNumber(ibanString);
@ -34,6 +36,7 @@ public class TransferData {
throw new IllegalArgumentException("IBAN has invalid format: " + ibanString);
}
// get account to transfer value to
var account = bank.get().getAccount(iban);
if (account.isEmpty()) {
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.banking.accounts.Account;
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.showMessageDialog;
import static me.teridax.jcash.lang.Translator.translate;
/**
* Dialog class for transferring some value from one account to another
*/
public class TransferDialog {
private final Account account;
@ -20,21 +22,21 @@ public class TransferDialog {
this.account = account;
this.onDeposit = onDeposit;
transferView = new TransferView();
transferData = new TransferData(bms);
transferView.getTransfer().addActionListener(e -> transfer());
transferView.getCancel().addActionListener(e -> transferView.dispose());
transferView.showDialog();
this.transferView = new TransferView();
this.transferData = new TransferData(bms);
this.transferView.getTransfer().addActionListener(e -> transfer());
this.transferView.getCancel().addActionListener(e -> transferView.dispose());
this.transferView.showDialog();
}
private void transfer() {
try {
var amount = transferView.getAmount();
account.takeoff(amount);
transferData.transferValue(amount, transferView.getBlz(), transferView.getIban());
onDeposit.run();
transferView.dispose();
this.account.takeoff(amount);
this.transferData.transferValue(amount, transferView.getBlz(), transferView.getIban());
this.onDeposit.run();
this.transferView.dispose();
} catch (IllegalArgumentException ex) {
Logging.LOGGER.severe("Could not transfer: " + ex.getMessage());
showMessageDialog(null, translate("Invalid account"), translate("Could not transfer"), ERROR_MESSAGE);