cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marc Portier <...@outerthought.org>
Subject Re: Event handling in Woody
Date Fri, 19 Sep 2003 15:22:21 GMT


Sylvain Wallez wrote:

> Marc Portier wrote:
> 

<snip />

> 
> Well, if you fail to explain to yourself, I understand why we sometimes 
> don't understand your posts ;-D
> 

doh!
care to explain this joke to us?
;-)


but I have to admit I mostly need other people around to develop own 
ideas, makes me a perfect guy for OSS in fact: the ideas are never 
really only *my* ideas, so I 'm very rarely struggling with 
idea-ownership, rather the contrary: struggling with idea-lonelyness ;-)


>> care to textualize some preview on what goes about before we see the 
>> code? 
> 
> Yep. Here it is.
> 
> At first, I wanted to add event listeners to widgets (i.e. the 
> _instances_), but that did not work, primarily because a repeater 
> dynamically creates widget instances and secondly because it requires 
> listeners to be painfully defined programmatically each time a form is 
> instanciated (in an action or flowscript).
> 
> So event listeners are defined in the form definition. I currently have 
> defined a ValueChangedEvent for data-aware widgets (field, booleanfield, 
> aggregatefield) and ActionEvent for actions. We also need a RepeaterEvent.
> 
> Two implementations of EventListenerBuilder exist : one that creates a 
> Java class (classical EventListener) and one that wraps a JavaScript 
> snippet. Just as in DHTML, that snippet has some predefined variable : 
> this (the widget) and event. If called within a flowscript, it also has 
> access to the precious "cocoon" object. I still have to see how to 
> create a "cocoon" object if used out of the flowscript context.
> 
> The definition therefore looks like this :
> <wd:field id="foo">
>  ...
>  <wd:on-change>
>    <wd:java class="com.my.Listener"/>

hm, this makes these listeners totally stateless, no?
what I mean:
- probably woody is going to instantiate them with a Class.forname() and 
newInstance() sequence, correct?
- as such they have no initial state other then some defaults 
(no-argument-constructor)
- consequence: they don't have pointers into our use-case controllers 
(be it flowscript or apples) like is the case with swing and the usage 
of anonymous inner classes.  Point being: it is going to be hard to 
callback into your business logic with these events, no?

as a way out I see the following approaches:
1/ keep like above:
so the eventListener doesn't have direct access to the use-case 
controller, but at least it has access to the Woody Form model, right?

so it could change state-information in the model (userData area or 
hidden widgets) and as such it becomes available to the 
use-case-controller since it has a point to the form and can expect it.

What I dislike about this is that the active-event-trigger becomes a 
passive data element waiting to be read.


2/ have the form-model declare named event-dispatchers
which behave like a sort of event-queue-channels

<wd:event-dispatcher type="value-changed" name="foo_changed" />

<wd:field id="foo">
  ...
  <wd:on-change>
    <wd:java event-dispatcher="foo_changed"/>

and add methods on the form model so the use case controller can 
register it's own instances to receive events from these named 
event-queue-channels:

form.registerValueChangedListener(
           "foo_changed",
            new ValueChangedListener(){

                public void valueChanged(ValueChangedEvent evt){
                    Widget source = evt.getSource();
                    Object newValue = evt.getNewValue();
                    ...
                    EnclosingClass.this.whatEverStateVariable = ...;
                }
         });


we avoid the 'dynamic widget instance' problem you mentioned above
and we can easily have eventListeners that can callback into our use 
case controllers...


obviously from my text I like 2/ the most, since it could also be 
incrementally added to your current stuff?

what do you think?

>    <wd:javascript>
>       var list = this.parent.getWidget("thelist");
>       list.selectionList = 
> Packages.com.my.App.getSelectionForTheList(this.value);
>    </wd:javascript>
>  </wd:on-change>
> </wd:field>
> 
> Similarily, there's an <on-activate> on <action> widgets.
> 

would probably have chosen on-valueChange and on-action, but that's a 
matter of taste probably

> I reused the JSF patterns for event handling : events are buffered until 
> the current processing phase is finished and fired afterwards, to ensure 
> the widget tree is in a consistent state.
> 

sounds like you already have something like event-dispatchers in place?

