java MVC + vetoable/deferred property - java

I have an interface FooModel and a class DefaultFooModel that have a few simple properties. I am getting stuck on a boolean enable property because I want to have this be vetoable/deferred:
public interface FooModel {
public boolean isEnabled();
/** returns old value */
public boolean setEnable(boolean enable);
public void addFooListener(FooModel.Listener listener);
public void removeFooListener(FooModel.Listener listener);
public interface Listener {
public void onFooEnableUpdate(boolean newEnable, boolean oldEnable);
}
}
What I want is for the model M to be the central point of access for the enable property. But here's the sequence of events that I want to occur:
view V (or any user of the model M) calls FooModel.setEnable(enable) on an arbitrary thread.
FooModel may either:
a. immediately call onFooEnableUpdate(newEnable, oldEnable) on each of its listeners in arbitrary order
b. start a potentially long sequence of events whereby another entity (e.g. controller C) can decide whether to enable, and somehow let FooModel know, whereby the enable property may be updated and then we proceed as usual in (a) above.
The thing is, I'm not sure how to go about doing this.
Approach 1: the mechanism to do this shouldn't be part of the model's interface. Instead, my DefaultFooModel has an implementation which accepts a FooController:
public interface FooController {
public void onFooEnableRequest(boolean newEnable, boolean oldEnable);
}
When DefaultFooModel.setEnable() is called, it then calls FooController.onFooEnableRequest(). The controller is expected to return immediately, but can take its time to digest the request, and then later call DefaultFooModel.updateEnable() which causes the real onFooEnableUpdate() to get called.
Approach 2: build something into the FooModel interface, but I'm not sure what.
Approach 3: Don't build anything into FooModel, just have it handle a regular property. Instead have the Controller listen to FooModel.onFooEnableUpdate() and override setEnable right away to the old value, then call FooModel.setEnable() later to set the new value.
Any advice?

Make FooModel a class instead of an interface.
The problem I see with making FooModel an interface is the complex logic that needs to be coded into the listener mechanism. It's generally not a good idea to force anyone who implements the interface to have to implement the listener logic as well.
Instead, make FooModel a class, implement the listener interface yourself, and creatively create public methods that can be overridden where you need to implement more specific functionality.
notifyListeners(boolean newEnable, boolean oldEnable) notifies all listeners, by default by calling the following method, but could be overridden to do nothing, or to notify conditionally
notifyListener(Listener listener, boolean newEnable, boolean oldEnable) notifies a specific listener

Related

What is a java.util.EventListener? [duplicate]

This question already has answers here:
Java listener must inherit from java.util.EventListener - why?
(2 answers)
Closed 2 years ago.
I can't find the answer to this question.
What is a java.util.EventListener? How does it work?
I have already done some research on google but I only found this, which isn't very clear: a tagging interface that all event listener interfaces must extend.
Can someone please help?
A listener is a class containing methods that are invoked when certain actions happen.
java.util.EventListener is a marker interface(an interface without any methods) that all listeners should implement.
In fact, it does not even add any functionality but it may be helpful with some IDEs and code-analysis tools.
So, if you want to create your own custom event (that you trigger), you need to somehow call all your listener methods when the event occurs.
For example, you can do this like the following:
At first, you create an interface for your listeners that extends EventListener:
public interface MyListener extends EventListener{
void onEvent();
}
Then, you will need to create a mechanism to register and call all the events:
private Collection<MyListener> listeners=new HashSet<>();
public void register(MyListener listener){
listeners.add(listener);
}
public void eventHappens(){
for(MyListener listener:listeners){
listener.onEvent();
}
}
Then, you can creator a Listener using
public class MyListenerImpl implements MyListener{
private String msg;
public MyListenerImpl(String data){
this.data=data;
}
#Override
public void onEvent(){
System.out.println(msg);
}
}
and you can register it using
register(new MyListenerImpl("Event occurs"));
Whenever a eventHappens() is called(you can call it if you e.g. receive a network packet), all your registered listeners will be executed.
For example:
register(new MyListenerImpl("listener 1 called"));
register(new MyListenerImpl("listener 2 called"));
System.out.println("calling event");
eventHappens();
would print
calling event
listener 1 called
listener 2 called
The first Google hit is the EventListener documentation, as you seem to have discovered.
See that blue navigation bar at the very top of the page? The fourth word is a “Use” link. Go to that.
EventListener provides typesafe polymorphism. For example, java.awt.Component has a getListeners method which requires a subclass of EventListener.
EventListener is actually part of the Java Beans specification. From section 6.4 of that specification:
Since the new Java event model is based on method invocation we need a way of defining and grouping event handling methods. We require that event handling methods be defined in EventListener interfaces that inherit from java.util.EventListener. By convention these EventListener interfaces are given names ending in “Listener”.
A class that wants to handle any of the set of events defined in a given EventListener interface should implement that interface.

