I have a listbox with a changeHandler attached to it.
In this changehandler, there are some very important verifications that I dont want to copy, to keep my code clean.
this.myListBox.addChangeHandler(this.myChangeHandler);
private ChangeHandler myChangeHandler = new ChangeHandler() {
#Override
public void onChange(ChangeEvent event) {
If (a<0)...
}
}
I used to have a ChangeListener with onChange(Widget sender) but it is now deprecated.
With the listener I had it was easy to execute the ChangeListener with:
this.myChangeListener.onChange(this.myListBox);
How can I execute the onChange(ChangeEvent event) of my new ChangeHandlereven when the user does not touch the listbox? (to make the verifications happen)
ChangeEvent can't be instantiated because is a native event. You can create a class that implements ChangeHandler and put the onChange logic in a public method (validate) that accepts the ListBox as argument. Then from onChange method you call the new validate method. If you want to use it "manually" you can simply call validate.
You can try to fire a native event:
DomEvent.fireNativeEvent(Document.get().createChangeEvent(), myListBox);
Related
Whenever we want to create a listener, we implement a listener interface. For example, lets implement SensorEventListener.
Now we have to override the methods of this listener interface.
public void onSensorChanged(SensorEvent event);
and
public void onAccuracyChanged(Sensor sensor, int accuracy);
What I don't understand is:
Why and how these methods work when I automatically use them?
Why does onAccuracyChanged method gets called when the accuracy changes?
After all, onAccuracyChanged is just an empty method that we override because our formula (or the interface we implement) requires us to do so. If it is something magical caused by the lower levels
When and why would someone actually use an interface in his/her
self-project regardless of android?
Here is a suitable answer. Allow me to give you an example about listeners.
Listeners:
Suppose there is a class that fetches data in the background, the Worker, and another class that is interested in that data, the InterestedClass.
public class Worker extends Thread{
interface DataFetchedListener{
void onDataFetched(String data);
}
private DataFetchedListener listener;
#Override
public void run(){
String data = fetchData();
// Data fetched inform your listener so he can take action
listener.onDataFetched(data);
}
public void setDataFetchedListener(DataFetchedListener listener){
this.listener = listener;
}
private String fetchData(){
// returns the fetched data after some operations
return "Data";
}
}
public class InterestedClass implements Worker.DatafetchedListener{
#Override
public void onDataFetched(String data){
doSomethingWith(data);
}
private doSomethingWith(String data){
// just print it in the console
System.out.println("Data fetched is -> " + data);
}
}
The Worker does not care which class will manipulate its data, as long as that class follows the contract of DataFetchedListener.
Equally this means that any class is able to do something with the data (InterestedClass just prints it in the console) but Worker does not need to know which class is that, just that it implements its interface.
The main could go like this...
public class Application{
public static void main(String[] args){
InterestedClass interested = new InterestedClass();
Worker worker = new Worker();
worker.setDataFetchedListener(intereseted);
worker.start(); // Starts Worker's thread
}
}
When the Worker will fetch the data then it will notify its listener (currently the interested object) and the listener will act accordingly (interested will print the data to the console).
In computing, an interface is a shared boundary across which two or more separate components of a computer system exchange information.(Wikipedia)
You may wish to respond to some events either system events or user events. But for that you need to know when the event you wish to capture occurs and also what must be done at that time.
And for that you open a confidential EAR to listen to events. But that will not be sufficient since you need to be notified too so that you can reply according to the event. You set callbacks that will notify when an event occur. Those empty body methods we create inside an interface.
A Listener is that interface that hears and notify back through callbacks.
So how can all that be used? And how all these do interact?
First create an interface with empty bodies methods that you intend to call when an event occurs:
public interface MyListener{
void actionOneHappens(Object o);
void actionTwo();
void actionThree();
}
Create a class that handles something, for example counts:
public class MyCounter{
//create a member of type MyListener if you intend to exchange infos
private MyListener myListener;
//let's create a setter for our listener
public void setMyListener(MyListener listener)
{
this.myListener=listener;
}
MyCounter(){
}
//this method will help us count
public void startCounting()
{
new CountDownTimer(10000,1000)
{
#Override
public void onTick(long millisUntilFinished) {
//I want to notify at third second after counter launched
if(millisUntilFinished/1000==3)
{
// I notify if true :
//as someone can forget to set the listener let's test if it's not //null
if(myListener!=null){
myListener.actionThree();
}
}
}
#Override
public void onFinish() {
}
}.start();
}
}
You can then create an object of type MyCounter and know when it's at three:
MyCounter myCounter=new MyCounter();
myCounter.setMyListener(new MyListener()
{
//then override methods here
#override
void actionOneHappens(Object o){
}
#override
void actionTwo()
{}
#override
void actionThree()
{
//Add you code here
Toast.makeText(getApplicationContext(),"I'm at 3",Toast.LENGTH_LONG).show()
}
});
//start your counter
myCounter.startCounting();
And it's done!! That's how we proceed.
Interfaces have no implementation and for using them we have two options:
A class that implement them
An anonymous class
And consider this code:
interface TestInterface {
void doSomething();
}
class TestClass{
private TestInterface ti;
public TestClass(TestInterface ti){
this.ti = ti;
}
public void testActionMethod(){
ti.doSomething();
//some other codes
}
}
class OurOwnLauncherApp{
public static void main(String[] args) {
TestClass tc = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Hi!");
}
});
tc.testActionMethod();
TestClass tc2 = new TestClass(new TestInterface() {
#Override
public void doSomething() {
System.out.println("Bye!");
}
});
tc2.testActionMethod();
}
}
In here we have:
An Interface (Just like what you asked)
A function class the uses that interface
An application somewhere that we don't know (Maybe your phone app, maybe your friends phone app, etc)
What this code does, it gives an anonymous class (which implements TestInterface) to the testActionMethod and with calling doSomething method inside testActionMethod, we invert the calling back to our own method. that's why you will see this result:
Hi!
Bye!
This is exactly a simplified version of listener interfaces and how they work
There is no magic thing. Generally, the event-listener mechanism is as follow:
For some entities, there is the possibility to listen to some events on that entity (let name this entity as event generator). So some way should exist for other entities to listen to these changes (let name these entities as listeners). Now a listener registers itself as a listener of event generator. When an event occurs on the event generator, it calls the related method of registered listeners.
As a simple example assume a button. The button may generate an event for some actions such as click. Now if a listener wants to aware when the button is clicked, it should register itself as a listener of that button. On the other hand, the button should provide a unified way of registering the listeners. This unified way is the interface. Each entity which implements the interface could register itself as a listener for click on that button:
1- Listener implements the interface
2- Listener registers itself as a listener of button (Event Generator)
3- Event Generator calls the appropriate method of all registered listeners (this method is a method of the interface).
For your case, android provides a manager which you could register a listener on some sensors by it: android.hardware.SensorManager.registerListener(). All things occurs here (which is not magic!). When you register an entity (which implemented the related interface, SensorEventListener) as a sensor listener, changes in that sensor will cause to call methods of the listener).
I have written a Swing GUI with several controls associated with the same Action subclass. The implementation of the Action subclass follows this psudocode:
public class MyGUI
{
Gizmo gizmo_; // Defined elsewhere
public class Action_StartPlayback extends AbstractAction
{
/* ctor */
public Action_StartPlayback(String text, ImageIcon icon, String desc, Integer mnem)
{
super(text, icon);
putValue(SHORT_DESCRIPTION, desc);
putValue(MNEMONIC_KEY, mnem);
}
#Override public boolean isEnabled()
{
return gizmo_ == null;
}
#Override public void actionPerformed(ActionEvent e)
{
gizmo_ = new Gizmo();
}
Action_StartPlayback act_;
};
The action is associated with both a button and a menu item, in a way similar to this psudocode:
act_ = new Action_StartPlayback(/*...*/);
// ...
JButton btn = new JButton(act_);
JMenu mnu = new JMenu(act_);
When I click the button or the menu item, the action's actionPerformed is fired correctly, gizmo_ is initialized and is non-null and everything works as expected -- except that the button and menu item are still enabled.
I expected that isEnabled would have been called again "automagically" but this is obviously not happening. isEnabled() is never called again.
This evokes two questions:
Is it OK for me to #Override the isEnabled() method as I have done here?
Assuming the answer to #1 is yes, how do I trigger a refresh of the GUI so that isEnabled() is called again, resulting in the button & menu item being disabled?
Instead of overriding setEnabled you could simply call setEnabled(false) after you intitialize your gizmo in your actionPerformed method:
#Override public void actionPerformed(ActionEvent e)
{
gizmo_ = new Gizmo();
setEnabled(false);
}
Here's the setEnabled implementation from AbstractAction:
public void setEnabled(boolean newValue) {
boolean oldValue = this.enabled;
if (oldValue != newValue) {
this.enabled = newValue;
firePropertyChange("enabled",
Boolean.valueOf(oldValue), Boolean.valueOf(newValue));
}
}
The automagical you're looking for is the call to firePropertyChange, which notifies components based on this action that the state has changed, so the component can update its own state accordingly.
I am no pro at this, but I don't see a see an automatic way of doing this, of notifying listeners that the state of enabled has changed. Of course you can call setEnabled(false) at the start of the actionPerformed, and then code Gizmo (or a wrapper on Gizmo) to have property change support and then add a PropertyChangeListener to Gizmo, and in that listener, when the state changes to DONE, call setEnabled(true). A bit kludgy but it would work.
This is not strictly limited to Swing, but a more general Java principle. A lot of classes in the JDK (and in other libraries) have a getter and a setter for a property. Those methods are not meant to be overridden to return a dynamic value as most of the times the superclass accesses the corresponding field directly and does not go through the getters.
If you have dynamic behavior, you should call the corresponding setter each time the value changes. This will notify the super class changes have been made, and typically this will also fire a property change event to notify other interested parties.
You can find a bit more on this convention if you do a search on Java beans.
In your case, a possible solution is to let your UI class fire a PropertyChangeEvent when that gizmo instance changes, and let your actions listen for that event. When they receive such an event, they update their own enabled state.
The enabled-state is stored in both of your objects, in the AbstractAction and in the JButton.
This is important because you only need one instance of Action_StartPlayback for multiple Components like:
In the menu's button.
In a toolbar.
In a Shortcut Strgp in example.
All of them can have the same instance of Action_startPlayback. The Action_startPlayback is the only source of truth. The components are responsible to respect this source of truth so every Component will ask the AbstractAction to notify them if something has been changed. The AbstractAction will remember all the components and will notify them using the Method firePropertyChange().
But how to repaint all pending components? You must force all pending Components to ask the Action_startPlayback for the actuall enabled-state! Look at this:
#Override public void actionPerformed(ActionEvent e)
{
gizmo_ = new Gizmo();
// now, force the components to get notified.
setEnabled(true);
}
I have a actionSave class which extends AbstractAction.I use it for save button. somewhere else i want to run the same instant of it which was used for the button.
I came to conclusion to use it as below but i do not know what to pass as argument?
model.getActionSave().actionPerformed("what should i add here for action event");
Extract the code of the actionPerformed() method into another method without argument, and call this method instead:
public void actionPerformed(ActionEvent e) {
save();
}
public void save() {
...
}
...
model.getActionSave().save();
Just create your own ActionEvent, it has a public constructor. E.g.
model.getActionSave().actionPerformed(
new ActionEvent( this, ActionEvent.ACTION_PERFORMED, "Save" )
);
If you are e.g. testing your UI, you can also opt to perform a click on the button through the API:
button.doClick();
But in general I prefer the first approach, and avoid the coupling with the UI
The application i work with override the default JComboBox from swing. Leets Call it MyComboBox. This version of ComboBox implement the FocusListener and contains the two methods focusGained and focusLost.
Now, in one of the panel of the application, the form contains a ComboBox of this type:
MyComboBox aMyComboBox = new MyComboBox();
I want to add a listener on this like that :
aMyComboBox.addFocusListener(new FocusListener() {
public void focusLost(FocusEvent e) {
//Do something here
}
public void focusGained(FocusEvent e) {
//Do something else
}
});
But when i run the code, it never pass into these method but only execute the focusGained/lost from the MyComboBox class.
Is there a way to add a listener on an object that already implements FocusListener?
Additional FocusListener should work unless the instance used in MyComboBox consumes the event (AWT event consumption).
Try making an example with an ordinary JComboBox -- this will help narrowing down the cause of the problem.
When developing Swing applications, I've typically defined a delegate interface for each UI component for action callbacks. For example, if there is a class, MyDialog, which contains a button, MyButton, then the ActionListener for MyButton will call MyDialog.Delegate.OnMyButtonClick(Event e). The UI component then becomes "dumb" and requires a controller to handle events as well as update the component itself.
I thought that by using the Swing Application Framework's #Actions, I could get around creating delegate interfaces and implementations by defining #Action methods in implementation classes, letting the ApplicationContext figure out what to call. Apparently, that is not the case, as I don't see any clear way of adding those classes into the ApplicationContext, nor do I see any examples out there of doing such a thing.
Has anyone managed to use SAF in this manner so that there is a clean separation between UI and UI action code?
I've discovered a good way to keep the UI separate from the behavior using #Actions.
First, create a UI Component, say a JPanel with a button and then give it a public method that can be used to set the action of the Button:
class CustomJPanel extends JPanel {
private JButton myButton;
public CustomJPanel() {
initializeComponents();
}
public void initializeComponents() {
myButton = new JButton();
}
public void setButtonAction(javax.swing.Action action)
{
myButton.setAction(action);
}
}
Next, create an Action class that will provide the logic for that button:
class CustomJPanelActions {
#Action
public void doSomething()
{
JOptionPane.showMessageDialog(null,"You pressed me!");
}
}
Finally, setup the application controller and during setup, assign the appropriate action to the appropriate UI:
class MyApp extends SingleFrameApplication {
private JFrame mainFrame;
private JLabel label;
#Override
protected void startup() {
getMainFrame().setTitle("BasicSingleFrameApp");
CustomJPanel panel = new CustomJPanel();
panel.setButtonAction(getContext().getActionMap(new CustomJPanelActions()).get("doSomething");
show(panel);
}
public static void main(String[] args) {
Application.launch(BasicFrameworkApp.class, args);
}
}
In this way, the UI is logically separated from the control (i.e. Action) and can be tested on its own. The controller can make any decisions it needs to in order to determine what Action set to use and which specific action to assign to the UI controls. That is, one can create a Test Action Set and a Live Action Set, etc.
This method of using SAF has worked rather well for me.
The SAF javadoc has some information on how to do this sort of thing in the doc for ActionManager#getActionMap