Hot questions for Using JTextField in numbers

Question:

I am trying to make calculator and i have an issue with JTextField. When I click numbers(JButtons) like 1,2,3,4,5 , they appears on JTextField like 54321. So, how can i change this to show 12345 instead of 54321?

public void actionPerformed(ActionEvent e) {

    JButton clickedButton = (JButton) e.getSource();


    String displayValue = parent.getDisplayValue();

    String clickedBtnValue = clickedButton.getText();

    parent.setDisplayValue(clickedBtnValue + displayValue); 

contentPane = new JPanel();
    textField = new JTextField(30);
    textField.setAlignmentX(Component.LEFT_ALIGNMENT);
    contentPane.add(textField);
    textField.setHorizontalAlignment(JTextField.RIGHT);
    textField.setBounds(10, 11, 152, 32);
    textField.setColumns(1);
    textField.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    textField.addActionListener(eng);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 184, 312);

    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

Answer:

Did you really think about this BEFORE you asked the question?

You are in control of your code so you should understand what your code is doing:

parent.setDisplayValue(clickedBtnValue + displayValue); 

The code is doing exactly what you tell it to do - the button text is appended before the existing text.

If you don't like it displayed that way then you can try:

parent.setDisplayValue(displayValue + clickedBtnValue); 

If you want a better solution, you can use the replaceSelection(...) method as demonstrated in: How to add a shortcut key for a jbutton in java?

Question:

I have a JTextField that I have overridden the Document for, so that I can prevent the user from entering some characters. The way this works is my extension of Document receives a Regex in its constructor, then checks anything the user types against the Regex:

public class ValidDocument extends PlainDocument
{
    private String regex;

    public ValidDocument(String regex)
    {
        this.regex = regex;
    }

    @Override
    public void insertString(int offs, String str, AttributeSet a)
    {
        if(str == null) return;

        try
        {
            if((this.getText(0, getLength()) + str).matches(regex))
                super.insertString(offs, str, a);
        }
        catch(BadLocationException ble)
        {
            System.out.println("Came across a BadLocationException");
        }
    }
}

I had an issue however, where a JTextField that I wanted to display only valid float/double numbers in wasn't displaying its initial value. The code I was using is below:

float value = 25.0f;
JTextField textField = new JTextField("" + value);
textField.setDocument(new ValidDocument("^(\\-)?\\d*(\\.)?\\d*$"));

So the JTextField displayed, but there was no initial value. I tried to enter 25.0 into the field and it accepted it I had originally expected it would. After a bit of stuffing around, I tried adding:

textField.setText("" + value);

And it displayed the value. It occurred to me that it might accept anything I tried to put in setText(), so I added alphabetic characters to it:

textField.setText("as" + value);

As I suspected, it included the alphabetic characters, even though the Regex should have prevented that. So my thoughts are that the Document is bypassed when using this function.

Can anyone shed some light on why applying the ValidDocument to my JTextField is removing the text I placed in the constructor of the text field? I have other JTextFields with less restrictive Regex's that still display the value I set in the constructor. And why would it be overriding the value passed into the constructor, but not the one passed into setText()?


Answer:

Don't use PlainDocument, use a DocumentFilter, it's what it is deisnged for. The method you're attempting to use has been out of date for more than 10 years, for example...

public class PatternFilter extends DocumentFilter {

    // Useful for every kind of input validation !
    // this is the insert pattern
    // The pattern must contain all subpatterns so we can enter characters into a text component !
    private Pattern pattern;

    public PatternFilter(String pat) {
        pattern = Pattern.compile(pat);
    }

    public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
            throws BadLocationException {

        String newStr = fb.getDocument().getText(0, fb.getDocument().getLength()) + string;
        Matcher m = pattern.matcher(newStr);
        if (m.matches()) {
            super.insertString(fb, offset, string, attr);
        } else {
        }
    }

    public void replace(FilterBypass fb, int offset,
                        int length, String string, AttributeSet attr) throws
            BadLocationException {

        if (length > 0) fb.remove(offset, length);
        insertString(fb, offset, string, attr);
    }
}

Which comes from this DocumentFilter Examples

Take a look at Implementing a Document Filter for more details

If you don't need real time filtering, another option would be to use a JFormattedTextField or JSpinner. See How to Use Formatted Text Fields and How to Use Spinners for more details

Question:

I'm trying to set up a program to help myself at work but I still can't cause, I can't add digit numbers to be allowed in this code:

