This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I am trying to extend a JTextField via a JFormattedField in order to obtain a textfield which accepts only numbers. This means when pressing a letter key, the control shouldn't respond to it. On the other hand when leaving the focus the entered string should format to according a specific pattern. I tried it using a JFormattedField using a MaskFormatter, but with the maskformatter I am bound to a specific text lenght, which is not the case. On the other side if only using a formatter (haven't tried it yet) I presume I won't get correct values until the control loses focus.
I need to use features of both.
A solution I have thought of is to implement my own KeyMap in the control, so actions for non valid characters return no response (or perhaps a beep!). I liked that feature from MaskFormatter. However before doing that I would appreciate any advise given to attain it, since I have seen myself many times developing things which could have saved, if had had deeper understanding of the component suite.
Use a custom DocumentFilter sub class on a regular text field's (Abstract)Document. Override insertString and replace:
You can also modify the string / text variable to strip out any non-digit before calling super.insertString / super.replace.
Hi rob, thanks for the answer. Looks cool. Tried overriding the insertString method in the Document instanceof the textField and works smoothly, however I would like to implement it via the Documentfilter, but not getting it to work (not attaching the DocumentFilter somehow and the overriden method not reached), am i missing something very stupid? the following code should do isnt'it?
I am implementing it inside the DefaultCellEditor (CuentaTableCellEditor) class, which holds a reference to the textField involved in managing everything.
I've modified your code a bit into an SSCCE, and it appears it's never calling insertString, only replace. So override that one too.
Also, don't catch the BadLocationException in the call to super.insertString or super.replace - just throw it on. It means some code is trying to do something bad, and you don't want to silently ignore that. You usually shouldn't see that exception being thrown anyway.
Joined: Apr 21, 2010
I had to override the method as you say, I saw it accidentally on a related post. Definetely this approach is the simplest way to attain it, which at the time doesn't interfer with other gui aspects.
Thanks for pointing me on this direction Rob. Had the chance to have a closer look to text controls and their inner working.