Mediator Design Pattern: Why do classes have to inform mediator of their behaviours?

In the following class:
public class Ignition {
private EngineManagementSystem mediator;
private boolean on;
public Ignition(EngineManagementSystem mediator) {
this.mediator = mediator;
on = false;
mediator.registerIgnition(this);
}
public void start() {
on = true;
mediator.ignitionTurnedOn();
System.out.println("Ignition turned on");
}
public void stop() {
on = false;
mediator.ignitionTurnedOff();
System.out.println("Ignition turned off");
}
public boolean isOn() {
return on;
}}
I am unsure of the reason for these lines of code, e.g:
mediator.ignitionTurnedOn();
Why does this class need to invoke this method to inform the mediator that the ignition is on? would this mean that the method is invoked twice? Once by this method and then within the mediator itself?
The purpose of the mediator is to relay information between colleagues. You only have to inform the mediator of things that other colleagues in your system need to know about.
I would venture that in this system, there is perhaps another class perhaps called Engine which has a start() method also registered with the mediator.
When the Ignition start method calls mediator.ignitionTurnedOn(), most likely, the mediator then calls something like getEngine().start() from inside its ignitionTurnedOn() method.
Probably nothing is invoked twice here.
The purpose of the mediator is to provide highly cohesive services that allow to decouple the elements of the system. In terms of a car, the Ignition system would not need to know the details of what happens, e.g., a Choke is opened, a Starter is invoked, etc. as these details can change depending on the type of Engine system.
So, here's what happens likely:
To know for sure, you'd have to see how :Ignition is being called and what Mediator.ignitionTurnedOn() actually does.

Detecting if a listener has been registered

How can I detect if a new listener has been registered for any widget in my android app? Is there a place where I can intercept the listener when it's being registered?
I may be misunderstanding but you could do something like:
public interface ListenerChangeListener { // Feel free to remove the redundancy :P
public void listenerAdded(ListenerChangeEvent e);
public void listenerRemoved(ListenerChangeEvent e);
}
And
public class ListenerChangeEvent extends AWTEvent // or other class {
// Implementation
}
Finally, subclass your own custom widgets and modify the addXListener() and removeXListener() methods to fire your custom events if any have been added to the component. Then you just create your "Listener" class as per normal and implement your new Listener interface and so on.
It's a bit long and drawn out, again, I may have misunderstood exactly what you were after.
You can get a list of listeners on an object through a getter method (e.g. getActionListeners () on AbstractButton), and check if the one you have added is in the list.

Easier Custom Events Handling in Java