char inte=evt.getKeyChar();
    if (!(Character.isDigit(inte)|| inte==KeyEvent.VK_BACK_SPACE) || inte==KeyEvent.VK_DELETE){
    getToolkit().beep();
        evt.consume();

So, im trying to get to a point to be able to add commas because i need to use floats.

Any ideas?


Answer:

This piece of code should help you:

char c = evt.getKeyChar();
if (!(Character.isDigit(c) || c == KeyEvent.VK_COMMA || c == KeyEvent.VK_DELETE || c == KeyEvent.VK_BACK_SPACE)) {
    getToolkit().beep();
    evt.consume();
}

Question:

I want that my text field accept only numbers (digit) and one dot, because it is a field in which the user can write the price of products. I have this code but it doesn't work well, it only accept numbers and delete.

char c=evt.getKeyChar();
if(!(Character.isDigit(c))||(c==KeyEvent.VK_BACK_SPACE)||(c==KeyEvent.VK_DELETE)){
    getToolkit().beep();
    evt.consume();
}

Can someone help me to fix it?


Answer:

I found a solution for this problem: this is the code i wrote

char c=evt.getKeyChar();
        if((Character.isDigit(c))||(c==KeyEvent.VK_PERIOD)||(c==KeyEvent.VK_BACK_SPACE)){
            int punto=0;
            if(c==KeyEvent.VK_PERIOD){ 
                        String s=pricefield.getText();
                        int dot=s.indexOf('.');
                        punto=dot;
                        if(dot!=-1){
                            getToolkit().beep();
                            evt.consume();
                        }
                    }
        }
        else{    
            getToolkit().beep();
            evt.consume();
        }

Question:

Well, this might sound as if it is a duplicate question but it is not. I have asked this question in connection with this question here. I have rewritten my DocumentFilter to use regular expressions. In validating a person's name I want only the following characters [a-zA-Z],',\S and ..

I have written my regular expression with the hope that it will solve this. It is working the way I want it but the fact that it is not allowing numbers when I have not yet set it to do so is puzzling me.

Question: Why is regex not allowing numbers?

This is the regular expression [\\_\\(\\)@!\"#%&*+,-:;<>=?\\[\\]\\^\\~\\{\\}\\|] and what it should not allow to be entered is commented in the code below:

My DocumentFilter is as follows:

public class NameValidator extends DocumentFilter{
@Override
public void insertString(FilterBypass fb, int off
                    , String str, AttributeSet attr) 
                            throws BadLocationException 
{
    // remove 0-9 !"#$%&()*+,-/:;<=>?@[\]^_`{|}~
    fb.insertString(off, str.replaceAll("^[\\_\\(\\)@!\"#%&*+,-:;<>=?\\[\\]\\^\\~\\{\\}\\|]", ""), attr);
} 
@Override
public void replace(FilterBypass fb, int off
        , int len, String str, AttributeSet attr) 
                        throws BadLocationException 
{
    // remove 0-9 !"#$%&()*+,-/:;<=>?@[\]^_`{|}~
    fb.replace(off, len, str.replaceAll("^[\\_\\(\\)@!\"#%&*+,-:;<>=?\\[\\]\\^\\~\\{\\}\\|]", ""), attr);
   }
}

Here is my test class:

public class NameTest {

private JFrame frame;

public NameTest() throws ParseException {
    frame = new JFrame();
    initGui();
}

private void initGui() throws ParseException {

    frame.setSize(100, 100);
    frame.setVisible(true);
    frame.setLayout(new GridLayout(2, 1, 5, 5));
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTextField name = new JTextField(10);
    ((AbstractDocument)name.getDocument()).setDocumentFilter(new NameValidator());
    frame.add(name);

}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            try {
                NameTest nt = new NameTest();
            } catch (ParseException e) {

                e.printStackTrace();
            }

        }
     });
    }
  }

Answer:

The reason is this part of your regex:

,-:

Which matches any character in the range of , (ASCII 44) to : (ASCII 58), which includes all the numbers (ASCII 48-57 inclusive).

If you escape the - it should work fine and not match numbers:

