0

I have an object that implements "IsTreeItem". The Object is displayed as a two level tree item. Each tree item is built with a check box. I need to know when a check box is changing value - so i am listening to ValueChangedEvents.

The first problem is that the Tree built with such items only fires SelectionEvents. If selection is changing the check box the ValueChanged event is fired afterwards - so there is no way to listen to events inside "IsTreeItem" from Tree.

So i let my "IsTreeItem" fire its own element. So i (field)injected an EventBus and used it to fire the event if "ValueChanged". The Problem is that my "IsTreeItem" is an Object sent from server (it is in shared package and serializable). The object is instantiated on server (EventBus is not ionjected) and "asTreeItem" is called on client.

Is there a way to inject the EventBus in the Method TreeItem asTreeItem() in some way? Or are there any other means to let some one outside know if a check box has changed its value.

dermoritz
  • 12,519
  • 25
  • 97
  • 185

1 Answers1

2

GIN can do member injection on already created instances.

You have to create a method in your Ginjector interface that takes such an instance as argument, with a return type of void.
Note that because no reflection is done on the client, GIN will only inject fields and methods from the class used as the argument type (and its super-classes).

@GinModules(MyGinModule.class)
interface MyGinjector extends Ginjector {
    …

    void injectIsTreeItemMembers(IsTreeItem item);
}
Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
  • that does not work or i did it wrong: added "void injectAttributeTreeItem(AttributeTreeItem item);" to client injector (also tried with IsTreeItem as type). My tree item has a field "@Inject private transient EventBus eb;". In meantime i got it to work via "EventBus getEventBus();" in client injector and "ClientInjector injector = GWT.create(ClientInjector.class); eb = injector.getEventBus();" in my TreeItem. but this feels bad somehow. – dermoritz Dec 05 '12 at 14:42
  • when will gin inject such an class? – dermoritz Dec 05 '12 at 14:50
  • You obviously have to call `injectIsTreeItemMembers()` with the object whose members you want to inject. TBH, I believe you have a design issue; putting an `EventBus` inside a DTO feels wrong. You'd probably better wrap your DTO on client-side to _intercept_ the setters and fire the event in addition to updating the wrapped DTO; or something along this line. – Thomas Broyer Dec 05 '12 at 14:55
  • your are absolutly right about "design issue" - at the moment we needed to listen to events inside "asTreeItem" we considered refactoring to split data from possible widget representation. But now we need to push out a release - refactoring must wait ;-) one question left: when to call injectIsTreeItemMembers? but in any case i need to get the injector "GWT.create(ClientInjector.class)" right? – dermoritz Dec 05 '12 at 15:01
  • Q: “when to call injectIsTreeItemMembers?” A: when you need it? Q: “in any case i need to get the injector "GWT.create(ClientInjector.class)" right?” A: to share a singleton `EventBus`, you need to use a singleton `ClientInjector`. – Thomas Broyer Dec 05 '12 at 15:20
  • i need "injectIsTreeItemMembers" when some one calls asTreeItem. So i need to inject the injector at the place where the tree is created? before creating the tree i call the method right? But how to get a singleton injector? at the moment i call ClientInjector injector = GWT.create(ClientInjector.class); in my "EntryPoint". i could add a "@Provider" for ClientInjector in my gin-module. but can i inject this injector also in my entry point class? Is this the way to get a singleton injector? – dermoritz Dec 05 '12 at 15:44
  • You can either store the `ClientInjector` in a static public field (crappy but works), or you can inject it anywhere you need it (just like you can inject the `Injector` with Guice) – Thomas Broyer Dec 05 '12 at 16:37