I discovered the hard way that:
new JFormattedTextField(new Integer(0))
does not do what I wanted.
What I wanted was to have a text entry field restricted to integers. What I got was a field which rounded off numbers to integers. This was surprising.
After a while of poking at it, I tried using various incarnations of NumberFormat and DecimalFormat in the field constructor with no luck. Perusing the sources was not particularly illuminating either, at least at first.
Finally I noticed that JFormattedTextField.getDefaultFormatterFactory(Object) contained this legerdemain:
if (type instanceof DateFormat) { ... } if (type instanceof NumberFormat) { ... } if (type instanceof Format) { ... } if (type instanceof Date) { ... } if (type instanceof Number) { /* mucking around with formatter factory */ }
Hmmm. So in a flash of inspiration I tried:
new JFormattedTextField(new BigInteger(0))and it worked, although I do not entirely understand why. JFormattedTextField maintains separately value, formatter and formatter factory in addition to the document model for text entry and a lot of state options for handling valid and invalid input.
I'm sure its a tour de force for someone at Sun, and most importantly the class works, but quirks like this one are difficult to find and explain.
UPDATE: A colleague of mine asked for more details on this point. To clarify:
Argument | Input | Behavior |
---|---|---|
new Integer(0) | 3.0 | 3 |
3.3 | 3 | |
new BigInteger(0) | 3.0 | 3 |
3.3 | invalid |
So to get non-integral input to be treated as invalid, you must initialize JFormattedTextField with a BigInteger; initializing with an Integer gets a rounding mode instead.
No comments:
Post a Comment