minor fixes
This commit is contained in:
parent
64f0b7d0c8
commit
97bafa3fa5
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -5,6 +5,7 @@ import me.teridax.jcash.banking.management.Profile;
|
|||
/**
|
||||
* Listens for changes in a selected account.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface AccountSelectionListener {
|
||||
|
||||
/**
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue