opinions on AutoCompleteSupport

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

opinions on AutoCompleteSupport

James Lemieux
Hey guys,

   I did a pile of work last night to support AutoCompleteSupport without assuming that .toString() is a reliable mechanism to produce a String equivalent of an object. You can now supply an optional FunctionList.Function <E, String> implementation which has all of the intelligence required to transfer the value to a String if .toString() is off limits for any reason.

   After a night of coaxing JComboBox and all related objects into even more backflips, I've got it working well in all cases I can test except one, where I must make a judgement call. The case is when the JComboBox's editor contains text that does not match any of the text values derived from the ComboBoxModel elements. We must find a way to transform the user's String into an instance of their data type, if possible, and failing that return the raw String.

   Interestingly, normal JComboBox tries to handle this case with reflection! Looking at BasicComboBoxEditor.getItem(...) you can see this:
...

// Must take the value from the editor and get the value and cast it to the new type.
Class cls = oldValue.getClass();
try {
   Method method = cls.getMethod("valueOf", new Class[] {String.class});
   newValue = method.invoke(oldValue, new Object[] { editor.getText()});
} catch (Exception ex) {
   // Fail silently and return the newValue (a String object)
}

so it actually searches for a valueOf(String s) method on the Class of your data objects!


We are in a unique position because we are asking the user to do this mapping explicitly, rather than implicitly relying on .toString() and a dubious method: valueOf(String).

So, I can either:

1) also try to reflect on the valueOf(String) method a la the stock Swing behaviour
2) force the users to provide functions for mapping in BOTH directions E -> String and String -> E

What do you think is a better approach? Any strong arguments for either side? I think I prefer option 2 myself, as it is explicit and not hidden, though it does require more work on the part of the user.

James
Reply | Threaded
Open this post in threaded view
|

Re: opinions on AutoCompleteSupport

Jesse Wilson
Both!

I'm assuming you have some API that says 'setStringifyingFunction()'
with a default that does the following:
   Function toString = new Function<Object, String>() {
      String execute(Object a) { return a == null ? "" : a.toString(); }
   }

What about just doing the same with valueOf, ie. provide a default
that does a reasonable default behaviour and allow the users to
override that default:
  Function valueOf = new Function<String, Object>() {
    Object execute(String a) {
      Class cls = oldValue.getClass();
      try {
        Method method = cls.getMethod("valueOf", new Class[] {String.class});
       newValue = method.invoke(oldValue, new Object[] { editor.getText()});
      } catch (Exception ex) {
         return a;
      }
    }
  }

The only crappy part here is that for this to really work
the Function needs 2 inputs - the old value and the new String.
That way it has something to call getClass() on.

Cheers,
Jesse


On 7/28/06, James Lemieux <[hidden email]> wrote:

> Hey guys,
>
>    I did a pile of work last night to support AutoCompleteSupport without
> assuming that .toString() is a reliable mechanism to produce a String
> equivalent of an object. You can now supply an optional
> FunctionList.Function <E, String> implementation which has all of the
> intelligence required to transfer the value to a String if .toString() is
> off limits for any reason.
>
>    After a night of coaxing JComboBox and all related objects into even more
> backflips, I've got it working well in all cases I can test except one,
> where I must make a judgement call. The case is when the JComboBox's editor
> contains text that does not match any of the text values derived from the
> ComboBoxModel elements. We must find a way to transform the user's String
> into an instance of their data type, if possible, and failing that return
> the raw String.
>
>    Interestingly, normal JComboBox tries to handle this case with
> reflection! Looking at BasicComboBoxEditor.getItem(...) you can see this:
> ...
>
> // Must take the value from the editor and get the value and cast it to the
> new type.
> Class cls = oldValue.getClass();
> try {
>    Method method = cls.getMethod("valueOf", new Class[] {String.class});
>    newValue = method.invoke(oldValue, new Object[] { editor.getText()});
> } catch (Exception ex) {
>    // Fail silently and return the newValue (a String object)
> }
>
> so it actually searches for a valueOf(String s) method on the Class of your
> data objects!
>
>
> We are in a unique position because we are asking the user to do this
> mapping explicitly, rather than implicitly relying on .toString() and a
> dubious method: valueOf(String).
>
> So, I can either:
>
> 1) also try to reflect on the valueOf(String) method a la the stock Swing
> behaviour
> 2) force the users to provide functions for mapping in BOTH directions E ->
> String and String -> E
>
> What do you think is a better approach? Any strong arguments for either
> side? I think I prefer option 2 myself, as it is explicit and not hidden,
> though it does require more work on the part of the user.
>
> James

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: opinions on AutoCompleteSupport

