0

I want to a JTextField to have maximum characters, Ive been trying out this code, what im trying to do is, if a user enters more then 13 characters it should erase the last character entered, I also tried with the Unicode Character (by replacing the \b to \u0008) but it gives the same result, this is my code:

if(EditTxtFName.getText().length() > 10)
{
    EditTxtFName.setBackground(Color.red);
    EditTxtFName.setText(EditTxtFName.getText() + "\b");
}
else
{
    EditTxtFName.setBackground(Color.white);
}

The output of what happens is, instead of deleting the last character is adds space and continues.. Thanks in advance..

2 Answers2

2

Use a DocumentFilter, it is designed to allow you to filter the content before it is added to the underlying Document of the text component...

See Implementing a Document Filter for more details

For example...

import java.awt.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;

public class SizeFilter extends DocumentFilter {

    private int maxCharacters;    

    public SizeFilter(int maxChars) {
        maxCharacters = maxChars;
    }

    public void insertString(FilterBypass fb, int offs, String str, AttributeSet a)
            throws BadLocationException {

        if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
            super.insertString(fb, offs, str, a);
        else
            Toolkit.getDefaultToolkit().beep();
    }

    public void replace(FilterBypass fb, int offs, int length, String str, AttributeSet a)
            throws BadLocationException {

        if ((fb.getDocument().getLength() + str.length()
                - length) <= maxCharacters)
            super.replace(fb, offs, length, str, a);
        else
            Toolkit.getDefaultToolkit().beep();
    }
}

Which could be applied using something like...

((AbstractDocument) EditTxtFName.getDocument()).setDocumentFilter(new SizeFilter(13));

Example from DocumentFilter Examples

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

Edit 2:

These solutions are outdated and should not be used. Instead, use the DocumentFilter solution posted in this thread.

Original Answer:

You can add a KeyListener that caps the strings length at 13 after releasing a button like so:

textField.addKeyListener(new KeyAdapter() {
    @Override
    public void keyReleased(KeyEvent e) {
        String typed = textField.getText();
        textField.setText(typed.substring(0, Math.min(13, typed.length())));
    }
});

This removes everything after the 13th character every time you type a character into the text field.

Edit 1:

Another thing you could try is this. Here, the PlainDocument class is extended in such a way that it will not accept strings that, combined with the text already contained in the document, would exceed a certain length set when creating the object.

This method is probably a little cleaner, you don't see characters "pop up" in the text field only to be removed just moments later and also it's easier to apply this method to several JTextFields.

Community
  • 1
  • 1
Marv
  • 3,517
  • 2
  • 22
  • 47
  • 1
    NO! Just no. Stop attaching `KeyListener`s to text components, they are not appropriate for modifying/filter content into text components, for a copious amount of reasons, apart from the fact that there are better ways to achieve the same result but it will not take into consideration the use case where the user pastes text into the field. There is also no need to use a custom `Document` either. – MadProgrammer Dec 13 '14 at 11:54
  • Fair enough. The `Document` solution is linked everywhere including [here](http://stackoverflow.com/questions/10136794/limiting-the-number-of-characters-in-a-jtextfield), but [an answer in that question](http://stackoverflow.com/a/24473097/3000387) also mentions using a `DocumentFilter`. Would that be the better version then? – Marv Dec 13 '14 at 12:02
  • 1
    Yes, `KeyListener` and custom `Document`s are mentioned everywhere, but they are simply wrong (or more importantly, superseded), in Java 1.3, there was no other way, since Java 1.4, we have the `DocumentFilter` which was designed to do this exact job. The problem is, people either wrote their own or told other people that they should follow these ideas and no one bothered to check if the API was updated. `DocumentFilter` IS the best solution and should be the only suggested method for achieving this kind of work, all other answers a wrong (now) – MadProgrammer Dec 13 '14 at 12:08
  • Okay, thank you for the explanation! Should I edit my answer in any way pointing out that these methods are outdated? – Marv Dec 13 '14 at 12:35
  • 2
    I'd edit to point `DocumentFilter` as primary solution, if you want to highlight the other methods as been "out-of-date" it would help the OP recognise bad recommendations ;) – MadProgrammer Dec 13 '14 at 12:44