spinner component

Daniel Zwolenski zonski at googlemail.com
Sun Dec 18 10:56:47 PST 2011


On 18/12/2011, at 7:38 PM, Tom Eugelink <tbee at tbee.org> wrote:

> No problem (never actually checked your code), but I got the idea of also making the index class flexible. Like it. I my API I decide to merge "hasNext" and "getNext" into one, by having "getNext" return null if there is no next. I would do that here again, which leaves 3 methods instead of 5 in the DataSource API.

I'm wondering if 'null' would need to be used as an actual valid value in some cases, ie to indicate 'no selection'? My list of options might be (null, 'yesterday', 'today', 'tomorrow'). Is this a valid use case or are we entering ChoiceBox/ComboBox territory at that point?

> 
> I tried to modify the current implementation accordingly and it worked. 
> 
> I also tried to get rid of the fourth method, getIdx(value), but I can't. The problem is that I want to completely encapsulate the handling of the index in the spinner. This means that the API of the spinner only involves the value, never the index. This means that at some point someone will want to set the value of the trigger and that value must be converted to the index. So the "getIdx" is a required method.

Good point, I can't think of a way around it. Id vote for non-abbreviated method names though (even for well known abbreviations like this) ie 'getIndex'

> 
> The other approach would be to fully expose the index being used in the [spinner]. But for a usability perspective I really prefer 
>     new Spinner<String>("a", "b", "c")
> 
> instead of something like
> 
>     new Spinner<String, Integer>("a", "b", "c")

The first option is definitely a lot nicer. 

Would there ever be a need to select by index though (I'm hoping not)? I can see a possible need for selectFirst (ie reset) but this is probably achieved by knowing what the first 'value' should be and calling set with that (eg setValue(new Date())). 

Last minute thought. I haven't checked (typing on my phone) but is your Spinner editable in the sense that you could free type in it (like the ComboBox)? That might be nice - it should probably use the same StringConverter design as ComboBox if it is to support this. 

> 
> Tom
> 
> 
> 
> On 2011-12-17 22:53, Daniel Zwolenski wrote:
>> 
>> Apparently my brain doesn't do the highly complicated mathematics required to implement increment and decrement by 1 on a Sunday morning. Obviously some of those minuses should be pluses and vice versa :) 
>> 
>> On Sun, Dec 18, 2011 at 8:48 AM, Daniel Zwolenski <zonski at googlemail.com> wrote:
>> Just exploring the index thing a little more - could we have both the index and the value as a type parameter?
>> 
>> So we have something like (just going for the gist of it, obvious cleanups, possible use of callbacks, etc needed):
>> 
>> Spinner<Integer, String> spinner = new Spinner<Integer, String>();
>> spinner.setValueProvider(new SpinnerValueProvider<Integer, String> {
>>      boolean hasNext(Integer current) { return current < myListOfValues.size() - 1; }
>>      Integer getNext(Integer current) { return current + 1; }
>>      boolean hasPrev(Integer current) { return current > 0; }
>>      Integer getPrevious(Integer current) { return current + 1; }
>>      String getValueFor(Integer index) { return myListOfValues.get(index); }
>> });
>> 
>> Then if you wanted to use an enum as the 'index' or an Int or a BigInt you could? 
>> 
>> e.g. 
>> 
>> Spinner<TypeOfSport, Sport> spinner = new Spinner<TypeOfSport, Sport>();
>> spinner.setValueProvider(new SpinnerValueProvider<TypeOfSport, Sport> {
>>      boolean hasNext(TypeOfSport current) { return current.ordinal() < TypeOfSport.values().length - 1;}
>>      TypeOfSport  getNext(TypeOfSport  current) { return TypeOfSport.values()[current.ordinal() - 1]; }
>>      boolean hasPrev(TypeOfSport  current) { return current > 0; }
>>      TypeOfSport  getPrevious(TypeOfSport  current) {  
>>         return TypeOfSport.values()[current.ordinal() + 1];  }
>>      Sport getValueFor(TypeOfSport  type) { return (create sport for type, e.g. look up from map) }
>> });
>> 
>> We could then provide a suite of default providers (Number, List, Enum, LinkedList, Calendar, etc). The provider could be what has the 'cycle' flag on it too. So a List 'cycle' could implement the default logic for that (i.e. the cycle becomes more of a provider issue). 
>> 
>> Just thinking out loud really.
>> 
>> 
>> On Sat, Dec 17, 2011 at 9:26 PM, Tom Eugelink <tbee at tbee.org> wrote:
>> 
>> 
>> 
>> In essence, this approach is a one-method Callback<Integer, T> 'data provider', where the method is 'public T call(Integer index)'. It is a simpler data provider than what you mention. I guess my question is whether the additional API is required? Also, in my opinion, I think Integer, rather than BigInteger, is likely sufficient - but this isn't a major issue for me right now.
>> 
>> 
>> I understand and am curious if it matches all that I needed. Basically what you see in my DataProvider API is what I needed while implementing the spinner:
>> - is there a next value? (I generalized that to "give me the idx of the next value", which allows for some additional dynamics.)
>> - is there a previous value? (dito)
>> - what is the value for idx X?
>> - what is the idx of value X?
>> 
>> Now, thinking about, this multiple times the same value in the domain may be an issue for the last one.
>> 
>> Tom
>> 
>> 
>> 
>> 
> 


More information about the openjfx-dev mailing list