Holger
In reply to this post by James Lemieux
Good idea, sounds reasonable to me.

Providing the mapping functions should be optional.
Default behaviour should follow a normal JComboBox
where it makes sense.

Holger

> Both!
>
> I'm assuming you have some API that says 'setStringifyingFunction()'
> with a default that does the following:
>    Function toString = new Function<Object, String>() {
>       String execute(Object a) { return a == null ? "" : a.toString(); }
>    }
>
> What about just doing the same with valueOf, ie. provide a default
> that does a reasonable default behaviour and allow the users to
> override that default:
>   Function valueOf = new Function<String, Object>() {
>     Object execute(String a) {
>       Class cls = oldValue.getClass();
>       try {
>         Method method = cls.getMethod("valueOf", new Class[] {String.class});
>        newValue = method.invoke(oldValue, new Object[] { editor.getText()});
>       } catch (Exception ex) {
>          return a;
>       }
>     }
>   }
>
> The only crappy part here is that for this to really work
> the Function needs 2 inputs - the old value and the new String.
> That way it has something to call getClass() on.
>
> Cheers,
> Jesse
>
>
> On 7/28/06, James Lemieux <[hidden email]> wrote:
> > Hey guys,
> >
> >    I did a pile of work last night to support AutoCompleteSupport without
> > assuming that .toString() is a reliable mechanism to produce a String
> > equivalent of an object. You can now supply an optional
> > FunctionList.Function <E, String> implementation which has all of the
> > intelligence required to transfer the value to a String if .toString() is
> > off limits for any reason.
> >
> >    After a night of coaxing JComboBox and all related objects into even more
> > backflips, I've got it working well in all cases I can test except one,
> > where I must make a judgement call. The case is when the JComboBox's editor
> > contains text that does not match any of the text values derived from the
> > ComboBoxModel elements. We must find a way to transform the user's String
> > into an instance of their data type, if possible, and failing that return
> > the raw String.
> >
> >    Interestingly, normal JComboBox tries to handle this case with
> > reflection! Looking at BasicComboBoxEditor.getItem(...) you can see this:
> > ...
> >
> > // Must take the value from the editor and get the value and cast it to the
> > new type.
> > Class cls = oldValue.getClass();
> > try {
> >    Method method = cls.getMethod("valueOf", new Class[] {String.class});
> >    newValue = method.invoke(oldValue, new Object[] { editor.getText()});
> > } catch (Exception ex) {
> >    // Fail silently and return the newValue (a String object)
> > }
> >
> > so it actually searches for a valueOf(String s) method on the Class of your
> > data objects!
> >
> >
> > We are in a unique position because we are asking the user to do this
> > mapping explicitly, rather than implicitly relying on .toString() and a
> > dubious method: valueOf(String).
> >
> > So, I can either:
> >
> > 1) also try to reflect on the valueOf(String) method a la the stock Swing
> > behaviour
> > 2) force the users to provide functions for mapping in BOTH directions E ->
> > String and String -> E
> >
> > What do you think is a better approach? Any strong arguments for either
> > side? I think I prefer option 2 myself, as it is explicit and not hidden,
> > though it does require more work on the part of the user.
> >
> > James
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>


_____________________________________________________________________
Der WEB.DE SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
http://smartsurfer.web.de/?mc=100071&distributionid=000000000071

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]