0

I try to create a composition of the class org.eclipse.swt.custom.CCombo (for 'project' reasons, I can't inherit from CCombo).

The goal is to avoid this code everywhere, when I want to retrieve the selected data element:

MyElement selectedElement = (MyElement)  myCombo.getData(Integer.toString(selectedIndex));

The combo is filled like this:

combo.setData(Integer.toString(myIndex), myObject);

So here is what is did so far:

public class GenericCCombo {

private CCombo combo;

public GenericCCombo(CCombo c) {
    combo = c;
}

public IGenericComboList getSelectedData () {
    return (IGenericComboList) combo.getData(String.valueOf(combo.getSelectionIndex()));
}

IGenericComboList is juste this:

public interface IGenericComboList {
public String getDescription();
}

So in my implementation code I can retrieve my selected data like this:

 //MyElement is just an enum that implements IGenericComboList.
 MyElement selectedElement = (MyElement)dateCombo.getSelectedData();

My question is: can I use 'generic type' to avoid casting here :

(MyElement)dateCombo.getSelectedData();

??

Tyvain
  • 2,640
  • 6
  • 36
  • 70
  • Take a look at http://stackoverflow.com/questions/7526817/use-of-instance-of-in-java Its never clean - a better solution would be to get the specific methods you want to use into the interface, so you don't have to know what the underlying instance is. – Catalyst Jul 05 '15 at 22:17
  • Can getData return other implementations of IGenericComboList? If so, how do you know that casting to MyElement is safe? Looks like the gist of this question is 'how to use generics'. Take a look at https://docs.oracle.com/javase/tutorial/java/generics/types.html. :) – Reinstate Monica Jul 05 '15 at 22:23
  • Can `combo` store multiple types? ie two different types of class at different indexes? (ie is it a "mixed bag" of stuff) – Bohemian Jul 06 '15 at 00:28

3 Answers3

0

You could declare GenericCCombo with a generic type argument:

class GenericCCombo<T> {
    public T getSelectedCombo() {
        //...
    }
}

When you create your GenericCCombo object, specify MyElement (or whatever element you want):

GenericCCombo<MyElement> dateCombo = ...;

If you aren't sure which value may be returned, making generics a bad option, look into the visitor pattern. Rather than being required to know the type of the object being used, you pass information to the object and allow the object itself to process it.

Community
  • 1
  • 1
Vince
  • 14,470
  • 7
  • 39
  • 84
0

Yes, you may use generics here, and the way to do it is with a generic parameter on GenericCCombo. I would suggest you make the .class of the incoming element an additional parameter, and use that as a double-check that you have the right class:

public class GenericCCombo<E extends IGenericComboList> {

  private CCombo combo;
  private Class<E> clazz;

  public GenericCCombo(CCombo c, Class<E> clz) {
    combo = c;
    clazz = clz;
  }

  public E getSelectedData () {
    Object o = combo.getData(String.valueOf(combo.getSelectionIndex()));
    if (! clazz.isInstance(o)) {
      throw new ClassCastException(String.format(
          "Element '%s' is instance of %s. Expected: %s",
          o, o.getClass(), clazz));
    }
    return clazz.cast(o);
  }
}
Daniel Martin
  • 23,083
  • 6
  • 50
  • 70
-1

Yes, its possible. Define your interface IGenericComboList with Generic type.

interface IGenericComboList<E> {
    public String getDescription();
}

Ensure that the "dateCombo.getSelectedData();" returns an element of IGenericComboList

Ratha
  • 46
  • 5