1

How can I forbid users to put blanks into a JTextField?
It should not even be possible to write blanks.

Tim Büthe
  • 62,884
  • 17
  • 92
  • 129
ddejmek
  • 167
  • 1
  • 5
  • 10

3 Answers3

3

I would suggest to set the Document of the JTextField with an extended PlainDocument in which you override the insertString method. (Also nice to limit the size...)
Something like:

Document doc = new PlainDocument() {
    @Override
    public void insertString(int offs, String str, AttributeSet attr)
    throws BadLocationException {
        String newstr = str.replaceAll(" ", "");  // could use "\\s" instead of " "
        super.insertString(offs, newstr, attr);
    }

    @Override
    public void replace(int offs, int len, String str, AttributeSet attr) 
    throws BadLocationException {
        String newstr = str.replaceAll(" ", "");  // could use "\\s" instead of " "
        super.replace(offs, len, newstr, attr);
    }
};
textField.setDocument(doc);

EDIT:
replace must also be overrided/implemented!

user85421
  • 28,957
  • 10
  • 64
  • 87
  • DocumentFilter is best. There are also methods to insert text other than insertString. – Tom Hawtin - tackline Apr 07 '09 at 14:34
  • @Tom: true, I've not seen that. A better way (I now know) for "filtering"! – user85421 Apr 07 '09 at 14:41
  • Nice, but I had to implement `replaceString` too, as it seems that insertString was never used by JTextField! – lapo Jun 22 '12 at 07:14
  • @lapo I see it the other way - here (Java 7, Windows XP) only `insertString()` gets called, not `replaceString()`, at least not when using the keyboard and copy&paste... Anyway I would override both, but I think that the solution using a `DocumentFilter` is more appropriate, see Tom's answer – user85421 Jun 22 '12 at 11:17
  • I thought that the filter was nicer too, but it only seems to be called on de-focus, not letter-by-letter, and what I wanted as to avoid some letter to be written at all. – lapo Jun 25 '12 at 17:41
  • @lapo the filter gets called every time the document is changed (as documented in DocumentFilter). Tested it with a JTextField displayed by a JOptionPane (Java 7, Nimbus Look&Feel, Windows XP) - the filter methods, actually only `replace`, get called for every typed letter – user85421 Jun 26 '12 at 06:53
  • @CarlosHeuberger Sorry, I had two questions mixed up! (I was talking about the `JFormattedTextField` approach) I actually used `DocumentFilter` myself from the beginning, but I commented yours because that's where the code example was. – lapo Jun 26 '12 at 18:56
2

You can use a keymap. Check out this example disallowing space would be look like this:

KeyStroke keyStroke = KeyStroke.getKeyStroke(Character.valueOf(' '), 0);
textField.getInputMap(JComponent.WHEN_FOCUSED).put(keyStroke, "none");
Tim Büthe
  • 62,884
  • 17
  • 92
  • 129
2

Probably the best way to go about this is to use a Document with a DocumentFilter that removes any typed, pasted or otherwise inserted spaces. (Edit: this question originally linked to a weblog entry about a small Swing program that demonstrates this technique (in that case to allow only integer input).)

Extending an subtype of Document is possible, but is more error-prone (and ties you to a particular implementation).

Trying to intercept key presses doesn't actually work (it's at the wrong level of abstraction, so misses out any other way you could insert text such as pasting, dnd, etc.).

JFormattedTextField is a good way to make sure any UI sucks big time.

Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305