JXTable - NumberEditor not propertly configured (swingx 1.0)

View: New views
8 Messages — Rating Filter:   Alert me  

JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,

at first, [b]I would like to thank for your working on this great project.[/b]

And now, I have a problem with JXTable (swingx 1.0, stable). I use JDK 1.6u16 (or 1.6u4).

[b]I use Integer[/b] (double or any other type) [b]for culumn.[/b]
JTable uses a protection in the case, [b]when user tries to enter an invalid value. So, if you try to enter a bigger value then integer max size is, you wonnt see the red cell.[/b]

[b]Is this bug or me mistake ? NumberEditor ?[/b]

[b]The complete StackTrace is: [/b]
[code]Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: NumberEditor not propertly configured
        at org.jdesktop.swingx.table.NumberEditorExt.getCellEditorValue(NumberEditorExt.java:130)
        at javax.swing.JTable.editingStopped(JTable.java:4661)
        at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:125)
        at javax.swing.DefaultCellEditor$EditorDelegate.stopCellEditing(DefaultCellEditor.java:330)
        at javax.swing.DefaultCellEditor.stopCellEditing(DefaultCellEditor.java:215)
        at org.jdesktop.swingx.table.NumberEditorExt.stopCellEditing(NumberEditorExt.java:91)
        at javax.swing.DefaultCellEditor$EditorDelegate.actionPerformed(DefaultCellEditor.java:347)
        at javax.swing.JTextField.fireActionPerformed(JTextField.java:492)
        at javax.swing.JTextField.postActionEvent(JTextField.java:705)
        at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820)
        at javax.swing.JFormattedTextField$CommitAction.actionPerformed(JFormattedTextField.java:1107)
        at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1636)
        at javax.swing.JComponent.processKeyBinding(JComponent.java:2849)
        at javax.swing.JComponent.processKeyBindings(JComponent.java:2884)
        at javax.swing.JComponent.processKeyEvent(JComponent.java:2812)
        at java.awt.Component.processEvent(Component.java:5818)
        at java.awt.Container.processEvent(Container.java:2058)
        at java.awt.Component.dispatchEventImpl(Component.java:4413)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
        at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:697)
        at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:962)
        at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:834)
        at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:661)
        at java.awt.Component.dispatchEventImpl(Component.java:4285)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Window.dispatchEventImpl(Window.java:2440)
        at java.awt.Component.dispatchEvent(Component.java:4243)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)
Caused by: java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at org.jdesktop.swingx.table.NumberEditorExt.getCellEditorValue(NumberEditorExt.java:122)
        ... 35 more
Caused by: java.lang.NumberFormatException: For input string: "546546546546524111"
        at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
        at java.lang.Integer.parseInt(Integer.java:459)
        at java.lang.Integer.<init>(Integer.java:620)
        ... 40 more
[/code]

JXTable, Model (sample, I use more column) ----- ----- ----- -----

[code]
        tableModel = new DefaultTableModel(new Object [][][] {}, new String [] {
            "ID", "Name", "Number"}) {
            Class[] types = new Class [] {
               java.lang.Integer.class,
               java.lang.String.class,
               java.lang.Integer.class};

            @Override
            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            };
        };

        jXTable.setModel(tableModel);
[/code]
JXTable, Model ----- ----- ----- ----- ----- -----
[Message sent by forum member 'merax' (merax@...)]

http://forums.java.net/jive/thread.jspa?messageID=366666

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...


Re: JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

sounds llike a bug - could you please file an issue in the swingx issue tracker? btw, does it happen only with Integer or as well with the float/double types?

As a temporary workaround, you can use the default editors from a core JTable - the price is lost localization (as far as I remember, to get that correct was the whole point for NumberEditorExt)

Thanks
Jeanette
[Message sent by forum member 'kleopatra' (fastegal@...)]

http://forums.java.net/jive/thread.jspa?messageID=366716

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...


Re: JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> sounds llike a bug - could you please file an issue in the swingx issue tracker? btw, does it happen only with Integer or as well with the float/double types?

I create new report in issue tracker (https://swingx.dev.java.net/issues/show_bug.cgi?id=1183)

Byte, Short, Integer, Long trows this bug (with big invalid value).
Double and Float looks fine for me (symbol "infinity").

> As a temporary workaround, you can use the default editors from a core JTable - the price is lost localization (as far as I remember, to get that correct was the whole point for NumberEditorExt)

I try look at NumberEditorExt or use double with check (real numbers only).

fnx
Merax
[Message sent by forum member 'merax' (merax@...)]

http://forums.java.net/jive/thread.jspa?messageID=366720

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...


Re: JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Merax,

thanks!

Actually, this turns out to be one-of-those-issues: first thought "easy", second "hmm ... maybe not ..." and then endless head scratching ;-)

