ovie
ovie

Reputation: 621

GWT.create(clazz) "generics" approach

I have to develop an "generic" wigdet for a GWT/GXT project and to do so I need to create an instance of an object which type is unknown. I found an approach that works perfectly in dev mode but as soon as I try to compile my project and deploy it I get an Only class literals may be used as arguments to GWT.create() error.

Here is a sample of what I do:

public class GenericEditableGrid<M> extends Grid<M>{
    private final ToolBar toolBar = new ToolBar();
    private final TextButton newItemButton = new TextButton();
    protected GridInlineEditing<M> editing;
    private final Class<M> clazzM;

    public GenericEditableGrid(Class<M> parametrizedClass, String gridTitle, ListStore<M> listStore, ColumnModel<M> cm) {
        super(listStore, cm);
        clazzM = parametrizedClass;
        // ... then I create my widget
        bind();
    }
    private void bind(){
        newItemButton.addSelectHandler(new SelectEvent.SelectHandler() {
            @Override
            public void onSelect(SelectEvent selectEvent) {
                editing.cancelEditing();
                // it is the folliwing line which is the problem obviously
                M element = GWT.create(clazzM);
                getStore().add(0, element);
                int index = 0;
                editing.startEditing(new Grid.GridCell(getStore().indexOf(element), index));
            } 

        });
    }
}

And this is how I use it in my subclasses:

super(InternationalString.class, gridTitle, new ListStore<InternationalString>(isprops.key()), buildColumnModel());

Basically, I would like to know what the problem is exactly with this approach and eventually how I should do to make it well.

Please note that my concern is not just to make it work, but more to do it the right way. As I could just avoid the problem using an abstract method which would handle the GWT.create() method in the daughter classes. But this is not the design I want, it just doesn't look right.

What I don't get also is what's the difference between doing this:

MyClass e = GWT.create(MyClass.class);

and:

Class<MyClass> clazz=MyClass.class;
MyClass e = GWT.create(clazz);

Because as far as I am concerned I think this is basically what I am doing and it looks like the same thing. Isn't it?

Upvotes: 2

Views: 1094

Answers (1)

StriplingWarrior
StriplingWarrior

Reputation: 156459

There's a well-worded explanation in this forum:

As the error message indicates, only class literals may be passed to the GWT.create method. The reason for this is that all GWT.create calls are basically turned into constructors at compile time, using the deferred binding rules for your module. As a result, all classes must be decided at compile time - your code requires that the at runtime the class is decided. This is too late, and so cannot be compiled.

GWT is not proper java, and so cannot be always treated as java. This is one such example of things that cannot be done in gwt. ...

What is it you are trying to do? Either you are making it far more complicated than it needs to be, or you need to write a generator to do it instead of taking this approach.

Upvotes: 2

Related Questions