JCash/src/me/teridax/jcash/gui/login/LoginView.java

126 lines
4.1 KiB
Java

package me.teridax.jcash.gui.login;
import javax.swing.*;
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;
private JButton login;
public LoginView() {
createComponents();
layoutComponents();
}
private void layoutComponents() {
var content = new JPanel(new GridBagLayout());
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("<html><h1>" + translate("Cashmachine") + "</b></html>", CENTER), NORTH);
var constraints = new GridBagConstraints();
constraints.gridwidth = 4;
constraints.insets = new Insets(12, 12, 12, 12);
addInputRow(constraints, content, blz, 1, translate("BLZ"));
addInputRow(constraints, content, iban, 2, translate("IBAN"));
addInputRow(constraints, content, pin, 3, translate("PIN"));
constraints.gridy = 4;
constraints.anchor = GridBagConstraints.PAGE_END;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(12, 12, 12, 12);
content.add(login, constraints);
}
private void createComponents() {
this.blz = new JFormattedTextField();
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() {
var format = NumberFormat.getIntegerInstance();
format.setGroupingUsed(false);
var formatter = new NumberFormatter(format);
formatter.setValueClass(Integer.class);
formatter.setMinimum(0);
formatter.setMaximum(Integer.MAX_VALUE);
formatter.setAllowsInvalid(false);
return formatter;
}
private void addInputRow(GridBagConstraints constraints, JComponent target, JComponent comp, int row, String name) {
constraints.gridwidth = 1;
constraints.gridx = 1;
constraints.gridy = row;
constraints.weightx = 0;
constraints.fill = GridBagConstraints.HORIZONTAL;
target.add(new JLabel(name, SwingConstants.RIGHT), constraints);
constraints.gridx = 2;
constraints.gridy = row;
constraints.weightx = 1;
constraints.fill = GridBagConstraints.HORIZONTAL;
target.add(comp, constraints);
}
public JTextField getBlz() {
return blz;
}
public JTextField getIban() {
return iban;
}
public JPasswordField getPin() {
return pin;
}
public JButton getLogin() {
return login;
}
}