英文:
Java text field for credit card number only showing last 4 digits
问题
我必须为一门课程使用Java创建一个超市应用程序,其中许多要求之一是在进行购买时要求输入信用卡/借记卡数据,当用户填写信用卡号字段时,只显示最后四位数字,类似于XXXXXXXXXXXX1456。
我正在使用Java Swing来创建GUI,尝试使用格式化字段、密码字段和普通字段,但似乎找不到一种方法,在填写时仅显示最后四位数字。
英文:
I have to do a supermarket app in Java for a class, one of the many requirements is that when a purchase is being made it asks for the credit/debit card data, and when the user fills the credit card number field it only displays the last four digits, something like XXXXXXXXXXXX1456
I am using Java Swing for the GUI and I have tried to use the formatted field, the password field and a normal field and I can´t seem to find a way to make it only display the last four digits when is being filled.
答案1
得分: 1
A [`JFormattedTextField`][1] has a *formatter factory*. I looked at the code of the default *formatter factory* – which is class `DefaultFormatterFactory` – and tried to adapt it to your requirements.
That class defines several *formatter* classes: one for when the `JFormattedTextField` is in *edit* mode, i.e. it has the keyboard focus and another for *display* mode, i.e. when the `JFormattedTextField` does **not** have keyboard focus.
In the below code I created a `CreditCardFormatterFactory` class as well as a `CreditCardEditFormatter` class and a `CreditCardDisplayFormatter` class.
Note that I may have misunderstood your requirements, so the below code may not be exactly what you require but I would like to think that it is good enough for you to be able to adapt it to your exact requirements.
```java
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.text.ParseException;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class FtfTest {
private void buildAndDisplayGui() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createFormattedTextField(), BorderLayout.PAGE_START);
frame.add(createButton(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createFormattedTextField() {
JPanel panel = new JPanel();
JLabel label = new JLabel("Credit Card Number");
panel.add(label);
JFormattedTextField creditCardFormattedTextField = new JFormattedTextField(
new CreditCardFormatterFactory());
creditCardFormattedTextField.setColumns(16);
panel.add(creditCardFormattedTextField);
return panel;
}
private JPanel createButton() {
JPanel panel = new JPanel();
JButton button = new JButton("Exit");
button.addActionListener(e -> System.exit(0));
panel.add(button);
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new FtfTest().buildAndDisplayGui());
}
}
class CreditCardFormatterFactory extends JFormattedTextField.AbstractFormatterFactory {
/** {@code JFormattedTextField.AbstractFormatter} to use for display. */
private JFormattedTextField.AbstractFormatter displayFormat;
/** {@code JFormattedTextField.AbstractFormatter} to use for editing. */
private JFormattedTextField.AbstractFormatter editFormat;
/** {@code JFormattedTextField.AbstractFormatter} to use if the value is null. */
private JFormattedTextField.AbstractFormatter nullFormat;
public CreditCardFormatterFactory() {
displayFormat = new CreditCardDisplayFormatter();
editFormat = new CreditCardEditFormatter();
}
@Override
public AbstractFormatter getFormatter(JFormattedTextField ftf) {
JFormattedTextField.AbstractFormatter format = null;
if (ftf != null) {
if (ftf.hasFocus()) {
format = getEditFormatter();
}
else {
format = getDisplayFormatter();
}
}
return format;
}
public JFormattedTextField.AbstractFormatter getDisplayFormatter() {
return displayFormat;
}
public JFormattedTextField.AbstractFormatter getEditFormatter() {
return editFormat;
}
public JFormattedTextField.AbstractFormatter getNullFormatter() {
return nullFormat;
}
}
class CreditCardDisplayFormatter extends JFormattedTextField.AbstractFormatter {
@Override
public Object stringToValue(String text) throws ParseException {
System.out.printf("CreditCardDisplayFormatter.stringToValue( ^%s^ )%n", text);
return text;
}
@Override
public String valueToString(Object value) throws ParseException {
System.out.printf("CreditCardDisplayFormatter.valueToString( ^%s^ )%n",
String.valueOf(value));
String str = value == null ? "" : value.toString();
if (str.length() > 0) {
if (str.length() > 12) {
str = "XXXXXXXXXXXX" + str.substring(12);
}
else {
str = str.replaceAll("\\d", "X");
}
}
return str;
}
}
class CreditCardEditFormatter extends JFormattedTextField.AbstractFormatter {
@Override
public Object stringToValue(String text) throws ParseException {
System.out.printf("CreditCardEditFormatter.stringToValue( ^%s^ )%n", text);
return text;
}
@Override
public String valueToString(Object value) throws ParseException {
System.out.printf("CreditCardEditFormatter.valueToString( ^%s^ )%n",
String.valueOf(value));
return value == null ? null : value.toString();
}
}
英文:
A JFormattedTextField
has a formatter factory. I looked at the code of the default formatter factory – which is class DefaultFormatterFactory
– and tried to adapt it to your requirements.
That class defines several formatter classes: one for when the JFormattedTextField
is in edit mode, i.e. it has the keyboard focus and another for display mode, i.e. when the JFormattedTextField
does not have keyboard focus.
In the below code I created a CreditCardFormatterFactory
class as well as a CreditCardEditFormatter
class and a CreditCardDisplayFormatter
class.
Note that I may have misunderstood your requirements, so the below code may not be exactly what you require but I would like to think that it is good enough for you to be able to adapt it to your exact requirements.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.text.ParseException;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class FtfTest {
private void buildAndDisplayGui() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createFormattedTextField(), BorderLayout.PAGE_START);
frame.add(createButton(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createFormattedTextField() {
JPanel panel = new JPanel();
JLabel label = new JLabel("Credit Card Number");
panel.add(label);
JFormattedTextField creditCardFormattedTextField = new JFormattedTextField(
new CreditCardFormatterFactory());
creditCardFormattedTextField.setColumns(16);
panel.add(creditCardFormattedTextField);
return panel;
}
private JPanel createButton() {
JPanel panel = new JPanel();
JButton button = new JButton("Exit");
button.addActionListener(e -> System.exit(0));
panel.add(button);
return panel;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new FtfTest().buildAndDisplayGui());
}
}
class CreditCardFormatterFactory extends JFormattedTextField.AbstractFormatterFactory {
/** {@code JFormattedTextField.AbstractFormatter} to use for display. */
private JFormattedTextField.AbstractFormatter displayFormat;
/** {@code JFormattedTextField.AbstractFormatter} to use for editing. */
private JFormattedTextField.AbstractFormatter editFormat;
/** {@code JFormattedTextField.AbstractFormatter} to use if the value is null. */
private JFormattedTextField.AbstractFormatter nullFormat;
public CreditCardFormatterFactory() {
displayFormat = new CreditCardDisplayFormatter();
editFormat = new CreditCardEditFormatter();
}
@Override
public AbstractFormatter getFormatter(JFormattedTextField ftf) {
JFormattedTextField.AbstractFormatter format = null;
if (ftf != null) {
if (ftf.hasFocus()) {
format = getEditFormatter();
}
else {
format = getDisplayFormatter();
}
}
return format;
}
public JFormattedTextField.AbstractFormatter getDisplayFormatter() {
return displayFormat;
}
public JFormattedTextField.AbstractFormatter getEditFormatter() {
return editFormat;
}
public JFormattedTextField.AbstractFormatter getNullFormatter() {
return nullFormat;
}
}
class CreditCardDisplayFormatter extends JFormattedTextField.AbstractFormatter {
@Override
public Object stringToValue(String text) throws ParseException {
System.out.printf("CreditCardDisplayFormatter.stringToValue( ^%s^ )%n", text);
return text;
}
@Override
public String valueToString(Object value) throws ParseException {
System.out.printf("CreditCardDisplayFormatter.valueToString( ^%s^ )%n",
String.valueOf(value));
String str = value == null ? "" : value.toString();
if (str.length() > 0) {
if (str.length() > 12) {
str = "XXXXXXXXXXXX" + str.substring(12);
}
else {
str = str.replaceAll("\\d", "X");
}
}
return str;
}
}
class CreditCardEditFormatter extends JFormattedTextField.AbstractFormatter {
@Override
public Object stringToValue(String text) throws ParseException {
System.out.printf("CreditCardEditFormatter.stringToValue( ^%s^ )%n", text);
return text;
}
@Override
public String valueToString(Object value) throws ParseException {
System.out.printf("CreditCardEditFormatter.valueToString( ^%s^ )%n",
String.valueOf(value));
return value == null ? null : value.toString();
}
}
答案2
得分: 0
String number = "6235761255231456";
String mask = number.replaceAll("\\d(?=\\d{4})", "X");
System.out.println(mask);
输出:
XXXXXXXXXXXX1456
这里我们使用了replaceAll方法,它接受正则表达式作为参数,并将除了最后四位数字之外的每个数字替换为X。所使用的正则表达式是匹配除了最后四位数字之外的所有数字。
英文:
String number = "6235761255231456";
String mask = number.replaceAll("\\d(?=\\d{4})", "X");
System.out.println(mask);
OutPut:
XXXXXXXXXXXX1456
here replace we are using replaceAll method which will take regular expression as parameter and and will replace every digit with X except last four digit the following regular expression is accepting all except last 4 digit.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论