In an Android app (or Java more generally if it's no different), what is the best way of calling a method whenever a variable's value changes?
What you really want to do is set up event-driven model to trigger a listener when an event happen (in your case, say a variable value has changed). This is very common not only for Java, but for other programming languages as well especially in the context of UI programming (though it is not necessarily only for that)
Typically this is done by doing the following steps:
Decide the interface that the listener should implement in the case of the event is triggered. For your case, you could call it VariableChangeListener and define the interface as:
public interface VariableChangeListener {
public void onVariableChanged(Object... variableThatHasChanged);
}
You could put any argument that you think it is important for the listener to handle here. By abstracting into the interface, you have flexibility of implementing the necessary action in the case of variable has changed without tight coupling it with the class where the event is occurring.
In the class where the event occurred (again in your case, the class where the variable could change), add a method to register a listener for the event. If you call your interface VariableChangeListener then you will have a method such as
// while I only provide an example with one listener in this method, in many cases
// you could have a List of Listeners which get triggered in order as the event
// occurres
public void setVariableChangeListener(VariableChangeListener variableChangeListener) {
this.variableChangeListener = variableChangeListener;
}
By default there is no one listening to the event
In the case of event occurred (variable has changed), you will then trigger the listener, the code would look like something like
if( variableValue != previousValue && this.variableChangeListener != null) {
// call the listener here, note that we don't want to a strong coupling
// between the listener and where the event is occurring. With this pattern
// the code has the flexibility of assigning the listener
this.variableChangeListener.onVariableChanged(variableValue);
}
Again this is a very common practice in programming to basically reacts to an event or variable change. In Javascript you see this is as part of onclick(), in Android you could check the event driven model for various listener such as OnClickListener set on a Button onclick event. In your case you will just trigger the listener based on different event which is whenever the variable has changed
You can make like this.As you have not defined what you want exactly.It may work. Suppose your variable name is v.Take one variable previous_v. Make previous_v=v; . You can put in your code according to your requirement:
if(v!=previous_v){
//your stuffs
}
Related
When handling various events, my general policy has been to create a xxxHandler class like MouseHandler, WindowHandler, etc which extends its appropriate xxxAdapter class provided by Java.
I was just going over some other text about handling events and it says that whenever you extend any EventListener interface, say ActionListener, you must call the enableEvents(AWTEvent e) method in the constructor and call the super.processXXXEvent() whenever an event is generated.
I find this approach highly confusing. These methods have the access specifier as protected so I assume that these are for internal use only ?
What exactly are those methods for ?
Are they really needed for handling events ?
Do they offer any benefits over the usual actionPerformed(), mouseMoved(), etc where you add your code to handle the events in the method definition without calling any super methods?
Help needed. Simple words are highly appreciated rather than technical mumbo-jumbo.
What exactly are those methods for?
The processEvent() method filters the types of events that comes to it. The parameter to this method is of type AWTEvent type.
After filtering, this method calls the corresponding processXYZEvent() method which takes the corresponding event object.
For example, processMouseEvent(MouseEvent)
The processXYZEvent() method notifies the corresponding listeners about the event by passing the event object to the handler.
For example, processMouseEvent(MouseEvent) notifies the registered mouse listener(s).
The enableEvents() method decides what event(s) to give to the processEvent() method. This method cannot be overrided since it is final. However this can be accessed in the sub class of the Component class to decide what type of events that the component support.
Are they really needed for handling events ?
Their role is mentioned above. This means that they are needed for handling events because you can only handle an event when an event object is created and dispatched and those methods do this.
I have a dialog, which have four buttons say New, Save, Delete, Cancel. Now each of these need to perform their action. So I have defined a separate class which implements an ActionListener. I have used this class to perform each of the button action.
public class MyClass implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().toString() == "OK") {
// Code
} else if( .. ){
}
}
}
What I have done is, I defined an inner class which I used to do the same functionality. But what I was not getting is, is it best practice to write a separate class or is it best to use inner class. I was suggested to write in a public class so tomorrow some one can use this class to perform their action. So I have the following questions,
If the functionality is not called by any object (which I can't say) then I can write it in inner class? OR
Is it a good practice always to write inner class which performs the actions of that dialog?
There is no general answer to these questions. If the code in actionPerformed() is one line, writing a whole class file is usually overkill.
If the code is more complex, it might be suitable to reuse but as the code grows, it also gets more specific (so you can't reuse it anymore).
Try to follow this approach:
Build your application from simple blocks that are independent of each other.
Configure the application by writing code that connects the blocks.
So in your case, you could have helper methods which do the work. Wrap them in Swing Actions; this allows you to use them in all kinds of buttons and menus.
Try to move as much work as possible into the helpers so that the actions become really simple. If in doubt, ask yourself: Is this code part of the work? Does everyone need to do this?
If yes, then the code should go into a work/helper class.
If it's things like UI related checks (visible/enabled), conversion (string to number), validation, etc., it should go into the action.
When you talk about defining an inner class for a GUI listener, I think immediately of using anonymous classes to do the job:
newButton.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// do the work for a button press
}
});
// similarly for save, cancel, delete buttons:
saveButton.addActionListener(
new ActionListener()
{
// ...
You'll often see this, and I often use this in my own code.
Which you use depends on the structure of your code, for instance:
how much work each listener needs to do
how much code is shared between the handlers
If each handler is short (e.g. just one method call, with all the real work handled within another class method), I'll use anonymous classes this way. But it does look goofy: unfortunately java requires us to define an object to employ a callback method.
It's also a matter of personal preference and coding style.
However, I'd rarely make a new top-level class for a GUI handler as in your example: even if I separate out the class so that I use the same class for each button, I'd define the class within the class file controlling the buttons, either as a non-public top-level class, or as an inner (non-anonymous) class. If the complexity of a GUI callback grows to the point that it deserves a separate class, I'd start looking for places to refactor.
proper way should be Swing Action(mentioned in comment by #Robin), for JButtons Components as most scalable choice, with implementations of interesting methods
most complex GUI is there way to add EventHandler, which fired event and could be compare in String value
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
I having a little trouble making use out of annotations in order to invoke the method that the annotation pertains to... I will give an example:
class MyEventHandlers {
#handler(id=“1”)
public doSomething() {
...
}
#handler(id=“2”)
public doSomethingElse() {
...
}
}
....
subscribe(“event1”, new MyEventHandlers, “1”);
//or maybe a better way to do this?!
....
//later, when I detect ‘event1’ I can process the required handler:
process(new MyEventHandlers, “1”)
The idea is, I want to have a way for defining handlers to events, and then linking a events to handlers. (consider for now an event is some string literal).
In all, I am not sure, what is the best style to use for doing what I want. The above is what I think at the moment. If there is better style to achieve this, please suggest.
I suspect that what you want to do, could be more easily implemented with an AOP framework.
But since you might want to do it yourself anyway:
The key to performance is to only use reflection during setup. So when subscribeing, you create a handler descriptor and add it to the listeners for the event. A handler descriptor is basically a java.lang.reflect.Method with an instance to call it on, and some knowledge on how to get event data in i.e. what arguments the method takes.
This way you can implement event triggering by
for (HandlerDescriptor desc : subscriptionMap.get(event)) {
desc.trigger(event);
}
, which should be plenty fast. You can have different HandlerDescriptors for handlers that take event info, ...
You can also make subscribe itself faster, by caching the java.lang.reflect.Methods at a class level (by a handler id key). Such that reflection is only used, when subscribeing a method of a class, not seen before.
What I'm not discussing here (hint: it's API style)
How to name the annotations
How to get context / event data in, you could take a look at JAX-RS for this.
Basically you'll also parse that info at setup time, e.g. by looking at the argument types, so that you don't need to dispatch for this at .trigger() time.
Whether to have subscribe / unsubscribe or return an Unsubscriber from subscribe.
That's the age old event system api style question.
I just started to learn how to use action listeners. To my understanding it works in the following way:
There are some classes which contains "addActionListener" method by default (for example classes for buttons).
Using this method we add an action listener to an object. For example: listenedObject.addActionListener(listeningObject).
When an action with the "listenedObject" is performed, the "actionPerformed" method of the "listeningObject" will be called. So, it means that when we program a class for the listeningObject, we need to put there "actionPerformed" method.
What is not clear to me, should we create a new class for every object that we want to listen. It does not seem to me as an elegant solution. On the other hand, if we have one action listener class for all (or at least many) object, than we have a problem since a instance of this class will not know which object is calling the "actionPerformed" method (and we need to know that since actions performed by the actionPerformed differs depending on who is called for this method).
In my opinion, for every listened object we need to create are "personal" action listener and we can do it by setting a specific value to the corresponding field of the action listener. But I am not sure that it is a standard way to go? How do usually people do it?
The most common way to handle this - judging from my own personal experience - is to simply create an anonymous inline class. Like this:
listenedObject.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
// Your action handling code in here
}
});
And often I've seen people place a call out to a method of the object containing the listenedObject. For example, in a Dialog that has a button:
myOkayButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
okayButtonPressed();
}
});
Then later in the dialog class:
private void okayButtonPressed() {
// Do what we need to do
}
Personnaly, when possible, i prefer to use an Action class (as an example a subclass of AbstractAction) instead of simply relying on an action listener. This way, I can provide the originating widget a name, an icon, a tooltip, and so on ...
The way I have always found useful (for navigation purposes) is to create an anonymous inner class which then delegates to the outer class:
listenedObject.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
listenedObject_actionPerformed(evt);
}
});
private void listenedObject_actionPerformed(ActionEvent evt) {
//Your handling goes here
}
It is then much easier to get to your handling code in an IDE using a structural lookup (CTRL+F12 in IDEA, CTRL+O in Eclipse).
The problem of using a single class (like a GUI MyCoolPanel) as the common listener to a bunch of its components (buttons etc) is that the actionPerformed method then has a lot of ugly if-else comparisons to figure out which button has actually been pressed - not very OO at all!
You certainly should not get overly worried about the performance aspects of this kind of thing - they are likely to be negligible in the extreme! Premature optimization is famously a bad thing
The way I have always found useful is to create a separate class which implements the ActionListener interface and all the other methods necessary to carry the action. This way, an action is not tied to a specific object and can be triggered from a button, a menu, etc. A little bit like the Command pattern I guess. It keeps the code simple.
Anonymous classes aren't reusable.
Redirection to the object containing the listenedObject leads to gigantic classes that are hard to maintain.
Beware that methods removeActionListener exists for a reason. You can skip listeners clean up if objects you listen to will die with object that handles events. But if your component listens the model supplied from external source, you should add your listeners in addNotify and remove them in removeNotify methods. Otherwise you may have a memore leak.
Maybe it's not actually at the moment, but I believe that in the nearest future (after Java 7 release) something like this would be the common way:
listenedObject.addActionListener ( #{doSmth();} );