The easy part was a swingx error: if stopCellEditing returns true, accessing getCellEditorValue must not fail with any error. That's fixed. What's still missing, is the visual error feedback. The core NumberEditor has the error feedback because ... it doesn't care overly much about localization: it uses a simple textField, no formatter, nothing. SwingX' NumberEditorExt behaves much better: it uses a JFormattedTextField with a configurable NumberFormat.

And here thingies start to get confusing: looking at the code, everything seems fine - the normal/error border is set on receiving a editValid property change. Only: the formatter thinks everything's fine even for Integers exceeding their boundaries. Oooookaaaayy, time for digging. Looking at the collaborators

- Number-/DecimalFormat: is merely concerned about the actual parsing - happy as long as the input string can be parsed into a valid Number, not concerned about types/type boundary conditions
- the main controller of how text-to-value conversion should be handled is the AbstractFormatter: with a NumberFormat the concrete class is a NumberFormatter (which is-a InternationalFormatter)
- reading its api reveals such niceties as valueClass, minimum, maximum ... cool. Sounds like the swingx editor could be easily enhanced to use those for better configuration and voila! everthing should be fine.
- except ... guess what <g>

quick unit test which fails:

[code]
    private static final String TOO_BIG_INTEGER = "11111111111111111111111111";
    @Test (expected = ParseException.class)
    public void testNumberFormatterMinMax() throws ParseException {
        NumberFormat format = NumberFormat.getIntegerInstance();
        NumberFormatter formatter = new NumberFormatter(format);
        formatter.setMaximum(Integer.MAX_VALUE);
        formatter.setMinimum(Integer.MIN_VALUE);
        formatter.stringToValue(TOO_BIG_INTEGER);
    }
[/code]

strange, right? The same test with min/max one-inside-boundary (that is MIN_VALUE +1 and MAX_VALUE -1) passes, that is correctly rejects values which are not inside. Back to core code digging ... and the culprit iiiissss ...

[code]
// InternationalFormatter

    public Object stringToValue(String text) throws ParseException {
        Object value = stringToValue(text, getFormat());
       // JW: snipped some unrelevant lines
       try {
            if (!isValidValue(value, true)) {
                throw new ParseException("Value not within min/max range", 0);
            }
        } catch (ClassCastException cce) {
            throw new ParseException("Class cast exception comparing values: "
                                     + cce, 0);
        }
        return value;
    }

    Object stringToValue(String text, Format f) throws ParseException {
        if (f == null) {
            return text;
        }
        // JW: remember - the format isn't really interested in actual types/ranges
        // so we get a perfectly valid (from format perspective) Double here
        return f.parseObject(text);
    }

[/code]

looks fine, right? Parse the text into a value and check against the range - exactly what we need.

Except ... the actual conversion method called is a subclass method ...

[code]
// NumberFormatter
    Object stringToValue(String text, Format f) throws ParseException {
        if (f == null) {
            return text;
        }
        Object value = f.parseObject(text);
        // JW: convert to expected type _before_ range check
        return convertValueToValueClass(value, getValueClass());
    }

    private Object convertValueToValueClass(Object value, Class valueClass) {
        if (valueClass != null && (value instanceof Number)) {
            if (valueClass == Integer.class) {
                return new Integer(((Number)value).intValue());
            }
     ....
    }

[/code]

.. which adds functionality in that it converts the Number into the expected type. That's done by using Number.xxValue which guarantee to be in-range. Ufff - bug or feature?. At least highly unexpected.

Ideas how to make our NumberEditor work correctly anyway? Could probably use the one-off boundaries, but that's a crude hack. Hmm ...

CU
Jeanette
[Message sent by forum member 'kleopatra' (fastegal@...)]

http://forums.java.net/jive/thread.jspa?messageID=366973

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...


Re: JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> .. which adds functionality in that it converts the
> Number into the expected type. That's done by using
> Number.xxValue which guarantee to be in-range. Ufff -
> bug or feature?. At least highly unexpected.
>

Seems to be intentional, from the class doc:

"NumberFormatter provides slightly different behavior to stringToValue than that of its superclass. If you have specified a Class for values, setValueClass, that is one of of Integer, Long, Float, Double, Byte or Short and the Format's parseObject returns an instance of Number, the corresponding instance of the value class will be created using the constructor appropriate for the primitive type the value class represents. For example: setValueClass(Integer.class) will cause the resulting value to be created via new Integer(((Number)formatter.parseObject(string)).intValue()). This is typically useful if you wish to set a min/max value as the various Number implementations are generally not comparable to each other. This is also useful if for some reason you need a specific Number implementation for your values."

Hmm ...

Jeanette
[Message sent by forum member 'kleopatra' (fastegal@...)]

http://forums.java.net/jive/thread.jspa?messageID=366977

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...


Re: JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

muttering to myself ;-)

