I'd like to ask you couple of question about Gui.
I saw the following example:
public class ShellWithButton {
public static void main(String[] args) {
Display display = Display.getDefault();
Shell shell = newShell (display);
Button ok = newButton (shell, SWT.PUSH);
ok.setText ("Push Me!");
ok.addSelectionListener(new ButtonHandler());
ok.setLocation(0,0);
ok.setSize(100,30);
shell.pack ();
shell.open ();
while(!shell.isDisposed ()) {
if(!display.readAndDispatch())
display.sleep ();
}
display.dispose ();
}
}
public class ButtonHandler
implements SelectionListener {
public void widgetSelected(SelectionEvent e) {
if(e.getSource() instanceofButton) {
Button b = (Button) e.getSource();
b.setText("Thanks!");
}
}
public voidwidgetDefaultSelected(SelectionEvent e){
// TODO Auto-generated method stub
}
}
(i)- Someone pushes the button- How does the program know to activate widgetSelected?
I can see that the button added the ButtonHandler listener to itself, but why that the pushing the button and not just clicking the box will send the event to ButtonHandler?
I can't see where only the pushing was sent to this listener.
(ii)-why do I send an instance of the ButtonHandler to the listeners? what does that mean?
(iii)- what's happeing when I push the button? what is this event? event is an instance of the button itself?
(iv)- Button b = (Button) e.getSource(); why do I need this casting of the source? the event, as was written, can come only from ok, which is instance of button.
(v)- why that the original button will change its title? we change B.
Thank you very much!
When someone pushes the button, the button calls widgetSelected()
because that's how the library was designed; it needs to call some
method so you can do something and they settled on that method. The
reason it calls YOUR widgetSelected() is because you gave it your
class for it to call. The button knows your class has a
widgetSelected() method because you implemented
SelectionListener, and that requires you to implement the
widgetSelected() method. That is the very reason for interfaces,
and I suggest you read up on them. Only clicking the button will
get the button to call your method because the button only knows
when it is clicked. When there is a click on the screen, only the
widgets that need to know about it are told.
As I mentioned above, you send your handler to the button so it
knows what to do when it's pushed.
When the button is pushed, it has to tell your handler what
happened, and so all the relevant information is given to you as a
SelectionEvent. The event itself isn't the button, but the event
tells you which button is pushed, in case you want the same handler
to handle more than one button.
You need the cast because your widgetSelected() method can be
called when something happens to all sorts of GUI objects, not just
buttons. Therefore, the source is given as some superclass common
to all the widgets that can call your method, and you need to cast
it back to a button when you're sure it's your button. Yes, in this
program it can only be called by the button, but that's not always
the case.
The button's text changes because B and the button you created and displayed are the same object. Objects (and arrays) in Java are "pointers," they tell you where the object is. When you assign one object to another variable, you're not copying the object, you're just using another variable to point to the same object.
(i) GUI usually uses the observer pattern, in which one or more objects subscribe to an event, and whenever this event happens it is send to all the subscribed objects, just like in your button case.
(ii) You send the instance to the listeners in order to associate them, so they may receive the event when appropriate.
(iii) What happens is that the event is causing the observers to receive a notification that your button was pushed, which eventually leads to some code being executed. The event itself is not an instance of the button, but rather a separate instance to handle the events.
(iv) You need to cast it, because the method signature is just generic, since it is used for several types of events.
(v) It changed its title, because using the observer pattern, the observer in this case your button was notified when the event which was pressing the button happened.
(i) The idea behind "Listeners" is that you want to provide a list of components, object, software modules, etc. that will be notified of the event. The reason the button click doesn't just trigger something is because something's got to be listening for that event in order to react to it. Any object implementing the appropriate Listener interface (depending on the type of event) can be added, and therefore process the event.
(ii) It's a callback. You have to tell the Listener, "Here's an instance of an object that can handle your events. Please add it to the list of objects to be notified." It's kind of like subscribing to an RSS feed, in a sense - everyone on the list gets the update when it happens.
(iii) The event is a separate object. The windowing system (which, at some deep level, connects to the windowing library of the underlying OS) creates the event object, and then goes down the list of registered Listeners, notifying each of them. There are some exceptions to this (for example, it's possible for a Listener to absorb an event, preventing anyone else on the list from hearing it, but that's a separate question of its own)
(iv) Because getSource() returns an instance of a component. If you want to be able to access the Button-specific methods (which is done in the following line, with setText, you have to be dealing with an instance of Button for that method call to know what to do (i.e. which class on which to operate).
(v) The button isn't changing it's title - the ButtonHandler is doing it. So, when the widget gets selected, the "widgetSelected" method gets called inside the ButtonHandler. It then checks the source of the event (which provides a reference to the original button) and then updates the button's text to reflect that it's been clicked.
Related
I want to make a touch on a button in a layout and also that touch is done by program using injectinputevent method, so that button is clicked even without touching it.
You can use the performClick method on that button.
Call this view's OnClickListener, if it is defined. Performs all normal actions associated with clicking: reporting accessibility event, playing a sound, etc.
You can call if from another method:
your_button.performClick();
Is there any way to delete an action listener off all components that have it attached?
Something like: Action.removeFromAll();
I have attached this Action to several different buttons and when any button is pushed it should no longer be possible to activate this action. So in the action performed of this action I want to delete it from all the buttons. Is this possible or will I just have to loop through all the buttons?
An easier work around would be to create an instance variable boolean shouldPerformAction = true on the action listener. And when you get the button pushed action, you set it to false. And in the actionPerformed() method, you check if the shouldPerformAction is false and return without doing any action.
I'm very new to Java and OOP. Here is what I've got:
public class AmountChanged implements View.OnFocusChangeListener {
#Override
public void notFocused(View edittext1, boolean focused) {
//Do this awesome stuff
}
How do I instantiate and use this on one of my editText boxes in the mainActivity? I have already declared the editText boxes in the onCreate method.
In your class where you are writing the code for the editext,in that activity's onCreate() method, you need to write
yourEditext.setOnFocusChangeListener(new AmountChanged());
Also give an eye to this please as you can use anonymous classes too.
Let's imagine you created an EditBox:
EditText editText = new EditText(this);
To set focus change listener, you should provide OnFocusChangeListener instance to the setOnFocusChangeListener. Since AmountChanged implements OnFocusChangeListener, you can do the following:
editText.setOnFocusChangeListener(new AmountChanged());
If you are going to use the same listener on many EditText items, you can save this listener as a variable somewhere:
View.OnFocusChangeListener myListener = new AmountChanged();
...
editText.setOnFocusChangeListener(myListener);
In the onCreate method where you have the editText box(es) you want to use this with,
View.OnFocusChangeListener ac = new AmountChanged();
editText.setOnFocusChangeListener(ac);
From the View Android Developer Guide,
Set up listeners: Views allow clients to set listeners that will be notified when something interesting happens to the view. For example, all views will let you set a listener to be notified when the view gains or loses focus. You can register such a listener using setOnFocusChangeListener(View.OnFocusChangeListener). Other view subclasses offer more specialized listeners. For example, a Button exposes a listener to notify clients when the button is clicked.
Listener in android means that it is gonna listen to some event(OnTouchListener, OnClickListener, OnFocusChangedListener etc.). As you see OnFocusChangedListener interface is announced inside View class, in scope of Android it usually means that any child of View can produce this event, so you need to "listen" to those events.
In scope of EdiText what you have to do is something like this:
editText.setOnFocusChangedListener(new AmmountChanged());
EdiText is a child of View. So we are start "listening" to all OnFocusChanged events that will happen inside editText by registering our instance implementation OnFocusChangeListener.
I'm playing with Android and I'd like to know if there's any way to invoke a listener call programmatically, for example, having an onClick() listener and invoke a call to this listener without touching the screen when the activity is created.
There is no way to get the set OnClickListener. So you need to store it and call your OnClickListener directly.
OnClickListener store = new OnClickListener() {/*...*/};
view.setOnClickListener(store);
store.onClick(view);
Never tried that, but after assigning a clickListener to your object (for example a Button), call on your onCreate method myButton.performClick().
Android doc :
public boolean performClick ()
Added in API level 1
Call this view's OnClickListener, if it is defined. Performs
all normal actions associated with clicking: reporting accessibility event,
playing a sound, etc.
Returns
True there was an assigned OnClickListener that was called,
false otherwise is returned.
Although this is possible, I'd actually advise against it. Listeners should be called from the UI but the business logic behind it is what should actually be called directly. This would provide "separation of concern" between both layers.
You should be calling the code that the listener calls in it's onClick method rather than invoking the onClick directly.
I am unable to understand the meaning of Has****Handlers interfaces in GWT. What would be the difference if a class implements HasClickHandlers (addClickHandler) and ClickHandler (onClick) interfaces.
thank you
HasClickHandlers - something that can be clicked, e.g. a button
ClickHandler - some code that handles on a click
A HasClickHandlers object is a widget, like a button, that can react when the user clicks on it. But a button by itself does not know what should happen when a user clicks on it. A developer can craft a ClickHandler object, which is some code that implements what should happen when the user clicks on that button. A button can be given a ClickHandler to react to the user's click, i.e. the button can have/hold a click handler - HasClickHandlers.
One may ask why does GWT say applications should define view interfaces with method signatures like:
HasClickHandlers getSaveButton();
instead of simply
Button getSaveButton();
Google advocates decoupling the view from presenter. The presenter usually cares very little for all the functionality of a button - it usually only cares that the button is something that can take a click handler and use it. An interface like HasClickHandler has very few methods and is very easy to mock. Using a real button however will sometimes require initializing some or part of the whole UI framework and instantiating prerequisite context classes in order to create a button for testing.
By having the interface return HasClickHandler instead Button, the unit test code for the presenter can decouple completely from the complexity of the UI framework by simply mocking interfaces like HasClickHandler. This means simpler test scaffolding and very fast unit tests (since you don't have the overhead of initializing/interacting with a UI framework).
http://googletesting.blogspot.com/2009/08/tott-testing-gwt-without-gwttest.html
Edit
OP asks:
ok, e.g. if ABC class implements Hasclickhandlers and Clickhandler and then onClick and addClickHandler (which returns HandlerRegistration), it means that 1)it will act on click event thru onClick method and 2)will let any other class(es) know (who is implementing ClickHandler and used addClickHandler of ABC class to register the event) that click has just been occurred? right?
Your classes like ABC will not implement HasClickHandlers. Only GWT widgets like buttons implement HasClickHandlers. Google is simply providing the HasClickHandlers interface as an alternative way to declare variable references to some widgets like buttons. These widgets will notify registered ClickHandler about a button click.
Your class ABC may implement ClickHandler or may contain an inner (possible anonymous) class that derives from ClickHandler. A typical usage looks like:
public class ABC {
...
getSaveButton().addClickHandler(
new ClickHandler() {
public void onClick(ClickEvent event) {
saveToDatabase();
}
}
}
...
The HasClickHandlers is for objects that generate click events. The ClickHandler is for objects that deal with the events.
For example, a Button will generate a click event. When you want to handle a click event, you create a ClickHandler that contains the code that does so. You register this ClickHandler with the Button object so that when a click happens, the Button knows who to tell about it. The HasClickHandlers interface is implemented by Button (via the FocusWidget parent class) which is just the interface for registering ClickHandlers. This interface simply standardizes the registering of ClickHandlers.