[\\_\\(\\)@!\"#%&*+,\\-:;<>=?\\[\\]\\^\\~\\{\\}\\|]

Question:

Is there any way to take several different numbers using JTextField?

For example, following numeric values are given: 2.0, 3.0, 4.0. I would like to put them into ArrayList separately.

How to handle incorrect input data ​​in order to continue the typing?

    //in this case the resulst is "arList: 1.92239991"
    textField = new JTextField("1.9, 223, 9991");
    textField.addActionListener(this);
    ArrayList<Double> arList = new ArrayList<>();

    String str = textField.getText();
    String result = str.replaceAll("\\s+","");
    String otherResult = result.replaceAll(",","");
    double d = Double.parseDouble(otherResult);
    System.out.println(d);

    arList.add(d);
    for (Double anArList : arList) {
        System.out.println("arList: " +anArList);
    }

Answer:

If the numbers are always separated by , you can use String#split, which will return an array of values.

String str = textField.getText();
String[] parts = str.split(",");

This will return each value between the ,, including the white space. You could then trim these results...

for (int index = 0; index < parts.length; index++) {
    parts[index] = parts[index].trim();
}

This will now contain just the remaining text. If you must have it in a list you can use...

List<String> values = Arrays.asList(parts);

If you need it as list of Doubles, you will need to parse each element indiviudally...

List<Double> values = new ArrayList<Double>(parts.length);
for (String value : values) {
    values.add(Double.parseDouble(value));
}

This will still throw a parse exception if any one of the values is not a valid Double.

A better solution might be to use a JFormattedTextField or JSpinner to collect the individual value and add each one to a list one at a time (could display them in a JList), this would allow you to validate each value as it is entered.

Have a look at How to Use Formatted Text Fields, How to Use Spinners and How to Use Lists for more details

Question:

Having trouble guys this is for my Fahrenheit-Celsius converter class, I can't seem to get my code to recognize the following which makes sure that only numbers are entered into the text field and if not, set as 0:

try {
            Double.parseDouble(fahr.getText());
        } catch (NumberFormatException e) {
            fahr.setText("0");
        }

I think it is because of the placement of it within my class. Please check out my full class (I placed it towards the bottom of the code):

public class Temperature implements ActionListener  {

    private static JTextField fahr;
    private static JTextField cels;
    private JFrame frame;
    private JButton first;
    private JButton second;
    private double fahrVal;
    private Double fahrConv;
    private double celsVal;
    private double celsConv;
    private NumberFormat amountFormat;


    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    Temperature window = new Temperature();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Temperature() {
        initialize();
        first.addActionListener((ActionListener) this);
        second.addActionListener((ActionListener) this);
    }

    private void initialize() { 
        amountFormat = NumberFormat.getNumberInstance();
        frame = new JFrame("raB eltiT");
        frame.setBounds(100, 50, 350, 350);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        first = new JButton("...To Celsius");
        first.setBounds(130, 60, 100, 50);
        first.setBackground(Color.cyan);
        first.setActionCommand("click");
        first.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                JButton src = (JButton) ae.getSource();
                //System.out.println("Button labeled " + src.getText() + " was clicked");
            }
        });
        first.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent me) {
                 cels.setText(String.valueOf(fahrConv));
            }
        });


        frame.getContentPane().add(first);

        second = new JButton("...To Fahrenheit");
        second.setBounds(130, 230, 100, 50);
        second.setBackground(Color.pink);
        second.setActionCommand("instead");
        frame.getContentPane().add(second);
        second.addMouseListener(new MouseAdapter() {
            public void mouseReleased(MouseEvent me) {
                 fahr.setText(String.valueOf(celsConv));
            }
        });

        // Build the Fahrenheit side

        JLabel fLabel = new JLabel("Fahrenheit");
        fahr = new JTextField("32");
        fahr.setPreferredSize(new Dimension(50,50));
        fahr.setHorizontalAlignment(JTextField.CENTER);
        JPanel fPanel = new JPanel();
        fPanel.setBounds(40, 120,100,100);
        fPanel.add(fLabel);
        fPanel.add(fahr);
        frame.getContentPane().add(fPanel);


        JLabel cLabel = new JLabel("Celsius");
        cels = new JTextField("0");
        cels.setPreferredSize(new Dimension(50,50));
        cels.setHorizontalAlignment(JTextField.CENTER);
        JPanel cPanel = new JPanel();
        cPanel.setBounds(220, 120, 100,100);
        cPanel.add(cLabel);
        cPanel.add(cels);
        frame.getContentPane().add(cPanel); 


        // Put it all up on the screen

        frame.setVisible(true);  

        try {// if is number
            Double.parseDouble(fahr.getText());
        } catch (NumberFormatException e) {
            fahr.setText("0");
        }
    }
    public void actionPerformed(ActionEvent event) {
         String fahrText = fahr.getText();
         fahrVal = Double.parseDouble(fahrText);
         fahrConv = ((fahrVal - 32)*5)/9;
         fahrConv = Double.parseDouble(new DecimalFormat("##.#").format(fahrConv));

        String celsText = cels.getText();
        celsVal = Double.parseDouble(celsText);
        celsConv = 32 + (celsVal * 9 / 5);
        celsConv = Double.parseDouble(new DecimalFormat("##.#").format(celsConv));


    }
}

Answer:

