<Swing Dev> [PATCH] 6179357: Generics: JList
Florian Brunner
fbrunnerlist at gmx.ch
Thu May 14 13:59:27 UTC 2009
Hi Pavel,
> Hi Florian,
>
>> Hi Pavel,
>>
>> I don't understand, what exactly you want to do.
>> DefaultListCellRender implements ListCellRenderer<Object>, which
>> means it is an implementation, which can be savely (without risking a
>> ClassCastException) be used with ANY object. That is due the fact,
>> that it checks if it is an instance of Icon or else calls
>> Object.toString, which is defined for any Object:
>>
>> if (value instanceof Icon) {
>> setIcon((Icon)value);
>> setText("");
>> }
>> else {
>> setIcon(null);
>> setText((value == null) ? "" : value.toString());
>> }
> Ok, that code actually prevents to use generics in the
> DefaultListCellRender class.
Well, it depends what you mean with "prevents". I guess something like
the following would still compile (did not test):
public class DefaultListCellRender<E> implements ListCellRenderer<E>{
public Component getListCellRendererComponent(
JList<? extends E> list, // or JList<?> ?
E value,
int index,
boolean isSelected,
boolean cellHasFocus)
{
....
if (value instanceof Icon) {
setIcon((Icon)value);
setText("");
}
else {
setIcon(null);
setText((value == null) ? "" : value.toString());
}
...
}
}
But since:
- renderers are consumers (-> "super" keyword is used with wildcards)
and Object is the super type of all types
- generics are only used at compile time
- the only generic method is already implemented without casting (except
in the case of Icon, which cannot be prevented with generics either)
it "prevents" us from the need of introducing a generic type parameter
here. (If you can live with the subclassing issue I mentioned before.)
If later someone really finds a scenario, which needs that generic
parameter here (what I doubt), I think it should still be possible to
change from:
DefaultListCellRender implements ListCellRenderer<Object>
to
DefaultListCellRender<E> implements ListCellRenderer<E>
without breaking backwards compatibility. Correct?
So we don't risk anything by not introducing that parameter right now,
if we don't see any benefit.
What do you think?
-Florian
>
> Thanks, Pavel
>
>>
>> There is no gain in calling eg.:
>> new DefaultListCellRender<Foo>()
>>
>> because the existing implementation (DefaultListCellRender implements
>> ListCellRenderer<Object>) already handles Foo.
>>
>> The only limitation is with sub-classing: Subclasses cannot change
>> the parameter type.
>> But this can be solved with using composition instead of inheritance,
>> eg:
>>
>> public class FooRenderer implements ListCellRenderer<Foo>{
>> private DefaultListCellRender defaultRenderer = new
>> DefaultListCellRender();
>>
>> public Component getListCellRendererComponent(
>> JList<? extends Foo> list,
>> Foo value,
>> int index,
>> boolean isSelected,
>> boolean cellHasFocus)
>> {
>> doSomethingWithFoo(foo);
>> return defaultRenderer.getListCellRendererComponent(list,
>> value, index, isSelected, cellHasFocus);
>> }
>>
>> private void doSomethingWithFoo(Foo foo){
>> // do something
>> }
>> }
>>
>> So, I think the answer is yes, it could be changed, but I see no real
>> benefit and more, client code needs then to specify a parameter,
>> which currently it doesn't.
>>
>> -Florian
>>
>> Pavel Porvatov schrieb:
>>> Hi Florian,
>>>
>>> I have a question about the DefaultListCellRenderer class. Can we
>>> modify it to use generics?
>>>
>>> Thanks, Pavel
More information about the swing-dev
mailing list