How to Use Java Observer's update(Observable, Object) Function? - java

I have a basic MVC pattern created in Java that uses the Observable/Observer class/interface.
Observable Observer Observable/Observer
Model Controller View
View triggers an event to the Controller, when the user interacts with the GUI.
- E.g presses a button, fills in a field, etc.
Model triggers an event to the View when it updates its state.
- E.g when the a button was pressed and the Controller requests new results.
My question is about the Observer function
update(Observable obs, Object arg);
This is one function, but I have many different kinds of updating to do in my View for example. How do I elegantly distinguish between an update to, say, my search results or the displaying of additional information? These are two completely different updates that use different objects from the Model.
My first idea was to use the Object to pass a string which would describe what update is required.
"UpdateResults" "DisplayAdditionalInformation" "AddQuestions"
but that seems error-prone and ugly. My second instinct was to create an EventObject that would be passed as an Object, but then I have to keep asking what kind of EventObject I'm using:
if (arg instanceof ResultEventObject)
// Get results from model
else if (arg instanceof InformationEventObject)
// Get information from model
else if (arg instanceof QuestionsEventObject)
// get questions from model
My third idea is to simply update everything, but that seems pointlessly inefficient.
I am probably not understanding the Observable/Observer interface correctly or I'm not using update() as it was intended by it's authors. Therefore my question, how do I use the updatefunction properly when I have many different types of updates or events to process?

You can create your own Listener interfaces depending on what view/model you are listening to. This allows your view/model to pass exactly the information required to your controller and will make it easier to unit test the controller.
For listening to the model, updating everything is the simplest solution and you can do that unless performance proves to be an issue.

Yes, I think its better to use Listener Interface
check this note http://www.softcoded.com/web_design/java_listeners.php

Related

Java Swing GUI User actions handling

How should Listeners etc be managed? I've found only examples with one button etc.
I can think of following options:
Extra class for each - doesn't seem right, especially when items
can be created dynamically
Class for each group (such as form1,
form2, controlButtonsOnLeft, controButtonsOnRight, mainMenu,
userMenu, ...) where I'll check which button/component caused this
(via getSource method for example)
Some super (sized) controller,
which will accept all user actions
New anonymous class for each,
which will call controller's method with parameters specifying
details (probably enums)
And another question: I've found many examples for MVC, I was wondering what is better (or commonly used) for app. developed by 1 person (app will not be huge)?
A. Viewer sets listeners to controller (A1-3)
B. Controller calls viewer's methods, which accepts listener as parameter (methods addLoginSubmitListener, addControlBoldButtonListener etc)
All of above are possible to implement and so far I would choose B4.
Meaning in Control I would do something like this:
...
viewer.addLoginButtonListener(new Listener()
{
#Override
public void actionPerformed(ActionEvent e) {
...
someButtonsActionHandler(SomeButtonEnum, ActionEnum);
...
}
});
...
private void LoginActionHandler(LoginElementsEnum elem, ActionEnum action)
{
if (elem.equals(LOGINBUTTON)) {...}
...
}
...
This combines readable code (1 logic part at one place in code), doesnt create any unwanted redundant code, doesnt require any hardly-dynamic checks, is easily reusable and more.
Can you confirm/comment this solution?
To be honest the question comes down to a number of questions...
Do you want reusability?
Do you want configurability?
Are they self contained? That is, does it make sense for anybody else to listener to the component or need to modify the resulting action of the listener in the future?
Personally, I lean towards self containment. A single listener for a given action/task. This makes it easier to manage and change should I need to.
If I don't need reusability (of the listener) or configurability, then an anonymous inner class is generally a preferred choice. It hides the functionality and doesn't clutter the source code with small, once use classes. You should beware that it can make the source code difficult to read though. This of course assumes that the task is purpose built (its a single, isolated case). Normally, in these cases I will prefer to call other methods from the listener that actually do the work, this allows a certain amount of flexibility and extendability to the class. Too often you find yourself wanting to modify the behaviour of a component only to find that behaviour buried within an anonymous or private inner class...
If you want reusability and/or configurability - that is, the listener performs a common task which can be repeated throughout the program or over time via libraries, then you will need to provide dedicated classes for the task. Again, I'd favour a self contained solution, so any one listener does only one job, much easier to change a single listener then having to dig through a compound list of if-else statements :P
This could also be a series of abstract listeners, which can build functionality for like operations, deleting rows from a table for example...
You could considering something like the Action API (see How to Use Actions for more details), which are self contained units of work but which also carry configuration information with them. They are designed to work with buttons, such as JButtons and JMenuItems, but can also be used with key bindings, making them extremely versatile...
The second part of you question (about MVC) depends. I prefer to keep UI related functionality in the view and out of the controller as much as possible. Instead of allowing the controller to set listeners directly to components, I prefer to provide my own, dedicated, listener for the controller/view interaction, which notifies the controller of changes to the view that it might like to know about and visa versa.
Think about it this way. You might have a login controller and view, but the controller only cares about getting the credentials from the view and authenticating them when the view makes the request, it doesn't care how that request is made from the views perspective. This allows you to design different views for different circumstances, but so long as you maintain the contract between the view and the controller, it won't make any difference...But that's just me.