The problem is not so much what you're doing but rather where and when you're doing it. You're calling

try {// if is number
    Double.parseDouble(fahr.getText());
} catch (NumberFormatException e) {
    fahr.setText("0");
}

in the code where you create the GUI, and this then happens before the user has any chance of inputting data into the JTextField, making this code useless. A better solution is to put this code into a listener that responds when the user is ready to submit the data, such as at the start of your ActionListener -- then call return:

Something like:

public void actionPerformed(ActionEvent event) {
    try {
        Double.parseDouble(fahr.getText());
    } catch (NumberFormatException e) {
        fahr.setText("0");
        // display a JOptionPane error message so the user knows there's been a problem
        return; // so the code below isn't called if input in error
    }
    String fahrText = fahr.getText();
    fahrVal = Double.parseDouble(fahrText);
    fahrConv = ((fahrVal - 32)*5)/9;
    fahrConv = Double.parseDouble(new DecimalFormat("##.#").format(fahrConv));

    String celsText = cels.getText();
    celsVal = Double.parseDouble(celsText);
    celsConv = 32 + (celsVal * 9 / 5);
    celsConv = Double.parseDouble(new DecimalFormat("##.#").format(celsConv));
}

Other options:

  • Use a JFormattedTextField
  • Or use a JSpinner
  • Or use a DocumentListener

Other unrelated issues:

  • Don't add MouseListeners to JButtons but rather use ActionListeners. Else the listener will not behave correctly. For instance, a MouseListener still will respond if the button has been disabled, whereas an ActionListener will correctly not respond in this situation.
  • Avoid null layouts and absolute positioning as this leads to rigid GUI's that are difficult to enhance, debug and that look sort-of OK on one platform and awful on all others.

Question:

I am looking for someone to help me make a JFormattedTextField. I want to to ONLY accept numbers (0-9). When a user inputs a invalid input (EX: "a"), it will not let it be inputted! I've tried other pre-made source codes but I don't know where to place it in my code! And they always cause errors...

Here is my code...

private void followerPrompt() {
    JFormattedTextField followerPrompt=new JFormattedTextField("0");  
    JFrame followerPromptWindow=new JFrame("Enter the number of followers you have:");  
    followerPromptWindow.setLayout(new GridLayout(2,1,1,1));  
    followerPromptWindow.add(followerPrompt);
    followerPromptWindow.setResizable(false);
    followerPromptWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    followerPromptWindow.setLocation(500, 400);
    followerPromptWindow.setVisible(true);  
    followerPromptWindow.setSize(promptWindowWidth * promptWindowScale,promptWindowHeight * promptWindowScale);  
    JButton followerPromptWindowButton = new JButton("Next Step");
    followerPromptWindow.add(followerPromptWindowButton);
    followerPromptWindowButton.addActionListener( new ActionListener()
    {
        public void actionPerformed(ActionEvent e) {         
            followerInput = followerPrompt.getText();
            System.out.println("Follower Input: " + followerInput);
            likePrompt();
            followerPromptWindow.dispose();
        }
    });
}

As you might see, I already have it set (and imported) to JFormattedTextField. But I don't know how to make it actually work. If someone can give me a code that was placed into my code and sent back, that would be great!

Thanks, Maxie_Z :)


Answer:

For this type of requirements, I'd ditch the JFormattedTextField (you don't want to format but to filter) and use a normal JTextField, with a custom DocumentFilter on its document. Create a custom filter, and override its replace and insertString methods to only accept digits. You can also beep/change the textfield's background momentarily when a non-digit is entered.

Question:

We are looking for a way to keep two types of texts for a JTextField

  1. Actual value is the value which the user input using keyboard
  2. Converted Value is a value which the user see inside that text field (The reason of doing this is that we want to display to our users Persian digits while he/she is typing - Only Display)

And finally the actual text will save inside our database NOT the Display text

We have created the text converter for the Display BUT we don't know how to apply this Scenario to the JTextField


Answer:

I went through this and I came up with this solution.

First we need to show the user persian/arabic digits when they have chosen Persian/Arabic keyboard in their OS and they're typing numbers inside their JTextField. To achieve this I wrote this custom 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();
    }
}

Next we need a utility class for number and text conversion from and to Persian/Arabic. I wrote this utility class for this matter:

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 + ""));
    }
}

Finally We need a Custom JTextField because we want control our inputs and outputs and convert them accordingly from-to our needs:

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));
    }

}

With this custom JTextField in place you can convert to English digit when you want to fetch the result of the JTextField and convert to Persian digit when you want to set a String which has English digits.

And Finally here is the test for the component :

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);
    }
}

Hope this is useful for you ...