Found that I'm not entirely alone

http://stackoverflow.com/questions/480632/why-doesnt-java-lang-number-implement-comparable

with that in mind, it seems to be a kind of hen-and-egg catch: Number isn't comparable, so before we can compare a Number to whatever concrete boundary, the Number has to be converted to a comparable compatible with that boundary. That conversion makes it valid in the boundaries ...

Started to experiment with a custom NumberFormatter (named StrictNumberFormatter) which converts every Number to a BigDecimal and then compares against boundaries which are BigDecimals. Seems to work, including giving a nice enough error feedback in the textfield. Not sure if that is reasonable in the general case, so please stop me anybody, if I'm trying something incredibly stupid.

Cheers
Jeanette
[Message sent by forum member 'kleopatra' (fastegal@...)]

http://forums.java.net/jive/thread.jspa?messageID=367000

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...


Re: JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

me again, yet another sequel <g>

StrictNumberFormatter is as ready as it might get (fixed a couple of problems). For value classes Byte, Short, Integer, Float it auto-installs the min/max and validates that a parsed number falls into that range before converting it into the target type. The range-check is done with type BigDecimal, so we are safe (? really).

NumberEditorExt can use this formatter. If configured to do so, it'll set the formatter's valueClass to the column class and then let the format/ter do their respective jobs (no more intervention in that level). Right now, the default is to not use the strict option - that will change as soon as I'm half-way sure we are not breaking anything. Naturally, I want everybody to try out the new stuff: you can do by registering a NumberEditorExt with strict option on, like:

[code]
table.setDefaultEditor(Number.class, new NumberEditorExt(true));
[/code]

There are some new tests in NumberEditorExtTest, some of them interactive tests where you can see/compare the behaviour of old and new. One nice side-effect is that the visual error feedback now happens on typing, that is as soon as the a conversion would be invalid, the red border is turned on.

Eagerly waiting for feedback (can take the blows <g>)

CU
Jeanette
[Message sent by forum member 'kleopatra' (fastegal@...)]

http://forums.java.net/jive/thread.jspa?messageID=367124

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...


Re: JXTable - NumberEditor not propertly configured (swingx 1.0)

by jdnc-interest :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Forgot the ranting <g>

Today, I spent most of the time to track down some NPEs in core which I had not expected, which originated from

[code]
// NPE if string == null
decimalFormat.parse(String, ParsePosition);
[/code]

Reading that method's doc,it looked like my - that is precondition - error

"Throws: NullPointerException - if text or pos is null."

Obviously I didn't like the thought - so went up the documentation chain, to NumberFormat

"Throws: NullPointerException - if pos is null."

har, har .. so technically we have a narrowing of preconditions in a subclass, which is illegal (or at least very, very, very bad behaviour). Going after the design intention, class doc of Format has a paragraph on subclassing, which states:

"Any parse method that does not take a ParsePosition argument should throw ParseException when no text in the required format is at the beginning of the input text."

Hmm ... that sounds like expectation is that the string is always not null and not empty. Then, what's the implications for client code, f.i. Formatters. It's stringToValue is doc'ed to allow null return values, from AbstractFormatter:

"Parses text returning an arbitrary Object. Some formatters may return null"

which is perfectly valid in the context of a FormattedTextField - empty or null text might simply be mapped to null. Now, who should decide how to convert a null/empty text if not the Format? If the formatter is not allowed to pass-in a null/empty text into the format's parsing method, then the formatter has to assume what to do. Core implementations of formatters don't care ...

Baseline? Don't know - StrictNumberFormatter assumes that its Format.parse can handle null and that the return value of that method can be null. That's achieved by wrapping the NumberFormat into a custom NumberFormatExt which delegates only if the given string is neither empty nor null.

CU
Jeanette
[Message sent by forum member 'kleopatra' (fastegal@...)]

http://forums.java.net/jive/thread.jspa?messageID=367131

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@...
For additional commands, e-mail: jdnc-help@...