How can I update a GUI from multiple classes?

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)

MVC architecture implementation

Originally I had the view holding commands for buttons, these buttons calculated this and output text onto JTextAreas after being pushed. What is produced is dependent on the value returned.
I am concerned I am not following standard MVC architecture by setting text like below inside my controller.
At the moment I changed my button commands into my controller as so
private class ReadActionListener implements ActionListener {
public void actionPerformed(ActionEvent l) {
/* there is other code in here, which results in setting text its not
just a set text button*/
/*interactions with model etc etc, outcome true? setText JTextArea like below*/
view.variable.setText("hi there");
}
}
Should I be setting text for the view inside the controller or is this breaking standard MVC architecture?
Thanks,
Jim
In MVC, you should not update the view from the controller. The controller is meant for event handling and altering the model according to these events. The model should then update its observers, ie. the view.
You can read up on the Observer design pattern here: http://javarevisited.blogspot.nl/2011/12/observer-design-pattern-java-example.html
There is a code example provided on that website as well.
In MVC, the model is a layer.
The model layer comprises of multiple objects: domain objects, services and mappers. You can read more in this post (although in PHP, the concepts still hold substance).
That being said, your controller handles the input from the user, sends this to the relevant object within the model layer, which then returns this data to the controller - and then your controller sends this to the view instance which handles the logic for displaying this to the user.
The observer pattern is really interesting and Koen's link above is a good one. I saved this snippet a while back from somewhere on SO:
Have state-setting operations on Subject call Notify after they change the
subject's state. The advantage of this approach is that clients don't have
to remember to call Notify on the subject. The disadvantage is that several
consecutive operations will cause several consecutive updates, which may be
inefficient.
Make clients responsible for calling Notify at the right time. The advantage
here is that the client can wait to trigger the update until after a series
of state changes has been made, thereby avoiding needless intermediate updates.
The disadvantage is that clients have an added responsibility to trigger the
update. That makes errors more likely, since clients might forget to call Notify.
This old but still valid example of the observer pattern may still be useful: http://javanook.tripod.com/patterns/observer.html

Using OO Observer pattern without updating object from which change originated

