rocketmail / jfxflow

Automatically exported from code.google.com/p/jfxflow
0 stars 0 forks source link

A few thoughts on transitions #4

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Hi Zonski,

I had a look at how the transitions between pages work and I think there
are few issues that you might like to look into :-)

As far as I have seen the entry and exit transitions are always executed
sequentially. This makes it impossible to implement something like a blend 
transition between two pages. I think it should be configurable in the  browser 
whether sequential or parallel transitions are used.

The default entry and exit transitions used by the browser, if the page
does not provide them explicitly, should also be configurable.

LG, MiPa

Original issue reported on code.google.com by m...@jugs.org on 30 Nov 2011 at 5:18

GoogleCodeExporter commented 8 years ago
Hi MiPa, 

Transitions are the trickiest part of the whole framework, mostly because they 
are new territory (neither swing apps nor web pages have had to do anything 
real similar) but also because by their nature they are not decoupled - the 
entry and exit page are linked and often want to know about each other.

I really wanted to get parallel transitions in there but the problem is that an 
Activity can be reused for multiple pages (in much the same way a servlet is). 
So if I have a PersonActivity, I can go to PersonPlace(id=0) and 
PersonPlace(id=1) and the browser will just map both of these to the same 
PersonActivity instance and pass it in the id as a parameter. If we had a 
ParallelTransition, the browser would be trying to show both pages at the same 
time (i.e. the exiting and entering one), which obviously won't work.

There are a few options for this that I can come up with, and I'd love to get 
input on this:

1. Make the Browser configurable, as you say, so that the developer can choose 
to switch on transitions. It would be up to the developer to ensure that if 
they turn on parallel transitions then the same activity is never navigated 
between directly. The system would probably check for this and fail with ever 
if it was attempted. This is the easiest, but also limited (i.e. I wouldn't be 
able to use it most of my apps).

2. When registering an activity with a browser, instead of registering the 
activity directly, we register a 'factory'. The browser can then create as many 
instances of the view as needed to achieve its results (a dumb algorithm would 
create one per Place, a smarter one would cache and reuse just 2 per activity 
and only when transitioning between the same page). I quite like this approach, 
however I'm a little worried about creating some performance or shared-resource 
problems. What if the activity has a massive, complex scene on it, and also 
what if the exiting page has a lock on some resource (like a file) that the 
entering resource needs - maybe this won't happen, but I think the potential 
risks need to be thought through. 

3. Somehow take a snapshot of each view (or perhaps just the exiting view) and 
cache it as an image, then just use this image for the transitions, and swap 
the real activity in at the last minute (I think this is what iPhone/Android 
browsers do). This might be ok for things like fade, fly, swipe, but for stuff 
like scale, and also custom transitions where a node is animated at a time I 
think it just won't work.

I had intended to make the default transitions attributes on Browser that you 
can set. I just forgot, so thanks for reminding me! I will add it in.

I have deliberately sectioned the transitions out to a separate 'transition' 
method on Browser with protected scope. The intent here is that it is easy for 
anyone to override this method and do whatever they like for transitions. 
Ideally the default implementation would provide for the most common cases 
though. So feel free to override this method and have a play with some 
alternate transition strategies, if you come up with something cool, let me 
know!

Keep the input coming!

Original comment by zonski on 30 Nov 2011 at 10:25