In Java, everytime I want to create a new custom event, I usually do it by add 3 methods namely:
addDogEventListener(EventListener listener);
removeDogEventListener(EventListener listener);
dispatchDogEventListener(DogEvent event);
Then now if I want to dispatch another event, say CatEvent, I will have to create all these 3 methods again:
addCatEventListener(EventListener listener);
removeCatEventListener(EventListener listener);
dispatchCatEventListener(CatEvent event);
Then if I want to manage just one kind of CatEvent event, say Meow, I have to copy and paste all these 3 methods again?! Like addCatMeowEventListener();... etc?
And usually, I need to dispatch more than one kind of events. It will be very untidy to have the whole class filled with so many methods to transmit and handle the events. Not only that, these functions have very similar code, like loop through the EventListenerList, add event to the list, etc.
Is this how I should do event dispatching in Java?
Is there a way like I can do it like:
mainApp.addEventListener(CatEvent.MEOW, new EventHandler() { meowHandler(Event e) { });
mainApp.addEventListener(CatEvent.EAT, new EventHandler() { eatHandler(Event e) { });
myCat.addEventListener(DogEvent.BARK, new EventHandler() { barkHandler(Event e) { myCat.run() });
In this way, I can just handle the different types of CatEvent in different eventHandler class and functions and I don't have to keep creating different event listener methods for different events?
Maybe I am missing something out about Java's event handling but is there a neater way that I don't have to keep copy and paste the 3 methods plus creating so many different kind of event objects for every different kind of methods I want to dispatch?
Thanks!
The event handling strategy I have is to publish by type which may suit you.
I have a broker which can examine the listener for an annotation which marks a method as listening to events. Using this approach you only need to add methods when you want to handle a specific class of event.
interface Subscriber { // marker interface for OSGi
}
#interface SubscriberCallback { // marker annotation
}
class Broker {
// uses reflections to find methods marked with #SubscriberCallback
public void addSubscriber(Subscriber subscriber);
public void removeSubscriber(Subscriber subscriber);
public <T> void publish(T... events);
}
class MyListener implements Subscriber {
#SubscriberCallback
public void onDogEvent(DogEvent... dogEvents) {
// called for one or more dog events
}
#SubscriberCallback
public void onCatEvent(CatEvent catEvent) {
// called for each CatEvent including subsclass of CatEvent.
}
}
Then if I want to manage just one kind of CatEvent event, say Meow, (and EAT)
The "action" of the event (MEOW or EAT) should be data defined in the CatEvent. Then your event listening code would check the action type and do the appropriate processing.
Maybe take a look at the TableModelEvent to see how this is done. It handles "insert", "delete" and "update" events using the same event.
Also you could probably model a general event listener based on the PropertyChangeListener. A PropertyChangeListener is used to handle events when various properties change on a Swing component. For example when you invoke setForeground() or setBackground() or setFont() or setText() or setIcon. The PropertyChangeListener uses a getName() method to determine which property has been changed. So for the above methods the names would be "foreground", "background", "font", "text", "icon". See How to Use Property Changes Listeners for an example of how this might work.
In your case the names would be "cat" and "dog". This approach would only work if the GeneralEvent you create can contain information that is relevant to each of your events (ie. "meow" and "bark").

Is there a recommended way to use the Observer pattern in MVP using GWT?

I am thinking about implementing a user interface according to the MVP pattern using GWT, but have doubts about how to proceed.
These are (some of) my goals:
the presenter knows nothing about the UI technology (i.e. uses nothing from com.google.*)
the view knows nothing about the presenter (not sure yet if I'd like it to be model-agnostic, yet)
the model knows nothing of the view or the presenter (...obviously)
I would place an interface between the view and the presenter and use the Observer pattern to decouple the two: the view generates events and the presenter gets notified.
What confuses me is that java.util.Observer and java.util.Observable are not supported in GWT. This suggests that what I'm doing is not the recommended way to do it, as far as GWT is concerned, which leads me to my questions: what is the recommended way to implement MVP using GWT, specifically with the above goals in mind? How would you do it?
Program Structure
This is how I did it. The Eventbus lets presenters (extending the abstract class Subscriber) subscribe to events belonging to different modules in my app. Each module corresponds to a component in my system, and each module has an event type, a presenter, a handler, a view and a model.
A presenter subscribing to all the events of type CONSOLE will receive all the events triggered from that module. For a more fine-grained approach you can always let presenters subscribe to specific events, such as NewLineAddedEvent or something like that, but for me I found that dealing with it on a module level was good enough.
If you want you could make the call to the presenter's rescue methods asynchronous, but so far I've found little need to do so myself. I suppose it depends on what your exact needs are. This is my EventBus:
public class EventBus implements EventHandler
{
private final static EventBus INSTANCE = new EventBus();
private HashMap<Module, ArrayList<Subscriber>> subscribers;
private EventBus()
{
subscribers = new HashMap<Module, ArrayList<Subscriber>>();
}
public static EventBus get() { return INSTANCE; }
public void fire(ScEvent event)
{
if (subscribers.containsKey(event.getKey()))
for (Subscriber s : subscribers.get(event.getKey()))
s.rescue(event);
}
public void subscribe(Subscriber subscriber, Module[] keys)
{
for (Module m : keys)
subscribe(subscriber, m);
}
public void subscribe(Subscriber subscriber, Module key)
{
if (subscribers.containsKey(key))
subscribers.get(key).add(subscriber);
else
{
ArrayList<Subscriber> subs = new ArrayList<Subscriber>();
subs.add(subscriber);
subscribers.put(key, subs);
}
}
public void unsubscribe(Subscriber subscriber, Module key)
{
if (subscribers.containsKey(key))
subscribers.get(key).remove(subscriber);
}
}
Handlers are attached to components, and are responsible for transforming native GWT events into events specialised for my system. The handler below deals with ClickEvents simply by wrapping them in a customised event and firing them on the EventBus for the subscribers to deal with. In some cases it makes sense for the handlers to perform extra checks before firing the event, or sometimes even before deciding weather or not to send the event. The action in the handler is given when the handler is added to the graphical component.
public class AppHandler extends ScHandler
{
public AppHandler(Action action) { super(action); }
#Override
public void onClick(ClickEvent event)
{
EventBus.get().fire(new AppEvent(action));
}
Action is an enumeration expressing possible ways of data manipulation in my system. Each event is initialised with an Action. The action is used by presenters to determine how to update their view. An event with the action ADD might make a presenter add a new button to a menu, or a new row to a grid.
public enum Action
{
ADD,
REMOVE,
OPEN,
CLOSE,
SAVE,
DISPLAY,
UPDATE
}
The event that's get fired by the handler looks a bit like this. Notice how the event defines an interface for it's consumers, which will assure that you don't forget to implement the correct rescue methods.
public class AppEvent extends ScEvent {
public interface AppEventConsumer
{
void rescue(AppEvent e);
}
private static final Module KEY = Module.APP;
private Action action;
public AppEvent(Action action) { this.action = action; }
The presenter subscribes to events belonging to diffrent modules, and then rescues them when they're fired. I also let each presenter define an interface for it's view, which means that the presenter won't ever have to know anything about the actual graphcal components.
public class AppPresenter extends Subscriber implements AppEventConsumer,
ConsoleEventConsumer
{
public interface Display
{
public void openDrawer(String text);
public void closeDrawer();
}
private Display display;
public AppPresenter(Display display)
{
this.display = display;
EventBus.get().subscribe(this, new Module[]{Module.APP, Module.CONSOLE});
}
#Override
public void rescue(ScEvent e)
{
if (e instanceof AppEvent)
rescue((AppEvent) e);
else if (e instanceof ConsoleEvent)
rescue((ConsoleEvent) e);
}
}
Each view is given an instance of a HandlerFactory that is responsible for creating the correct type of handler for each view. Each factory is instantiated with a Module, that it uses to create handlers of the correct type.
public ScHandler create(Action action)
{
switch (module)
{
case CONSOLE :
return new ConsoleHandler(action);
The view is now free to add handlers of different kind to it's components without having to know about the exact implementation details. In this example, all the view needs to know is that the addButton button should be linked to some behaviour corresponding to the action ADD. What this behaviour is will be decided by the presenters that catch the event.
public class AppView implements Display
public AppView(HandlerFactory factory)
{
ToolStripButton addButton = new ToolStripButton();
addButton.addClickHandler(factory.create(Action.ADD));
/* More interfacy stuff */
}
public void openDrawer(String text) { /*Some implementation*/ }
public void closeDrawer() { /*Some implementation*/ }
Example
Consider a simplified Eclipse where you have a class hierarchy to the left, a text area for code on the right, and a menu bar on top. These three would be three different views with three different presenters and therefore they'd make up three different modules. Now, it's entirely possible that the text area will need to change in accordance to changes in the class hierarchy, and therefore it makes sense for the text area presenter to subscribe not only to events being fired from within the text area, but also to events being fired from the class hierarchy. I can imagine something like this (for each module there will be a set of classes - one handler, one event type, one presenter, one model and one view):
public enum Module
{
MENU,
TEXT_AREA,
CLASS_HIERARCHY
}
Now consider we want our views to update properly upon deletion of a class file from the hierarchy view. This should result in the following changes to the gui:
The class file should be removed from the class hierarchy
If the class file is opened, and therefore visible in the text area, it should be closed.
Two presenters, the one controlling the tree view and the one controlling the text view, would both subscribe to events fired from the CLASS_HIERARCHY module. If the action of the event is REMOVE, both preseneters could take the appropriate action, as described above. The presenter controlling the hierarchy would presumably also send a message to the server, making sure that the deleted file was actually deleted. This set-up allows modules to react to events in other modules simply by listening to events fired from the event bus. There is very little coupling going on, and swapping out views, presenters or handlers is completely painless.
I achieved something on these lines for our project. I wanted a event-driven mechanism (think of PropertyChangeSupport and PropertyChangeListener of standard jdk lib) which were missing. I believe there is an extension module and decided to go ahead with my own. You can google it for propertychangesupport gwt and use it or go with my approach.
My approach involved logic centred around MessageHandler and GWTEvent. These serve the same purpose as that of PropertyChangeListener and PropertyChangeEvent respectively. I had to customize them for reasons explained later. My design involved a MessageExchange, MessageSender and MessageListener. The exchange acts as a broadcast service dispatching all events to all listeners. Each sender fires events that are listened by the Exchange and the exchange the fires the events again. Each listener listens to the exchange and can decide for themselves (to process or not to process) based on the event.
Unfortunately MessageHandlers in GWT suffer from a problem: "While a event is being consumed, no new handlers can be hooked". Reason given in the GWT form: The backing iterator holding the handlers cannot be concurrently modified by another thread. I had to rewrite custom implementation of the GWT classes. That is the basic idea.
I would've posted the code, but I am on my way to airport right now, will try to post the code as soon as I can make time.
Edit1:
Not yet able to get the actual code, got hold of some power-point slides I was working on for design documentation and created a blog entry.
Posting a link to my blog article: GXT-GWT App
Edit2:
Finally some code soup.
Posting 1
Posting 2
Posting 3
have a look at: http://www.gwtproject.org/javadoc/latest/com/google/gwt/event/shared/EventBus.html
(which outdates http://www.gwtproject.org/javadoc/latest/com/google/web/bindery/event/shared/EventBus.html)
It should run fine with GWT as I'll try right now myself.

Categories

Resources