I'm building an application which contains a GUI and a Model. I'm using the Observer pattern (using java's built in interfaces) to update the GUI when fields in the model are changed.
This is generally working fine, but I have a situation in which a particular String variable in the model (specifically the url of a file) can be changed by two separate JTextFields (swing) the contents of which actually reflects the value of the model variable in question.
The issue I am having comes from the fact that an change in one of these JTextFields needs to cause an update to the state of the model, and the contents of the other JTextField. My Model ensures that notifications are sent to observers only in the case that the state of the model has changed. However, the process by which JTextFields are modified involves blanking it's text content then reseting it.
Without going into too much detail, the upshot of this is that the update / notification process gets stuck in an infinte loop. I have temporarily hacked around this by setting aside the observer pattern for this particular problem, but I was wondering if anyone could suggest a neat way of ensuring that a particular component is not "updated" by a change which originated from the same component.
Any help appreciated.
As discussed in Java SE Application Design With MVC, this is one of several Issues With Application Design. The suggested approach relies on a PropertyChangeListener, illustrated here. The PropertyChangeEvent includes both old & new values for reference.
This link which talks about a Bidirectional Observer may offer some help on this.
It does seem in your case that the Model and View are trying to update each other. The solution would lie in enforcing the direction of an update. For example Inner layer -> Model -> View and View -> Model -> Inner layer. So it wouldn't really be a true Observer Pattern.
The update(Observable o, Object arg) method of java.util.Observer does accept an Observable(Subject) object. This object can be used to provide a hint to the Model asking it to propagate the update inward rather than toward the View.
I gave it a quick try and found that setting up Bidirectional observer (using Java apis) is not as simple as I thought. But you could venture a try.

Java Swing: keeping the event handling maintanable

In my current project we are using for our Swing client the following patterns:
Business Object (POJO) <--> (mapping) <--> Presentation Model (POJO with property change support) <--> (binding) <--> view components
Everything is fine and works the way we are expecting them to behave.
BUT, we encouter those problems when view begin to grow:
Many events are fired, resulting in cascading events. One update on a field may result in dozens of subsequent property update
When dialog complexity grows, the number of listeners grows as well, and the code begin to be messy and hard to understand.
Edit after first answer:
We don't fire event if there is no change on value.
We don't add listener if we have no need for them.
We have screen with very complexes rules and with a need for notification from other related panels. So we have a lots of useful listeners and a single user change can triggers many underlying events.
The idea about binding the presentation model with the business model is not so good for us: we perform some code in the mapping process.
I'm looking for guides, advices, best practices, etc about building maintainable Swing application, especially for the event management side.
There are many ways of reducing the number of events being sent.
Don't propagate an event when there is no change. A typical example for this one ios the idiomatic way of writing a setter triggering a PropertyChangeEvent (see below) but it is the case for all kind of events you fire by hand.
public void setMyField(Object newValue) {
Object oldValue = myField;
if((oldValue==null && newValue!=null) || (oldValue!=null && !oldValue.equals(newValue))) {
myField = newValue;
propertyChangeSupport.firePropertyChange("myField", oldValue, newValue);
}
}
}
Only register as event listener when you start to be interested in, and unregister as soon as you stop being interested in. Indeed, being a listener, even if it is for no action, forces the JVm to call the various methods used for event propagation. Not being a listener will avoid all those calls, and make the application by far simpler.
Consider replacing your POJO to increased POJO mapping by direct instanciation of increased POJO. or, to say things simpler : make your POJO authentical java beans with PropertyChangeEvent handling abilities. To allow them to be easily persisted, an easy solution is, once "rehydrated", or loaded from the persistence layer, add a persistence updater mechanism as PropertyChangeListener. This way, when a POJO is updated, the persistence layer gets notified, and updates the object in DB transparently.
All these are rather simple advices, requiring only a great dose of discpline, to ensure events are fired only at the right time, and for the right listeners.
I suggest a single event action per model. Don't try breaking it down to fields with the hopeless ProtpertyChangeListener. Use ChangeListener or your own equivalent. (Honestly, the event argument is not helpful.) Perhaps change the 'property' type to be a listenable object, rather than listening to the composite object.
The EventListenerList scheme used by most Swing components is fairly lightweight. Be sure to profile the code before deciding on a new architecture. In addition to the usual choices, another interesting approach to monitoring event traffic is suggested by this EventQueue subclass example.

Categories