'Replace 0s of jTextField as I type

I want jTextField with 12 0s and I need to change those 0s to numbers I type as I type.

  • In begining there is 000000000000
  • If I type 123 then it should be 000000000123

I done this on KeyPressed event, but it's not working properly.

  try {
        int i = Integer.parseInt(jTextField1.getText());
        jTextField1.setText(String.format("%012d", i));
    } catch (Exception e) {
        jTextField1.setText(String.format("%012d", 0));
    }
}             

It changes as I type, but there is few problems.

  1. It changes till I type 11 numbers, just after I type 12th number it delete all numbers and it display again as 000000000005 (if 12th number I typed is 5)
  2. When I delete all it shows only 10 0s not 12,but When I type a number again it shows typed number and 11 0s.

Any solutions?



Solution 1:[1]

Here is a custom class that tries to simulate data entry of a bank machine. That is text is entered right to left:

import java.awt.*;
import java.text.*;
import javax.swing.*;
import javax.swing.text.*;

public class ABMTextField extends JTextField
{
    private DecimalFormat format;
    private String decimal;

    public ABMTextField(DecimalFormat format)
    {
        this.format = format;

        decimal = Character.toString( format.getDecimalFormatSymbols().getDecimalSeparator() );

        setColumns( format.toPattern().length() );
        setHorizontalAlignment(JFormattedTextField.TRAILING);

        setText( format.format(0.0) );

        AbstractDocument doc = (AbstractDocument)getDocument();
        doc.setDocumentFilter( new ABMFilter() );
    }

    @Override
    public void setText(String text)
    {
        Number number = format.parse(text, new ParsePosition(0));

        if (number != null)
            super.setText( text );
    }

    public class ABMFilter extends DocumentFilter
    {
        public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
            throws BadLocationException
        {
            replace(fb, offs, 0, str, a);
        }

        public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
            throws BadLocationException
        {
            if (".0123456789".contains(str))
            {
                Document doc = fb.getDocument();
                StringBuilder sb = new StringBuilder( doc.getText(0, doc.getLength()) );

                int decimalOffset = sb.indexOf( decimal );

                if (decimalOffset != -1)
                {
                    sb.deleteCharAt(decimalOffset);
                    sb.insert(decimalOffset + 1, decimal);
                }

                sb.append(str);

                try
                {
                    String text = format.format( format.parse( sb.toString() ) );
                    super.replace(fb, 0, doc.getLength(), text, a);
                }
                catch(ParseException e) {}
            }
            else
                Toolkit.getDefaultToolkit().beep();
        }

        public void remove(DocumentFilter.FilterBypass fb, int offset, int length)
            throws BadLocationException
        {
            Document doc = fb.getDocument();
            StringBuilder sb = new StringBuilder( doc.getText(0, doc.getLength()) );

            int decimalOffset = sb.indexOf( decimal );

            if (decimalOffset != -1)
            {
                sb.deleteCharAt(decimalOffset);
                sb.insert(decimalOffset - 1, decimal);
            }

            sb.deleteCharAt( sb.length() - 1) ;

            try
            {
                String text = format.format( format.parse( sb.toString() ) );
                super.replace(fb, 0, doc.getLength(), text, null);
            }
            catch(ParseException e) {}
        }
    }

    private static void createAndShowUI()
    {
//      DecimalFormat format = new DecimalFormat("###,##0.00");
        DecimalFormat format = new DecimalFormat("0000000000");
        ABMTextField abm = new ABMTextField( format );

        JPanel panel = new JPanel();
        panel.add( abm );

        JFrame frame = new JFrame("ABMTextField");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( panel );
        frame.setSize(200, 200);
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowUI();
            }
        });
    }
}

You can change the default mask as follows:

//DecimalFormat format = new DecimalFormat("###,##0.00");
DecimalFormat format = new DecimalFormat("0000000000");

Solution 2:[2]

String result = text.substring(1) + inputKey;

this will exclude the left character and add the new one.

Solution 3:[3]

Your integer values may be maxing out, try just using the String.

    try {
        String i = jTextField1.getText();
        String text = "";
        for (int j = 0; j < (12 - i.length()); j++) {
            text += "0";
        }
        jTextField1.setText(text + i);
    } catch (Exception e) {
        jTextField1.setText(String.format("%012d", 0));
    }

Or if you would like it even shorter, you could do this.

    try {
        String i = jTextField1.getText();
        String text = "000000000000";
        jTextField1.setText(text.substring(0, (12-i.length())) + i );
    } catch (Exception e) {
        jTextField1.setText(String.format("%012d", 0));
    }

Which just substrings a String of 12 0's depending not he length of the text field, and then adds it to the end.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Gabri T
Solution 3