GoogleCodeExporter commented 8 years ago
Hi,
here are a few more comments from my side. I'd definitely go with option 2. 
Everything else either looks too simplistic or too hackerish to me. Your 
framework should be flexible enough to suite many different purposes and thus 
should not be too narrow and limiting. At the moment you have not forseen it 
but I think it is, e.g. just a matter of time until someone will ask you to 
display two activities at the same time. (Ups, I guess I've just done it :-).) 
This may be needed for a lot of purposes, e.g. for visually comparing the 
content of two activity instances, for printing the content of two activities 
on a single page (once JavaFX will support printing at all.) and so on ...

As to your concerns. You will never be able to prevent people from making 
mistakes but it would be a big mistake to restrict the usefulness of the 
framework right from the beginning by beeing too restictive. If it is clearly 
documented that several instances of an activity may exist at the same time 
then every programmer should be able to cope with that. I think a key feature 
would be to properly define the lifecycle of an activity instance so that it 
can react accordingly. It should also be possible to veto switching to another 
activity if there is a need for it.

LG, MiPa

Original comment by m...@jugs.org on 2 Dec 2011 at 12:41

GoogleCodeExporter commented 8 years ago
You've backed up my own feelings on this one Michael, so I'm looking into how 
best to implement the factory approach. It obviously adds some complexities. 

Two particular things of concern: 

1. Factories and auto-wiring. 

Currently we can return activities from our SpringContext and they get nicely 
autowired, if we return a factory and that factory then returns the acitivity, 
we need a clean way for the activity to get autowired. 

Technically this is not Flow's problem, but I want it to play nice with Spring 
in particular, so I'm trying to find a way to do this in Spring. I'm not too 
sure about Guice as I don't use that to the same depth. If you have any 
experience/suggestions in either area, please let me know. 

As an aside, I've had it in the back of my mind to create a FxmlCellFactory at 
some point too, which would then allow List/Tree/Table cells to get loaded from 
FXML and autowired, much as the controllers do. If we get the factory working 
in general then this should be easily adapted to support this as well. 

2. Releasing Activities

I guess I will keep weak references to the loaded activities in the Browser so 
they can be reclaimed by the GC as needed. I'm wondering if that will be enough 
(I've never used weak references in anger), or whether I will need to 
explicitly release the activities. 

I already call setActive(false) on them, which triggers the deactivate() method 
to be called. I guess if an activity has created any listeners, etc, in the 
activate it will have to remove these in the deactivate in order for the weak 
referencing to be of any value. This one probably just needs some playing 
around with and then some good docco.

Thanks for your feedback.     

Original comment by zonski on 4 Dec 2011 at 2:15

GoogleCodeExporter commented 8 years ago
1. I can't say much about Spring because I don't have any experience with that.

2. I don't understand your intention with the weak references here exactly. 
While an activity is active you will probably want to have a hard reference to 
it because otherwise it might be reclaimed by the GC at any time. When it is 
inactive this hard link should be released but what you are then doing here is 
just implementing a cache.
I wonder whether it is actually the responsibility of the browser to do this 
caching or whether this belongs into the factory because the factory probably 
knows much better which caching policy is best for this type of activity and 
the programmer could then also choose a ready-made cache implementation of his 
own liking.

Original comment by m...@jugs.org on 4 Dec 2011 at 8:31

GoogleCodeExporter commented 8 years ago
Hi is this such an important thing?

By the way, it looks like you try to do something similar like dev on Android. 
Right ?

Cheers, Rob.

Original comment by weissmannrob on 6 Dec 2011 at 8:11

GoogleCodeExporter commented 8 years ago
Parallel transitions are needed to do cool page swipe animations, much like 
iPhone/Android have made popular. They would be a neat addition.

The framework has some similarities to Android, but in truth it is more 
inspired by GWT. Check out this video from the GWT architects for more info:

http://www.youtube.com/watch?v=PDuhR18-EdM

It make sense that this is similar as GWT is trying to make a clean Java API 
for web apps in the browser, whereas JFX Flow is trying to provide a clean API 
for browser-style apps on JFX. From the end users perspective the API should 
have similar concepts if the two frameworks hit their targets. There are a 
number of areas of difference though, JFX Flow doesn't have to worry about 
nasty JScript or running within a third-party, browser so it has some more 
flexibility. 

Regarding this issue, I am leaning towards Michaels' suggestion of leaving the 
caching up to the factory, and in fact there is already a PlaceResolver that 
maps a Place to an activity so this could work as the 'factory'. 

I plan to implement this before too long, but I have a Jan deadline for one of 
my projects, it's xmas and I am also in debate on the openjfx forum about some 
changes to JFX that could make the form validation part of JFX Flow work really 
well, so this change may not happen until Jan.

Original comment by zonski on 9 Dec 2011 at 3:36