0

I've got an applet that pops up a dialog to enter credit card details. I'm using four JFormattedTextField classes to allow the user to input each 4 digit fragment of the credit card. I've got code in place to auto tab to the next field as the user is typing out the CC number. The problem is that when the dialog is launched from an applet running in IE8 using ( I'm restricted to using Java 7 update 13), if the user types in the number quickly, spaces appear to be inserted apparently at random even though a mask is applied to only allow alpha-numerics.

The code below is are the listeners on the the JFormattedTextField class where I suspect the issue resides.

super.addFocusListener(new FocusListener() {

        @Override
        public void focusGained(FocusEvent event) {
            EntryField field = (EntryField)event.getSource();

            if (_initialPosition > 0) {
                // if the initial position is set externally. This will happen when the caret is being set during
                // the initial load of the dialog.
                field.select(0, 0);
                field.setCaretPosition(_initialPosition);
                _initialPosition = -1;
            }
            else if (event.getOppositeComponent() == field.getNextControl()) {
                field.select(0, 0);
                field.setCaretPosition(field.getMaxCharacters()-1);
            }
            else {
                field.select(0, 0);
                field.setCaretPosition(0);
            }
        }
        @Override
        public void focusLost(FocusEvent event) {}
    });

    this.addKeyListener(new KeyListener() {
        @Override
        public void keyPressed(KeyEvent keyEvent) {
            if(keyEvent.getKeyChar() == KeyEvent.VK_BACK_SPACE) {
                EntryField field = (EntryField) keyEvent.getSource();
                if (field.getCaretPosition() == 0 && field.hasPreviousControl()) {
                    field.backtrackFocus(true);
                }
            }
            else if(Character.isLetterOrDigit(keyEvent.getKeyChar())) {
                EntryField field = (EntryField) keyEvent.getSource();
                if (field.getCaretPosition() == field.getMaxCharacters() - 1) {
                    field.moveFocus();
                }
            }
            else if(keyEvent.getKeyCode() == KeyEvent.VK_LEFT) {
                EntryField field = (EntryField) keyEvent.getSource();
                if (field.getCaretPosition() == 0 && field.hasPreviousControl()) {
                    field.backtrackFocus(false);
                }
            }
            else if(keyEvent.getKeyCode() == KeyEvent.VK_RIGHT) {
                EntryField field = (EntryField) keyEvent.getSource();
                if(field.getCaretPosition() == field.getMaxCharacters() - 1 && field.hasNextControl()) {
                    field.moveFocus();
                }
            }
            else if(keyEvent.isControlDown() && keyEvent.getKeyChar() == 'c') {
                EntryField field = (EntryField) keyEvent.getSource();
                field.paste();
            }
        }

        @Override
        public void keyTyped(KeyEvent keyEvent) {
            if (_checkAmEx && Character.isLetterOrDigit(keyEvent.getKeyChar())) {
                EntryField field = (EntryField)keyEvent.getSource();
                int pos = field.getCaretPosition();
                if (pos == 2 && creditCardIsAmex()) {
                    field.moveFocus();
                }
            }
            else if(keyEvent.getKeyChar() == KeyEvent.VK_DELETE) {
                EntryField field = (EntryField) keyEvent.getSource();
                field.setCaretPosition(field.getCaretPosition() - 1);
                field.shiftTextLeft();
            }
            else if(keyEvent.getKeyChar() == KeyEvent.VK_BACK_SPACE) {
                EntryField field = (EntryField) keyEvent.getSource();
                field.shiftTextLeft();
            }
        }

        @Override
        public void keyReleased(KeyEvent keyEvent) {}
    });
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Fergal
  • 5,213
  • 6
  • 35
  • 44
  • 3
    Don't use `KeyListener` on text components, use a `DocumentListener` to monitor the changes to the state of the field and customise the focus transversal through the [Focus subsystem](http://docs.oracle.com/javase/tutorial/uiswing/misc/focus.html) – MadProgrammer May 21 '14 at 01:06
  • 2
    1) For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete and Verifiable Example). 2) Why code an applet? If it is due to spec. by teacher, please refer them to [Why CS teachers should stop teaching Java applets](http://programmers.blogoverflow.com/2013/05/why-cs-teachers-should-stop-teaching-java-applets/). 3) As an aside, I'd bet you see the exact same behavior if the formatted text field was in an application. Meaning 'applet' is irrelevant to the problem. – Andrew Thompson May 21 '14 at 01:10
  • An alternative approach is cited [here](http://stackoverflow.com/a/10099809/230513). – trashgod May 21 '14 at 01:10
  • 1
    You might want to use an input verifier instead of a mask. A mask will insert placeholders which are probably your "random" spaces. An input verifier will not yield focus unless requirements are met, which is what you probably really want. See the answers [here](http://stackoverflow.com/questions/23471121/jtextfield-specific-format-checking/23497005#23497005) and [here](http://stackoverflow.com/questions/22828689/how-to-use-jformattedtextfield-to-accept-names-like-strings) for example. – user1803551 May 21 '14 at 03:54

0 Answers0