How to get com.google.web.bindery.event.shared.EventBus instance in com.google.gwt.user.client.ui.Composite extending class?;
I've readed: How to use EventBus for non-Presenter class in GWTP?, but I am looking for answer like:
BEST APPROACHES TO GWT DEVELOPMENT
I have widget that I would like to fire an event IndicatorEvent. But in this widget I don't have a handler for this event.
The handler is in other class. So to fire it I will use:
fireEvent(new IndicatorEvent("Custom Widget Message"));
Method fireEvent is avalible in com.google.web.bindery.event.shared;EventBus
public abstract void fireEvent(Event<?> event);
So I need an instance of EventBus in view class that extends Composite. This view doesn't have MVP stuff (presenters, uihandlers, etc.) it is simple one class element/widget.
What approach should I pick up?
Should I convert this to Presenter/View pair? (In gwtp presenters is EventBus reference from PresenterWidget class) And then using ui handlers, delegate execution from view to presenter?
Should I inject instance of EventBus into widget class?
Please help.
Any Widget can fire an event without using the EventBus.
If you know the recipients of this event, you can simply attach handlers directly to the recipients. To do that, you define this method in your composite widget:
public HandlerRegistration addIndicatorEventHandler(IndicatorEventHandler handler) {
return addHandler(handler, IndicatorEvent.TYPE);
}
and then in your other widget (recipient):
myCustomWidget.addIndicatorEventHandler(new IndicatorEventHandler() {
#Override
public void onIndicator(IndicatorEvent event) {
// do something
}
});
You will need to use EventBus if (a) there is no direct/easy link between the two widgets (firing event and event recipient), (b) there are many recipients, and/or (c) you do not want to create a dependency between parts of your code which contain event firing widget and event recipients.
We can assign only single component per view. So approach first doesn't make any sense as we creates lots of component/widgets for all small sections from particular view.
Second approach is comparatively more likable if we are already using some dependency injection framework like gin or dagger2.
I can add one more approach is to have simple setter method in component for passing eventBus instance from the parent class like presenter or controller where we are using/creating component object.
My conclusion will be it absolutely depends upon purpose and implementation of component. If we have interface-implementation or presenter-implementation kind of component stating some common behavior second approach is best suitable way. On the other hand if we have simple plane component serving just as small part of view, I will recommend third approach.
Related
I'm trying to create a UI library that basically holds a lot of methods and actions I typically use when building a layout. One example of such a function is managing the fab clicks. I have one fab in the main activity, and I change its function, icon, and visibility based on which fragment is loaded. I'm currently doing everything with interfaces as you can see here. It all works fine, but the only issue is that I have to make sure other users use activities and fragments that extend my interface.
Example
protected void hideFab() {
capsuleActivity().getFab().hide();
}
protected CActivityCore capsuleActivity() {
if (!(getActivity() instanceof CActivityCore)) {
throw new RuntimeException(s(R.string.capsule_activity_context_error));
}
return ((CActivityCore) getActivity());
}
If they don't need the functions for one fragment, they have to override a lot of my methods to make it not do anything. My other option could be to use an EventBus, and to just send various events whenever something is called and resolve it accordingly. That way, it no longer matters if users use my classes or not; if they only want the functions in a few fragments, they can just extend my fragment for those fragments and not worry about the rest.
My question is, would this be a nice and viable way of doing things, or is this moreso overkill as to how EventBuses should be used?
Another function I'm considering is to have the activity send a callback to the current fragment and have it run only if the fragment extends a certain class.
Current implementation:
#SuppressWarnings("unchecked")
protected <T extends Fragment & CFragmentCore> void onCurrentFragment(Class<T> clazz, #NonNull Current<T> callback) {
Fragment current = getSupportFragmentManager().findFragmentById(getFragmentId());
if (clazz.isInstance(current.getClass())) {
callback.onMatch((T) current);
}
}
But I could also instead use an EventBus with an event containing the class and a callback function.
Using an EventBus is a design choice. It has advantages and disadvantages, which you can easily find on Google.
There is no such thing as an "overkill" if you are able to simplify your code.
Apart from that, an EventBus is probably a good idea in your scenario, as it provides an easy way to manage View-Controller communication.
Let's say I have a class that builds a GUI and has a method updateMainUI(String text) that appends text to a JTextArea. Currently, I'm using abstract classes and methods to update the field from a different class, but I'm wondering if this is the 'right' way to do it?
I now have three abstract classes that have an protected abstract updateUI(String text) method that I override in my GUI class to update the field whenever I need to, but I'm doing the same thing in multiple classes and now I feel like I need another class that does the exact same thing.
Is there a better or more acceptable way of doing this?
From you question, it's difficult to be 100% sure, but, it is generally encouraged to use a Model–view–controller approach to these types of problems.
This is, the model defines the "virtual" state, the view represents this state to the user and the controller controls changes to the model initiated from the view...
The view is notified, by the model, when it changes, so it can update the state and the view notifies the controller when some part of its view/state has changed and may be reflected in the model.
To this end, I would encourage you to define some kind of model, which is normally described by a interface which can be used by the various aspects of your program. Updates to the model don't need to come from the user/UI, but you will need to ensure that you clearly document when notifications might come from a different thread other than the Event Dispatching Thread, so your UI code can take correct actions and synchronise the updates.
So, based on you example, your model might have a method call setText (or some such), which triggers some kind of event notification to registered listeners.
This instance of the model would be shared amongst the various classes of your application
You main UI would be one of these classes listening for a change in the models state, when it detected a change, it would update its state accordingly.
This is an example of the observer pattern and you see this in use all over Swing (via it's listener/event API)
Where best place to register event handlers when using MVP paradigm? I know that application wide events must be registered in "AppController", but I need to rise event from one presenter, and second presenter must handle it . So is better to define eventHandler inside AppController, or better to define eventHander inside second presenter (rise this event in 1st presenter)?
Application wide events don't necessarily have to be registered in the AppControler.
I don't think it actually actually where you register them as long as you pass around and use one global singleton EventBus.
Normally you pass this global EventBus to your various Presenters via a constructor parameter (using dependency injection for example).
In the first presenter you can register for a specific event which is fired by the second presenter on the global EventBus.
In the examples provided by Google Web toolkit that they are adding the event handlers in one class only for the whole application.
As in - for Module1, 2 and 3 all events are registered in the main AppController class. I find this a bit monolithic and would not it better when we are using the MVP pattern that we declare a method called bind() in each of the Presenters that is as follows:
public class MyTestPresenter implements Presenter{
private void bind()
{
TestEvent.eventBus.addHandler(TestEvent.Type, new TestEventHandlerImpl() )
}
}
public class TestEvent
{
public static SimpleEventBus eventBus = new SimpleEventBus()
}
Query is:
If our application is huge - we would be using one eventbus to populate more than a thousand events in it - or would we design in such a way that we have separate instances of event bus for each module?.
Any cost of keeping the static event bus field. Any better design to give it's instance to all classes - passing it around to all classes through a constructor with each presenter class having it's reference seems a bit of clutter ...
What are activity and places in GWT when it comes to event handling? - Can someone give a pointer to how to understand the concept of activity/place in general?
Actually I dislike event bus implementation in GWT too. I've asked smt about before.
Now I develop some desktop application and I design eventBus in next way.
public interface EventBus {
void fireEvent(Event event);
<T extends Event> void addHandler(Class<T> eventType, Handler<T> handler);
interface Event {
}
interface Handler<E extends Event> {
void handle(E event);
}
}
So in usual Java application I would design it in other way, but here we should deal with issues connected with javascript and so on.
If our application is huge - we would
be using one eventbus to populate more
than a thousand events in it - or
would we design in such a way that we
have separate instances of event bus
for each module?.
I was thinking about this question too. I found that there are no any real advantages. For modularity you can separate visibility of your events. And there is some disadvantage. Suppose you should deal with several eventBusses in same class - code will be messy. Beside you should map this instances to classes somehow.
Any cost of keeping the static event
bus field. Any better design to give
it's instance to all classes - passing
it around to all classes through a
constructor with each presenter class
having it's reference seems a bit of
clutter ...
You can do both. In new Activity-Place framework it passed as parameter.
What are activity and places in GWT
when it comes to event handling? - Can
someone give a pointer to how to
understand the concept of
activity/place in general?
Activity it's like your old presenter but without low level view binding. Place just like history entry that used for specify windows.
I'm building a GUI application and try to adhere to the MVC principle as good as I can.
Therefore my model fires PropertyChangeEvents with the help of PropertyChangeSupport so the GUI knows what to update when.
The model of my application is nested, i.e. I have a main model class that contains some properties or Lists of other model classes which in turn might contain more model classes.
A simple example:
public class MainModel {
private int someData;
private List<Stuff> stuffList;
// imagine PropertyChangeSupport and appropriate getters/setters
// for both MainModel and Stuff
}
Now both MainModel and Stuff have PropertyChangeSupport. If someone listens to events fired from MainModel, it gets changes of someData and from adding/deleting to/from the list stuffList.
But what if someone wants to get events from changes made to the individual elements of stuffList? There are two possibilities:
The observer has to fetch the list of Stuff elements and register as a listener to each element separately.
The main model registers itself as a listener to the elements of stuffList when they are added and forwards these events to the listener of the main model.
This is how it looks like with the first approach:
mainModelInstance.addListener("new stuff element", new PropertyChangeListener() {
public void propertyChanged(PropertyChangeEvent evt) {
Stuff s = (Stuff) evt.getNewValue();
s.addListener( // ... and so on
);
}
});
I think 1. has the advantage of keeping the model clean and dumb but leads to code duplication (many UI elements have to listen to changes to stuffList and add themselves dynamically to the new Stuff elements, see above). With 2. its the opposite: The client code is not as messy but the model acts partly as a listener which somehow doesn't feel right. That's why I currently use the first approach.
What are your thoughts? Maybe I'm too harsh on myself and 2. is okay. Or maybe there is a completely different (and better) way?
For at least 20 years, I've programmed MVC models observing other models (like for doing what is now called MVP[resenter] or MVVM patterns), and here are some heuristics I'd offer...
(1) Views and Controllers are hierarchical, and GUI event handling has long recognized that by letting event listeners listen at different levels of the hierarchy (like directly at a button level, or at the entire web page level). Each event specifies the most specific component associated with the event even if a higher level container was being listened to (aka observed). Events are said to "bubble up".
(2) Models can equally be hierarchical. The Model-generated "update" event can also use the same technique as above, specifying in the event the most specific "inner model" associated with the update event, but allowing observing at the "outer" composite model level. Observer update events can "bubble up".
(3) There is a common paradigm for hierarchical models...the spreadsheet. Each cell is a model that observes the other models/cells referenced in its formula.