how to position the Caret of a JTextField?

0

I have JTextField where opening and closing parentheses is optional. However, whenever the user opens and does not close a parenthesis, my program gives error, because I use this text field to calculate an arithmetic expression.

In order to avoid this error, I would like, as soon as the user types in "(" I would complete with ")" and put the caret between those characters, but I do not know how to do it. For example:

JTextField txt = new JTextField;
txt.setText("2*(");
String ultimoCaractereDigitado = txt.substring (txt.length() - 1, txt.length());

if(ultimoCaractereDigitado.equals("(")){
    txt.setText(ultimoCaractereDigitado+")");
    //text.getText() = 2*()
    txt.addCaretListener(new CaretListener() {
        @Override
        public void caretUpdate(CaretEvent caret) {
        //Posição do caret: penúltimo caractere, ou seja, entre o "(" e ")"    
        caret.setDot(txt.getText().length - 2);
        }
    });
}

The ce.setDot() method does not exist, is there any way I can get the position of the caret other than caretUpdate ?

    
asked by anonymous 05.07.2017 / 16:05

1 answer

1

You can do this by merging the PlainDocument and CaretListener , where with the first class you detect if what you typed in the field is the opening of the parenthesis and concatenates the closing together, and with the second, you position the cursor between them. For this, I have used a Boolean variable hasOpenParentese so that both methods have a way to "communicate" and pro CaretListener know when to reposition the cursor:

textField.setDocument(new PlainDocument() {

    @Override
    public void insertString(int offset, String str, AttributeSet attr) throws BadLocationException {
        if (str == null) {
            return;
        }

        if (str.equals("(")) {
            hasOpenParentese = true;
            str += ")";
        }
        super.insertString(offset, str, attr);
    }
});

textField.addCaretListener(e -> {
    if (hasOpenParentese) {
        hasOpenParentese = false;
        JTextComponent comp = (JTextComponent) e.getSource();
        comp.setCaretPosition(e.getDot() - 1);
    }
});

What results:

Imadeanexecutableexampleinthe github , if you want to test before applying it in your code.

    
05.07.2017 / 20:42