我们正在寻找一种方法来为JTextField保留两种类型的文本
最后,实际文本将保存在我们的数据库不是显示文本
中我们为Display BUT创建了文本转换器,但我们不知道如何将此场景应用于JTextField
答案 0 :(得分:0)
我经历了这个,我提出了这个解决方案。
首先我们需要在他们的操作系统中选择波斯语/阿拉伯语键盘时显示用户波斯语/阿拉伯语数字,并且他们在JTextField中键入数字。为此,我编写了这个自定义DocumentFilter:
public class PersianNumberDocumentFilter extends DocumentFilter {
private static final String REPLACE_CHARS = "0123456789.";
@Override
public void insertString(FilterBypass fb, int offset, String text,
AttributeSet attr) throws BadLocationException {
if (text != null && !text.isEmpty() && REPLACE_CHARS.contains(text)) {
text = doSwap(text);
}
super.insertString(fb, offset, text, attr);
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text,
AttributeSet attrs) throws BadLocationException {
if (text != null && !text.isEmpty() && REPLACE_CHARS.contains(text)) {
text = doSwap(text);
}
super.replace(fb, offset, length, text, attrs);
}
@Override
public void remove(FilterBypass fb, int offset, int length)
throws BadLocationException {
super.remove(fb, offset, length);
}
public String doSwap(String text) {
InputContext context = InputContext.getInstance();
String windowsKeyboardSelected = context.getLocale().toString();
if (!windowsKeyboardSelected.contains("fa") && !windowsKeyboardSelected.contains("ar")) {
return text;
}
StringBuilder sb = new StringBuilder();
for (char c : text.toCharArray()) {
if (REPLACE_CHARS.contains(String.valueOf(c))) {
if (c == '.') {
c = ',';
} else {
c = (char) ('\u06F0' - '0' + c);
//c = (char) ('\u0660' - '0' + c); Arabic Number Digits
}
}
sb.append(c);
}
return sb.toString();
}
}
接下来,我们需要一个实用程序类,用于从波斯语/阿拉伯语进行数字和文本转换。我为这件事写了这个实用程序类:
public class PersianNumber {
private static HashMap<Character, String> unicodeMap = new HashMap<>();
private static HashMap<Character, String> unicodeMapArabic = new HashMap<>();
private static HashMap<Character, String> unicodeMapViceVera = new HashMap<>();
static {
//English/Persian Numbers Map
unicodeMap.put('0', "\u06F0");
unicodeMap.put('1', "\u06F1");
unicodeMap.put('2', "\u06F2");
unicodeMap.put('3', "\u06F3");
unicodeMap.put('4', "\u06F4");
unicodeMap.put('5', "\u06F5");
unicodeMap.put('6', "\u06F6");
unicodeMap.put('7', "\u06F7");
unicodeMap.put('8', "\u06F8");
unicodeMap.put('9', "\u06F9");
//English/Arabic Numbers Map
unicodeMapArabic.put('0',"\u0660");
unicodeMapArabic.put('1',"\u0661");
unicodeMapArabic.put('2',"\u0662");
unicodeMapArabic.put('3',"\u0663");
unicodeMapArabic.put('4',"\u0664");
unicodeMapArabic.put('5',"\u0665");
unicodeMapArabic.put('6',"\u0666");
unicodeMapArabic.put('7',"\u0667");
unicodeMapArabic.put('8',"\u0668");
unicodeMapArabic.put('9',"\u0669");
//Persian English Numbers Map
unicodeMapViceVera.put('\u06F0', "0");
unicodeMapViceVera.put('\u06F1', "1");
unicodeMapViceVera.put('\u06F2', "2");
unicodeMapViceVera.put('\u06F3', "3");
unicodeMapViceVera.put('\u06F4', "4");
unicodeMapViceVera.put('\u06F5', "5");
unicodeMapViceVera.put('\u06F6', "6");
unicodeMapViceVera.put('\u06F7', "7");
unicodeMapViceVera.put('\u06F8', "8");
unicodeMapViceVera.put('\u06F9', "9");
//Arabic English Numbers Map
unicodeMapViceVera.put('\u0660', "0");
unicodeMapViceVera.put('\u0661', "1");
unicodeMapViceVera.put('\u0662', "2");
unicodeMapViceVera.put('\u0663', "3");
unicodeMapViceVera.put('\u0664', "4");
unicodeMapViceVera.put('\u0665', "5");
unicodeMapViceVera.put('\u0666', "6");
unicodeMapViceVera.put('\u0667', "7");
unicodeMapViceVera.put('\u0668', "8");
unicodeMapViceVera.put('\u0669', "9");
}
public static String getPersianNumber(String englishNumber) {
if (!englishNumber.matches("-?\\d+(\\.\\d+)?")) {
throw new NumberFormatException("the input [" + englishNumber + "] is not a number!");
}
char[] numChars = englishNumber.toCharArray();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < numChars.length; i++) {
builder.append(unicodeMap.get(numChars[i]));
}
return builder.toString();
}
public static String getEnglishNumber(String persianNumber) {
char[] numChars = persianNumber.toCharArray();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < numChars.length; i++) {
String value = unicodeMapViceVera.get(numChars[i]);
if(value == null){
builder.setLength(0);
builder.append(persianNumber);
break;
}
builder.append(unicodeMapViceVera.get(numChars[i]));
}
return builder.toString();
}
public static boolean isAPersianNumber(String persianNumber){
char[] numChars = persianNumber.toCharArray();
for (int i = 0; i < numChars.length; i++) {
String value = unicodeMapViceVera.get(numChars[i]);
if(value == null){
return false;
}
}
return true;
}
public static String convertToStringWithPersianNumber(String input){
StringBuilder sb = new StringBuilder();
for(char c : input.toCharArray()){
String ch = unicodeMap.get(c);
if(ch != null){
sb.append(ch);
continue;
}
sb.append(c);
}
return sb.toString();
}
public static String convertToStringWithEnglishNumber(String input){
StringBuilder sb = new StringBuilder();
for(char c : input.toCharArray()){
String ch = unicodeMapViceVera.get(c);
if(ch != null){
sb.append(ch);
continue;
}
sb.append(c);
}
return sb.toString();
}
public static void main(String[] args) {
System.out.println(getEnglishNumber("۹۶۵۹۴۵۴"));
System.out.println(getPersianNumber("9999999999999651221"));
System.out.println(getPersianNumber(59683399623213L + ""));
}
}
最后我们需要一个自定义JTextField,因为我们需要控制输入和输出,并根据我们的需要进行相应的转换:
public class JPersianTextField2 extends JTextField {
public JPersianTextField2() {
// Hopefully someday (Oracle Love Iranians) and create This Locale for us
Locale locale = new Locale("fa", "IR");
// Locale locale = new Locale("ar", "KW");
ComponentOrientation farsiOrientation = ComponentOrientation.getOrientation(locale);
super.applyComponentOrientation(farsiOrientation);
PlainDocument doc = (PlainDocument) super.getDocument();
doc.setDocumentFilter(new PersianNumberDocumentFilter());
super.setColumns(25);
}
@Override
public String getText() {
String tmp = super.getText();
if (tmp != null && !tmp.isEmpty())
return PersianNumber2.convertToStringWithEnglishNumber(tmp);
else
return super.getText();
}
@Override
public void setText(String t) {
if (t != null && !t.isEmpty())
super.setText(PersianNumber2.convertToStringWithPersianNumber(t));
}
}
使用此自定义JTextField,当您想要获取JTextField的结果并在您想要设置具有英文数字的字符串时转换为波斯数字,您可以转换为英文数字。
最后,这是对组件的测试:
public class MyFormatterTest extends JFrame {
public MyFormatterTest() {
setTitle("Example");
JPanel panel = new JPanel();
JLabel label = new JLabel("text :");
JPersianTextField2 tf = new JPersianTextField2();
tf.setText("سلام من مهدی هستم برنامه نویس ارشد 31 ساله"); //Hi This is mehdi, 31 years old Sr. software developer
panel.add(label);
panel.add(tf);
JButton button2 = new JButton();
button2.setText("getText");
button2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(tf.getText());
}
});
panel.add(button2);
getContentPane().add(panel, BorderLayout.SOUTH);
pack();
}
public static void main(String[] args) {
//Available Locales inside Your JVM
for (Locale l : Locale.getAvailableLocales()) {
System.out.println(l.getCountry() + ":" + l.getLanguage());
}
MyFormatterTest mfe = new MyFormatterTest();
mfe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mfe.setVisible(true);
}
}
希望这对你有用......