You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@pivot.apache.org by Chris Bartlett <cb...@googlemail.com> on 2010/06/08 19:20:20 UTC

Pivot event handling

I have a question about the preferred way to modify event related behaviour
defined in a component's skin.

A simple example might be to modify the behaviour of a ListView responding
to key presses.
(To keep this example simple, I will assume that all list items are
enabled.)
If the first list item is selected (index 0) when the UP key is pressed, I
want the selection to jump to the last list item.
Similarly, if the last list item is selected when the DOWN key is pressed
the selection should change to the first list item.

org.apache.pivot.wtk.skin.terra.TerraListViewSkin handles UP & DOWN key
press events and is installed as the first ComponentKeyListener on the
component.
As I understand things, this listener code changes the selected list item
before any custom listeners are called.
Custom listeners therefore do not know if the list item has just been
changed from index 1 to index 0 (a press of the UP key handled by the
default skin listener).
This means that they do not know whether they need take further action in
order to alter the selection as described, or do nothing.


I have previously accomplished similar things by
a) grabbing a reference to the relevant listener from the listener
b) removing that listener from the listener list
c) populating a custom 'prioritised' ComponentKeyListener with my own high
priority listener which functions as desired, as well as the original
listener as a low priority
(This calls the listeners in order of highest priority until one has
consumed the event)
d) adding the custom listener back into the listener list
This results in my listener being called first, and only calls the default
listener (from the skin) if I haven't already handled the event.


What is the preferred method of achieving this sort of thing with Pivot?
Should I create a modified version of TerraListViewSkin which overrides the
'problem' code and set this against the specific ListView?
I can see this being likely if the custom listener could not do all it
needed to using publicly accessible API methods of the given component, and
instead needed to directly interact with any private instance data held by
the skin.

I imagine (or rather hope!) that the preferred method would not involve
additional listeners to track the selection states between keypresses.

Regards,

Chris

Re: Pivot event handling

Posted by Chris Bartlett <cb...@googlemail.com>.
Thanks for the quick response, Greg.

I absolutely agree that the listener list 'hack' is just that and far from
perfect, but it allows for the trivial change to be injected with very
little effort and just a few lines of code.
The reason I took that approach is that it seemed too much effort for the
other routes that I could think of, and none of them seemed any more
elegant.  (Not that I was avoiding the effort, it just suggested to me that
those other approaches were not the best way either)

At least I now know that I wasn't missing something obvious.

Chris


On Wed, Jun 9, 2010 at 12:46 AM, Greg Brown <gk...@mac.com> wrote:

> Extending the default list view skin is certainly one solution. However, I
> actually don't see a problem with monitoring selection change events as well
> as keyboard events. There is no implied association between keyboard events
> and selection change events - it is up to the skin (or other listener) to
> create that association. So, I might say that, by definition, you need to
> listen for both types of events in order to implement the logic you
> describe.
>
> I don't think that hacking the listener list is a great approach, though.
> Seems like...well, a hack.  :-)
>
>

Re: Pivot event handling

Posted by Greg Brown <gk...@mac.com>.
Extending the default list view skin is certainly one solution. However, I actually don't see a problem with monitoring selection change events as well as keyboard events. There is no implied association between keyboard events and selection change events - it is up to the skin (or other listener) to create that association. So, I might say that, by definition, you need to listen for both types of events in order to implement the logic you describe.

I don't think that hacking the listener list is a great approach, though. Seems like...well, a hack.  :-)


On Jun 8, 2010, at 1:20 PM, Chris Bartlett wrote:

> I have a question about the preferred way to modify event related behaviour defined in a component's skin.
> 
> A simple example might be to modify the behaviour of a ListView responding to key presses.
> (To keep this example simple, I will assume that all list items are enabled.)
> If the first list item is selected (index 0) when the UP key is pressed, I want the selection to jump to the last list item.
> Similarly, if the last list item is selected when the DOWN key is pressed the selection should change to the first list item.
> 
> org.apache.pivot.wtk.skin.terra.TerraListViewSkin handles UP & DOWN key press events and is installed as the first ComponentKeyListener on the component.
> As I understand things, this listener code changes the selected list item before any custom listeners are called.
> Custom listeners therefore do not know if the list item has just been changed from index 1 to index 0 (a press of the UP key handled by the default skin listener).
> This means that they do not know whether they need take further action in order to alter the selection as described, or do nothing.
> 
> 
> I have previously accomplished similar things by 
> a) grabbing a reference to the relevant listener from the listener
> b) removing that listener from the listener list
> c) populating a custom 'prioritised' ComponentKeyListener with my own high priority listener which functions as desired, as well as the original listener as a low priority
> (This calls the listeners in order of highest priority until one has consumed the event)
> d) adding the custom listener back into the listener list
> This results in my listener being called first, and only calls the default listener (from the skin) if I haven't already handled the event.
> 
> 
> What is the preferred method of achieving this sort of thing with Pivot?
> Should I create a modified version of TerraListViewSkin which overrides the 'problem' code and set this against the specific ListView?
> I can see this being likely if the custom listener could not do all it needed to using publicly accessible API methods of the given component, and instead needed to directly interact with any private instance data held by the skin.
> 
> I imagine (or rather hope!) that the preferred method would not involve additional listeners to track the selection states between keypresses.
> 
> Regards,
> 
> Chris