> I still have to define also the ability for the form to be submitted 
> when a widget's value changes. Considering the car selector example, 
> this would allow to refresh the model list as soon as the maker is 
> changed withouth having to push the "select maker" button.
> 

you mean having a client-side javascript thingy to do a submit-on-change?

I saw Bruno tinkering on something like this, IIRC it was triggering an 
action (since we didn't have value-changed events)

only downside of it is that you have to add a no-value option to the 
list which is selected by default in order to trigger the change:

the list then shows the text (select one from the list) otherwise you 
can't trigger the generation of the select-maker if e.g. the option you 
want to make is the default selected one :-)

> I'm thinking of adding a new "submit-on-change" attribute on 
> <wi:styling>, but I'm wondering if this belongs to the view or to the 
> form definition. Seems better on the view.

yep, that's what Bruno did, if you like, I can check how he did it.

> 
>> also this links back to another wild idea I'm having
>> I'm still not quite satisfied with the way the repeater-binding (the 
>> not simple one) needs to operate for detecting 
>> new/deleted/syill-existing rows in the repeater...
>>
>> So I hope the way you handle valuechanged can give some inspiration on 
>> how to mark the changed state of repeater rows? 
> 
> 
> 
> Aha ! I was also thinking of an event-driven binding, but kept this wild 
> idea for now : the binding would register itself on the repeater and 
> "collect" modifications.
> 

yep, it is different to what I was thinking but it might serve as an 
alternative.

what I meant is that the control itself would be remembering what 
happened to the rows in between two calls to some method that sets a 
'resetRowModificationInfo()' which would then be called to set some 
revision-point between which the control would be remembering some 
metadata on each of the rows.

of course this borrows from the current way binding is used: once at the 
start (load) and once at the end (save) of the use case.

looking at how this often maps to talking to a (persistency) backend 
system I'm not really tempted into changing this usage pattern for now

of course if we agree that stacking up these changes are not part of the 
  concern of the widget itseld, then we will need a listener of some 
kind to do it for us... still have to think about how the Binding could 
then get a hold of those results.


>> BTW: I assume that the ValueChangedEvent is holding both the old and 
>> new value? 
> 
> Of course !
> 

yep, but what I really meant is that I was assuming that the widget was 
remembering both old and new states (which I realize now it is probably not)

>>> allow event listeners to be written both in Java (classic-style) and 
>>> in JavaScript (flowscript-style).
>>
>>
>>
>> Makes sense.
>>
>> I guess reusing the awt eventhandling interfaces is out of the question? 
> 
> 
> 
> Using AWTEvent doesn't really makes sense, but the new FormEvent class 
> extends java.util.EventObject, and the listeners extend 
> java.util.EventListener. However, I used the convenient 
> AWTEventMulticaster as the base class for a FormEventMulticaster.
> 
>> Not that I would consider it as a breaking design point to start using 
>> it, but yesterday someone showed me usage of jbeaver (see at 
>> http://www.ratundtat.com/index01.htm?menue=40, it's not oss but it 
>> didn't look entirely impossible to create something similar.) and I 
>> couldn't help dreaming about a common GUI description language that 
>> could result into both Swing and Woody based apps...
> 
> 
> 
> And SWT... Some of my current wild thoughts is to use Woody and 
> flowscript to build Eclipse plugins. Imagine every component coming with 
> its own Woody form and associated flowscript and binding : building a 
> Cocoon IDE for Eclipse can become quite easy.
> 

yep, but what I meant was this: in order to be able to swap from the one 
to the other it would be really nice to also be able to re-use the 
use-case controllers and their accompanying eventListeners...

of course if we go for this event-dispatcher idea that would still hold, no?

>> From that angle: being able to share your event-controllers might make 
>> sense (although wrapping them inside specific listener interfaces 
>> should not be that hard) 
> 
> Sorry, don't understand: what are "event-controllers" ?
> 

sorry here, I started mixing use-case controller (i.e flow-script or 
apple) and the eventListener... as shown above they often go hand in hand:

some eventListeners only affect the view itself, but some of them really 
have to callback into the state of the use-case.

<snip />


-marc=
-- 
Marc Portier                            http://outerthought.org/
Outerthought - Open Source, Java & XML Competence Support Center
Read my weblog at              http://radio.weblogs.com/0116284/
mpo@outerthought.org                              mpo@apache.org


Mime
View raw message