Salut,
je viens de rencontrer un problème de types paramétrés qui m'a obligé à mettre en place une solution qui ne me plait pas. Mais j'ai beau chercher, je n'arrive pas à trouver comment obtenir une solution satisfaisante.
En résumé, j'ai tout d'abord une interface :
J'ai dans un composant une méthode comme ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part public interface IViewItem<O> {...}
J'ai une action qui appelle cette méthode à partir d'une sélection, donc un objet de classe implémentant l'interface org.eclipse.jface.viewers.ISelection.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 public void expand(Collection<IViewItem<?>> objects, int level) { if ( objects!=null ) { if ( level<0 ) level = TreeBasketViewer.ALL_LEVELS; for(Object object : objects) { getViewer().expandToLevel(object, level); // getViewer() me renvoit du org.eclipse.jface.viewers.TreeViewer } } }
Comme les implémentations de cette interface ne me renvoit que des Object[] ou des List (sans paramètre), je me suis fait une classe d'utilitaire avec une méthode pour obtenir une collection paramétrée, ce qui facilite le traitement en amont, comme suit, qui me permet en plus d'extraire uniquement les objets qui correspondent à la classe spécifiée :
En général, elle me sert à récupérer dans une sélection d'instances de type différents, les objets d'un type donné et je peux ainsi facilement écrire :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 public static <T> Collection<T> getSelection(ISelection selection, Class<T> clazz) { Collection<T> col = new ArrayList<T>(); return _getSelection(selection, col, clazz, false); }
Maintenant pour appeler ma méthode expand, j'ai une action avec le code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 for(Page page : SelectionUtil.getSelection(selection, Page.class)) { if ( page.getFolio().isOdd() ) { ... } }
Elle fonctionne mais, ce qui ne me plait pas, c'est le fait de créer une nouvelle ArrayList (le code en rouge), de dupliquer en fait ma collection d'origine. Et en plus de devoir caster en Collection<? extends IViewItem<?>>. Ça ressemble a de la bidouille.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 @SuppressWarnings("unchecked") @Override public void run() { BasketSelection basketSelection = (BasketSelection) getBasketHandler().getSelection(); Collection<? extends IViewItem<?>> tmpobjects = (Collection<? extends IViewItem<?>>) SelectionUtil.getSelection(basketSelection.getItemSelection(), IViewItem.class); Collection<IViewItem<?>> objects = new ArrayList<IViewItem<?>>(tmpobjects); switch(state) { case ONE_LEVEL: basketHandler.expand(objects,1); break; case ONE_LEVEL_MORE: basketHandler.expandMore(objects,1); break; case ALL_LEVELS: basketHandler.expand(objects,TreeBasketViewer.ALL_LEVELS); break; } }
SelectionUtil.getSelection(basketSelection.getItemSelection(), IViewItem.class); retourne du Collection<IViewItem> qui ne peut être casté en Collection<IViewItem<?>>, type attendu par la méthode expand().
J'ai essayé de modifier ma méthode SelectionUtil.getSelection(...) avec : Collection<? super T>, Collection<? extends T>, mais j'ai toujours un problème au final lors de l'appel de expand(...).
Evidemment, pour getSelection(), le type T peut être n'importe quelle classe, paramétrée ou pas paramétrée.
Si je fais :
ça ne compile pas parce que objects devrait être du Collection<IViewItem<?>>...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Collection<IViewItem> objects = SelectionUtil.getSelection(basketSelection.getItemSelection(), IViewItem.class); switch(state) { case ONE_LEVEL: basketHandler.expand(objects,1); break; ... }
Si je fais :
Je ne peux évidemment pas compiler à cause du fait que je ne peux pas caster du Collection<IViewItem> en Collection<IViewItem<?>>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Collection<IViewItem> objects = SelectionUtil.getSelection(basketSelection.getItemSelection(), IViewItem.class); switch(state) { case ONE_LEVEL: basketHandler.expand((Collection<IViewItem<?>>)objects,1); break; ... }
Je ne peux pas écrire :
Je ne trouve pas de solution...
Code : Sélectionner tout - Visualiser dans une fenêtre à part Collection<IViewItem<?>> objects = SelectionUtil.getSelection(basketSelection.getItemSelection(), IViewItem.class);
Partager