1

I have a lot of different JFormattedTextFields with action and keylisteners. Every Field has a keylistener, so when I press enter I will focus the next JFormattedTextField. The Problem is, for some JFormattedTextFields my code is formatting the input and then sets the text new and for those selectAll() does not work.

JFormattedTextField a = new JFormattedTextField(someDouble);
JFormattedTextField b = new JFormattedTextField(someDouble2);
a.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            leasingfaktor1Field.selectAll();
            if(...) {
                //do something
                a.setText(tausenderPunkt(someValue));
            }   
        }
    });
a.addKeyListener(new KeyAdapter() {
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == 10) {
                b.requestFocusInWindow();
            }
        }
    });
b.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            leasingfaktor1Field.selectAll();
            if(...) {
                //do something
                b.setText(tausenderPunkt(someValue));
            }   
        }
    });
b.addKeyListener(new KeyAdapter() {
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == 10) {
                c.requestFocusInWindow();
            }
        }
    });

The function tausenderPunkt():

public String tausenderPunkt(double value) {
    String s = String.format("%1$,.2f", value);
    return s;
}

So when my cursor is in field a and i press enter the cursor goes to field b but does not select the text or values. When i do not use setText() i do not have the problem. Somebody has a solution?

Edit: For some JFormattedTextFields the solution was to add selectAll() to the keyAdapter, but not for all. For example:

b.addKeyListener(new KeyAdapter() {
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == 10) {
                c.requestFocusInWindow();
                c.selectAll();
            }
        }
    });

Edit2: The problem seems to be when i create the JFormattedTextFields. When i do not create them with a value in the constructor it works. But i have to do.

mavok
  • 27
  • 14
  • have you tried switching, i.e. doing the `setText` first then the `selectAll()`? Also you could try to do the `selectAll` inside an `invokeLater` block – geert3 Nov 25 '15 at 15:02
  • i can not switch the order because at first the programm should selectAll() so the user can overwrite the value and then setText() to format it (for example for numbers). i tried invokeLater but it does nothing. A mouseAdapater and selectAll() works fine. – mavok Nov 25 '15 at 15:07
  • Every time I have faced a scenario like this, the solution that always work is to do the initialization in background using a `SwingWorker`, after it has finished in method `doInBackground()`, I use the `done()` method to complete the task. – gersonZaragocin Nov 25 '15 at 16:58
  • Shouldn't the formatting be done in an AbstractFormatter? https://docs.oracle.com/javase/7/docs/api/javax/swing/JFormattedTextField.AbstractFormatter.html – keuleJ Nov 26 '15 at 18:57

3 Answers3

1

Before moving to your next text field you should consider handling all the required conditions for the text field you are currently focused on and this would of course include the formatting of values or text supplied to that field. Once all the desired conditions are met then move on to the next text field.

In reality this can all be accomplished through the keyPressed event for your particular situation. There is no need for the actionPerformed event on any of your text fields, for example:

a.addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            checkConditions(a, b);
        }
    }
});

b.addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            checkConditions(b, c);
        }
    }
});
//----------  and so on  -------------

Here is a simple method so as to eliminate the need for repetitious code:

private void checkConditions(JFormattedTextField fieldA, JFormattedTextField fieldB) {
    // Make sure something is contained within fieldA and 
    // that it's actually numerical text.
    if(!fieldA.getText().isEmpty() && 
                fieldA.getText().matches("([-]?)\\d+([,]\\d+)?(([.]\\d+)?)")) {
        // Convert the supplied text to Double and
        // ensure the desired numerical formating.
        String res = (String)tausenderPunkt(Double.parseDouble(fieldA.getText().replace(",","")));
        fieldA.setText(res);
        // Set Focus to our next text fieldB.
        fieldB.requestFocusInWindow();
        // Highlight the contents (if any) within the
        // next text fieldB.
        fieldB.selectAll();
    }
    // If fieldA is empty or fieldA does not contain 
    // numerical text then inform User and re-highlight
    // the entry in fieldA.
    else {
        JOptionPane.showMessageDialog (null, "Please Enter Numerical Values Only!", 
                "Incorrect Entry", JOptionPane.WARNING_MESSAGE);
        fieldA.selectAll();
    }
}

If you want the contents of your first text field to be highlighted as soon as focus has been established upon it (tabbed to or clicked on) then consider using a FocusGained event for that component or any other component where you desire the same effect.

I Hope this has helped in some way.

EDITED!

So as to handle OP's particular situation.

DevilsHnd - 退職した
  • 8,739
  • 2
  • 19
  • 22
  • Thank you! But now when i dont change the value in the JFormattedTextField the cursor doesnt jump to the next field when i press enter. Do i have to add a KeyListener or is ther a bettey solution? – mavok Nov 26 '15 at 09:22
  • Uhhhh....I see what you mean @mavok. In that case then just use a keylistener with your KeyPressed event handler then instead of the ActionListener. I have modified my answer to accomodate this particular situation as well. I have also modified the match regex to accomodate commas within entries. – DevilsHnd - 退職した Nov 26 '15 at 18:55
0
String str=this.getText();
this.setText(str);
this.selectAll();
Yanto
  • 1
0

You can get the focus owner and remove the focusable feature:

Component focusOwner = FocusManager.getCurrentManager().getFocusOwner();

When you get the component, put this sentence after load it:

component.setFocusable(false);