Application Framework Architecture

classic Classic list List threaded Threaded
25 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Application Framework Architecture

Sébastien Bordes
I start a new topic related to overall architecture, I hope that we can share all good features we like to work with but also all bad ones we don't want to see anymore.

So what kind of architecture should we proposed ?

** Model - View => Controller like PureMVC (mainly used for Flex applications)
** View - Model  => Swing Components (JTable + TableModel)
** Model - View => ViewModel from Silverlight which is more a  Model-View-ViewController-ViewModel with the hidden xaml.cs file
** Command - EditPart - Figure - EditPolicy => from Eclipse GEF
** None (it could be an option for some people...)

**Add yours here....**

When I have started JRebirth I tried to choose the best of all technology with the objective to keep it as simple as possible.

The JRebirth pattern is a kind of MVC² with extensions.
** WB-CS-MVC, Wave-Behavior Command-Service Model-View-Controller

------------------------------------------
Start of JRebirth pattern description
------------------------------------------
The first MVC level is Command-Service-Model used to manage application lifecycle (these 3 elements are called Component)
The second one is Model-View-Controller used to manage UI (View and Controller can be omitted to gain some bytes in memory)
Extensions are managed by Behaviors that could be added to any Component of the first MVC layer.

All element of the first layer (=Components) are able to communicate synchronously or asynchronously with each other, a custom event bus (=Notifier) is used that carry on messages named Wave.

Into JRebirth Thread management is deeply linked to Component & Wave management.
=> all commands can be run any thread (JAT, JIT, JTP, HPTP)
=> any wave received by a Model will be handled into UI thread (=JAT)
=> each service call will be performed into a slot of the thread pool (=JTP)
=> any subscription to event bus are performed  into a dedicated thread (=JIT) with restraint similar to JAT

The design pattern also abuses of generic declaration to strongly link a Model with its View and Controller, so when you are handling an UI event, a simple call to getModel() will return the right Model type (the completion will provide all accessible method to sepped up development).


Commands can be grouped and chained to manage transaction (commit/rollback) and undo/redo; this is a great feature of Eclipse frameworks, the big pitfall (due to history) is that into Eclipse ecosystem we have to deal with GEF Commands, GMF Commands, EMF Commands and Eclipse Commands ... (responsible of a bunch of headache)
IMHO Command is really a must-have feature to perform short and repetitive tasks.

OSGI provides a certain type of Services, which could be hard to deploy and used (configuration etc), but a service layer could be very useful to manage data or repetitive call to a remote service.

Model,View and Controllers are a well-known pattern that could seem a little heavy, and a simple Model could do the job alone, but for complex code it could be important to maintain a good Separation of Concerns;
-> Model will manage the data and interaction with rest of the application
-> View will draw the User Interface
-> Controller will handler UI events

The Behavior is an addition that allow severals Component to do the same thing, it's a workaround for multiple inheritance, several different Components can use the same Behavior type (ie: a security Behavior that check credentials)
------------------------------------------
End of JRebirth pattern description
------------------------------------------

TL;NR

I think that this pattern answer well to all problems met while writing a modern application, but it's my vision, other frameworks have their own.

According to you which pattern should we provide ? and/or what pattern are you using ?





Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

aalmiray
Administrator
Speaking for Griffon, we follow the MVC pattern too. There are explicit types for each MVC member. An MVC triad (we call them MVCGroups) can be created by combining MVC members in any way developers see fit, for example sometimes there's no M, or sometimes the V is totally reusable (same instance) between two or more groups. All actions (provided by the C) are automatically executed off the UI thread (configurable too).

In contrast plain JavaFX encourages MVC too but mixes the responsibilities of the M and C in the same target (the FXML controller). It also does not encourage separation of V widgets from the C (they get injected by means of the @FXML annotation).

Regardless of whether there should be an M member (be it a simple model, or a presentation model, or a non-anemic model) what's clear is that we have C members (the action providers) and V members (the UI). Forcing an MVC approach makes sense IMHO if we can make some of these members optional (like when no M is needed for example). But then again what's key at this stage is defining the actions, their properties and how they can be used. Implementors can further define how these actions are kept together (inside a C, or a Map, or somewhere else).

Btw, IIRC Eclipse 4 Platform uses Command Handlers, so technically there's no single C but a set of actions.

Cheers,
Andfes
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Sébastien Bordes
aalmiray wrote
 if we can make some of these members optional
I'm totally agree with you, things must be kept as simple as possible, and all parts shall be optional; the underlayer framework should do the job.

JRebirth Precisions
JRebirth MVC is a little bit complex than what I explained. The MVC patern is a Model-First (because M is a Component) and could be:
* M - Only Model: rely on SimpleModel implementation
* MV - Model with a View: Controller is omitted
* MVC - Model, View, Controller: Basic Implementation
* FMFFC - FxmlModel , Fxml, FxmlController: View and Controller are respectively replaced by Fxml and FxmlController
* MVCFFC - FxmlModel, View, Controller, Fxml, FxmlController: Basic + Fxml files

In my case the Controller only register UI handler and do local things (its responsibility is variable but is kept into MVC). If the action should trigger something outside the view it can call another Component (CSM) by usinf sync call (trought facade) or async call throught event bus (Notifier+Wave).
It's also possible to link directly a command to an event handler (with some parameters).

I think that it's important to propose a way to write UI without fxml and with plain java code because sometimes it's more easy to write few java lines than integrating fxml files (moreover it's a bit faster because we don't parse fxml file)

Concerning Eclipse
Eclipse provides Command and Command Handler because everything is extensible with a lot of Provider and Priority management, JRebirth Command definition is an Interface (extending Command) and Command Handler are just concrete class that implements this Interface, thus we can support different implementations for a same command without any redundant information or complex pattern (mixing code and xml). This modularity also works for Models and Services, useful to use a custom branding system or to call different kind of remote services.

GriffonFX questions
If I understand well, GriffonFX use a View-First MVC, and the View is a fxml file (support plain java too ?).
You action is like JRebirth Commands, but are they mandatory? ie if I check a checkbox to enable a ui part, where do you put the code, into an action or elsewhere?
Your Controller is another part than FXMLController shipped with FXML file ?
What is the responsiility of your Model ?

Does GriffonFX provide :
_ a way to declare Service
_ Action not triggered by an UI event
_ a local event bus

I'm curious to see if other AF have a different approach (and I think they have), let us know
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

raniejade
In reply to this post by Sébastien Bordes
I like the idea of smaller reusable components (aside from views), just like android's fragment class http://developer.android.com/guide/components/fragments.html.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Sébastien Bordes
raniejade wrote
I like the idea of smaller reusable components (aside from views), just like android's fragment class http://developer.android.com/guide/components/fragments.html.
I think that you are talking of reusable UI components?

Fxml files can do that, or any method returning a JavaFX Node, for convenience they can possibly be wrapped into a class.

Smart Reusable Components
If you want more complexe reusable (ui) clever component, JRebirth Provide InnerComponent that allow to reuse other Component (CSM) into one (composition), initialized after the owner, strongly linked by it, released by it and ready to use.
ie: your login page can have an InnerComponent displaying an icon reflecting the server availability status and listening a message sent by a watchdog Service. This InnerComponent could be reused elsewhere in your application with the same logic to display the server status.
 
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

aalmiray
Administrator
In reply to this post by Sébastien Bordes
Well, I can't say MVCs in Griffon are View first considering you may configure an MVC group without a View! ;-)

Models follow the presentation model pattern. They are simply put just data holders. They make sure controllers and view can talk to each other without one invoking methods directly on the other. Views typically bind UI widget properties to model properties. Controllers work with model properties only.

Services are regular beans that can be injected into any instance using @Inject. This is how Afterburner.fx and Jacpfx do it to. I believe it's possible to do the same with Eclipse4 though it may be the case that OSGi specific services require a different annotation.

Actions are defined in the following way:
 - their behavior is defined by a matching public method provided by the Controller that owns them.
 - their properties can be obtained from i18nzable resources (icon, description, mnemonic and so forth).
 - these properties can be updated programmatically too.
 - actions are toolkit agnostic but they can create a toolkit specific action (from GriffonAction into javax.swing.Action for example).
 - actions run automatically outside of the UI thread. this behavior is configurable per action, controller or application wide.

There is an application wide event bus, with the possibility to create localized event buses too. The event bus follows a naming convention to figure out event handlers. This is a part of Griffon I'd like to make explicit with annotations, similarly as it's done by Eclipse4. Perhaps even reuse the Event Bus definition from CDI 2.0.

More info on Griffon can be found at the guide, specifically:

 controllers & action: http://new.griffon-framework.org/guide/latest/#_controllers
 services: http://new.griffon-framework.org/guide/latest/#_services
 event bus: http://new.griffon-framework.org/guide/latest/#_events
 javafx sample app: http://new.griffon-framework.org/guide/latest/#_javafx_2

In terms of JavaFX UIs, Griffon allows developers to define the Views

 - using FXML
 - using JavaFX nodes directly
 - using GroovyFX if Groovy is the main language

The sample JavaFx Java app linked before uses FXML while the Groovy based application relies on GroovyFX. Nothing prevents the developer from using JavaFx directly.

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

aalmiray
Administrator
In reply to this post by raniejade
Yup, reusable components via a fragment mechanism (like the one you linked form Android) is something that we can discuss. This feature however belongs to a higher level IMO, the architecture. Now, I'm not saying we can't deliver it, I'm saying we must be cautious in pushing a particular architecture style or the other.

Bottom line is, that having a base API allows extensions (like this one) to be built on top. So even if the JSR or the RI do not deliver a fragment feature in the Final release someone can build it on top and ship it as part of an open source library :-)

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

raniejade
Good idea, I think we can still get some idea from android's architecture.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

raniejade
In reply to this post by Sébastien Bordes
Before this thread get long, we need to keep in mind Testability :).
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Sébastien Bordes
Thanks Andres for these explanations.
Learning how other frameworks work is useful to understand their philosophy and how they solve common problem.

Obviously if the JSR API choose some architecture points, some framework will be able to follow the move (and they won't stop their development). So we must remain into the mainstream.

So for GriffonFX, according to my understanding, the pattern could be G(MVC)+B where B means Bean that could be used as Action or Service, threading concerns are always managed using constructs like runInsideUIAsync.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Hendrik Ebbers
A quick overview to the DataFX MVC and Flow API

DataFX provides a MVC approach that adds a lot of API sugar to the FXML API of JavaFX. As a first example you can find a simple controller here:
https://gist.github.com/hendrikebbers/9eb8f025dfb4696db49e

DataFX Controllers supports a lot of standard annotations like @PostConstruct. In addition the @ViewNode and @ViewController Annotation can be used to provide a link to the view. @ViewNode does mainly the same as @FXML but provides additional functionalities. Actions can be defined by an unique id. Therefore you can use Annotations to bind controls to actions. If you want a action to be called in a background thread you only need to add the @Async Annotation to the method.

Next to this there are some special annotations to inject DataFX related Objects like an exception handler or the DataFX concurrency toolkit. Here is an example:
https://gist.github.com/hendrikebbers/e7fb475ba999da8ffed6

On top of the MVC API is the Flow API. By using this API you can define flows in your application. By doing so you can define links between views or actions that will open a specific view. A Flow can easily defined by using the controller classes:
https://gist.github.com/hendrikebbers/67400df5b5296cdbcd4f

When using a flow you can define actions as global actions for the flow or actions that are view specific.

Next to this the Flow API adds a lot of new annotations. By adding the @BackAction annotation to a node like a button the flow will navigate back to the last view once the button is clicked. Instead of defining the links in the flow definition you can use the @LinkAction(NextViewController.class) annotation.

In addition the Flow API provides CDI by using @Inject. To do so 4 different scopes are defined:

application scope (singleton)
flow scope (same instance will be injected in every controller / view / model of the flow)
view scope (same instance will be injected in the controller / model of the view)
dependend (always inject a new instance)

In addition DataFX provides a event system. This can be used to handle events between 2 separated flows, for example. Each event type is defined by a unique id. The following code snippet defines two controllers that can be used in complete different parts of the application and don’t know each other. By using the event system the first controller can send events to the second one by clicking the button:
https://gist.github.com/hendrikebbers/b81f5c3816f5055b03f8
If you want the async events you only need to add the @Async annotation to the producer or / and receiver. By doing so you can create events on a background thread that will be received on the platform thread.

If you want to now more you should have a look at the DataFX tutorials (http://www.guigarage.com/2014/05/datafx-8-0-tutorials/) or ask me :)
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Hendrik Ebbers
About the DataFX plugin API:

DataFX provides a PlugIn API that can be used to define additional components / plugins that will be managed by DataFX. Therefore you can define two types of Annotations: A injection annotation that can be used to inject specific objects or a handler annotation that can be use to do some stuff with objects. Here are two examples:

DataFX provides a plugin for feature driven development. By doing so you can define nodes in your controller like this:

@FXML
@HideByFeature("PLAY_FEATURE")
private Button playButton;

@FXML
@DisabledByFeature("FEATURE2")
private Button button2;

Now you can use the togglz API (http://www.togglz.org/documentation/overview.html) to define feature toggles and change them at runtime. If you for example disable the PLAY_FEATURE the playButton will become hidden. This is en example for a plugin that provides handler annotations.

Another example:

DataFX provides a Plugin for remote EJBs. By using the plugin you can inject a Remote-EJB-Proxy in your controller:
https://gist.github.com/hendrikebbers/7c0d042a5ba43baf950e
In this case the EJB Wrapper / Proxy will be injected by using the custom / plugin annotation
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Sébastien Bordes
Cool, DataFX bring some interesting features ( Flow, Feature management, concise annotated event bus (but global?))

When you mention Platform thread, you are talking about UI thread (I name it JAT for JavaFX Application Thread, its full real name), we should find a name for it inorder that everybody have use the same word for it.

Do you support view with plain java code ?

 
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

neugens
In reply to this post by Hendrik Ebbers
I really like DataFX, and it was very impressive to see it live at JavaOne last year.

One thing I'm not so sure about the actual API though is the implicit contract defined by the various annotations. On one end, this is a great way to decouple everything, this is probably the greatest advantage, and something that DataFX really does wonderfully well.

On the other end, most of those annotations (see for example @PostConstructor) impose an agreement ("the annotations must be used on a method that takes no parameters"), but this agreement can only be checked at runtime, and only if the code is actually executed. Probably this can be solved by running some sort of validator at build time or at class loading time, but I still see this to be a problem in the long term for maintainability (there's no compile time check that warns you against changes of the API relative to those annotations).
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

aalmiray
Administrator
Indeed. I'd like the contract to be very explicit. For example, in Griffon we rely on naming conventions to determine actions and event handlers. DataFX uses annotations for this but some of them are perhaps too narrow or specific.

To be fair the contract of @PostConstruct was well defined since JavaEE 5 (link to Javadoc http://docs.oracle.com/javaee/7/api/javax/annotation/PostConstruct.html).

What's surprising is that the Eclipse 4 platform totally disregarded this javadoc an applied its own constraints:

 - methods may have any number of arguments.
 - arguments may use @Inject.
 - there may be more than one method annotated with @PostConstruct (I think this is true).

Being able to check at compile time that annotations are being used in the right way would mean writing an annotation processor. This sounds like a good idea as long as the target code is written in Java. It breaks down immediately if there's a different JVM language at play: Groovy requires an AST transformation; God knows what Scala needs.

So yeah, if annotation usage becomes an problem I think the RI could provide a set of annotation processors (as an additional JAR) that any other framework implementor may use to verify applications are conformant to the annotation's usage.

Cheers,
Andres
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Hendrik Ebbers
In reply to this post by Sébastien Bordes
Sébastien Bordes wrote
Cool, DataFX bring some interesting features ( Flow, Feature management, concise annotated event bus (but global?))
Thx :)
Currently the event bus is global. The main idea is to send events from one flow to another one. The module is still in the incubator and therefore it can be easily changed. My first idea was an event system that isn't global but by doing so the API wasn't that nice. One of the main goals of DataFX is to create application code that is easy readable.

Sébastien Bordes wrote
When you mention Platform thread, you are talking about UI thread (I name it JAT for JavaFX Application Thread, its full real name), we should find a name for it inorder that everybody have use the same word for it.
Yes. I would like Platform Thread or Toolkit Thread.

Sébastien Bordes wrote
Do you support view with plain java code ?
This feature is planed for the future. This is one point why I introduced the @ViewNode annotation instead of using @FXML that don't match when you have a coded view instead of a FXML one.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Hendrik Ebbers
When talking about the use of annotations in controllers I think that some are Java standard and should be used in the JSR:

- @PostConstruct to mark a method in the controller class that will be called once the instance is created and the injection is done. When talking about Inject I mean fields that are marked with @Inject and fields that are marked by JSR specific annotations.
- @Inject to inject you data model or services in the controller. I would not use this annotation to inject nodes of the view in the controller.

Next to this I think it's important to add some additional annotations:

- An annotation to inject nodes / components in the view to the controller. This is what @FXML in JavaFX or @ViewNode in DataFX does.
- An annotation to define the runtime behavior of a method. Normally when you add a action handler to a button the handler will be called in the platform thread. By using DataFX you can define annotations (for example @ActionTrigger & @ActionMethod) to bind actions to a specific control. In Griffon you need to use naming conventions. I think there will be a way to bind a method as an action handler to a control, too. The JSR must specify if the method will be called on the platform thread or on a background thread by default. DataFX calls the method on the platform thread and Griffon on a background thread. I like the first one more because the behavior is known from most UI toolkits. Let's say we adopt this for the JSR. In that case it must be easy to define a way to call the method on a background thread. In DataFX I introduced the @Async annotation. If a action methods is marked by this annotation it will be called on a background thread. I think such an annotation will be very useful for the JSR.

When having an annotation to inject ui nodes in the controller you will always have a toolkit specific controller because you will inject a component / node class of the toolkit like:

@ViewNode
private JButton swingButton;

One of the main goals of the JSR is to provide a toolkit undefended way how applications can be defined. Wouldn't it be great if we can define a way how controllers can be reused for several toolkits. By doing so you only need to change the view part for a MVC module if you want to reuse it on a different platform (like desktop and iOS / RoboVM). I had some discussions with Andres about this topic some weeks ago and we found a approach that maybe will work: Next to the annotation that can be used to inject controls the JSR will provide a second one to inject properties. Here is an example:

@ViewProperty("myButton.text")
private Property<String> buttonText;

public void anyMethod() {
     buttonText.set("click me");
}

This code isn't platform or toolkit specific and can be reused on any toolkit. Ok, the toolkit must provides buttons that have a text. But even this is ok, if the properties provide a method to check it. On mobile or touch devices you normally don't have tooltips and I think that iOS doesn't support them. So if you want to write a controller code that can be reused on iOS it maybe looks like this:

@ViewProperty("myButton.tooltip")
private Property<String> buttonTooltip;

public void anyMethod() {
     if(buttonTooltip.isSupported()) {
         buttonTooltip.set("Don't click this button!");
     }
}

What does this mean:
The JSR must provide a general property API. But I think that such an API will make sense. Working with properties is great and if the properties provide change listeners and methods to bind properties this will be a great benefit.

What do you think?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

Sébastien Bordes
In reply to this post by aalmiray
aalmiray wrote
Being able to check at compile time that annotations are being used in the right way would mean writing an annotation processor. This sounds like a good idea as long as the target code is written in Java. It breaks down immediately if there's a different JVM language at play: Groovy requires an AST transformation; God knows what Scala needs.
JRebirth provides a developerMode (a simple flag activated into jrebirth.properties) that allow to check Wave API violation and throw immediately an understandable exception. This API is composed by annoation and basic java Objects.
Thus developers are warned at runtime, it should be better do it at runtime but could be complex for modular applications.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

aalmiray
Administrator
In reply to this post by Hendrik Ebbers
I like the idea of properties, but It's a very slippery slope than leads into a big, big hole to Wonderland/Neverland.

Some of you may be aware of Stephen's Bean properties 2.0

   http://blog.joda.org/2014/12/what-might-beans-v20-spec-contain.html

If not mistaken it will be made into a JEP or JSR and hopefully added to JDK9. I'd be cautious and not define our own property layer here but rather send feedback and participate at

   http://jodastephen.github.io/property-alliance/

Another way to see actions working with view data in an UI toolkit independent manner is through a presentation model. A Presentation model is simply a data holder, getters and setters as barebones. Its properties should be observable, and they can be so using a specific property API as required by the target UI toolkit. i.e, JavaFX Property if JavaFX, observable (via PropertyChangeEvent) if Swing/SWT.

Observable JavaFX presentation models often expose the base values besides the direct Property references. Observable presentation models in Swing/SWT can only expose the base values. So there's a common ground.

Instead of injecting properties directly into a Controller (the owner of actions), we can inject a model. this model can be injected into a View too; and it will be the job of the View to "bind" UI properties to model properties. Views are UI specific so there's little that can be standardized here. Here's a rough idea how this could work


public class SampeModel {
    private StringProperty text = ...
   // getters and setters following the JavaFX conventions
}

public class SampleController {
   @Inject private SampleModel  model;

   @Action
   public void someMethod() {
       model.setText("click me");
   }
}

public class SampleView {
   @Inject private SampleModel  model;

   @FXML private Button button;

   @PostConstruct
   private void initUI() {
       runInsideUIThreadSync(() -> {
           Node node = loadFXML();
           model.textProperty().bindBidirectionally(button.textProperty());
           // add node to an scene or parent container
       });
   }
}


Some questions and notes:

 - should these classes have a defined JSR type? that is, Model, Controller and View.
 - the model instance should have a scope != @Singleton so that the same instance can be injected in both Controller and View. Perhaps the three classes should use a scope like @MVC("sample").
- how would one create multiple instances of an @MVC set? This points to having well defined identifiers.
- how would the method annotated with @Action be registered as an EventHandler on the button?
- how would additional properties harvested by @Action (name, icon, tooltip, accelerator, ect) be applied to the linked button?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Application Framework Architecture

neugens
In reply to this post by Hendrik Ebbers
On Tue, 2015-02-17 at 00:26 -0700, Hendrik Ebbers [via jsr377-api]
wrote:

> When talking about the use of annotations in controllers I think that
> some are Java standard and should be used in the JSR:
>
> - @PostConstruct to mark a method in the controller class that will be
> called once the instance is created and the injection is done. When
> talking about Inject I mean fields that are marked with @Inject and
> fields that are marked by JSR specific annotations.
> - @Inject to inject you data model or services in the controller. I
> would not use this annotation to inject nodes of the view in the
> controller.
>
> Next to this I think it's important to add some additional
> annotations:
>
> - An annotation to inject nodes / components in the view to the
> controller. This is what @FXML in JavaFX or @ViewNode in DataFX does.
> - An annotation to define the runtime behavior of a method. Normally
> when you add a action handler to a button the handler will be called
> in the platform thread. By using DataFX you can define annotations
> (for example @ActionTrigger & @ActionMethod) to bind actions to a
> specific control. In Griffon you need to use naming conventions. I
> think there will be a way to bind a method as an action handler to a
> control, too. The JSR must specify if the method will be called on the
> platform thread or on a background thread by default. DataFX calls the
> method on the platform thread and Griffon on a background thread. I
> like the first one more because the behavior is known from most UI
> toolkits. Let's say we adopt this for the JSR. In that case it must be
> easy to define a way to call the method on a background thread. In
> DataFX I introduced the @Async annotation. If a action methods is
> marked by this annotation it will be called on a background thread. I
> think such an annotation will be very useful for the JSR.
>
> When having an annotation to inject ui nodes in the controller you
> will always have a toolkit specific controller because you will inject
> a component / node class of the toolkit like:
>
> @ViewNode
> private JButton swingButton;
>
> One of the main goals of the JSR is to provide a toolkit undefended
> way how applications can be defined. Wouldn't it be great if we can
> define a way how controllers can be reused for several toolkits. By
> doing so you only need to change the view part for a MVC module if you
> want to reuse it on a different platform (like desktop and iOS /
> RoboVM). I had some discussions with Andres about this topic some
> weeks ago and we found a approach that maybe will work: Next to the
> annotation that can be used to inject controls the JSR will provide a
> second one to inject properties. Here is an example:
>
> @ViewProperty("myButton.text")
> private Property<String> buttonText;
>
> public void anyMethod() {
>      buttonText.set("click me");
> }
>
> This code isn't platform or toolkit specific and can be reused on any
> toolkit. Ok, the toolkit must provides buttons that have a text. But
> even this is ok, if the properties provide a method to check it. On
> mobile or touch devices you normally don't have tooltips and I think
> that iOS doesn't support them. So if you want to write a controller
> code that can be reused on iOS it maybe looks like this:
>
> @ViewProperty("myButton.tooltip")
> private Property<String> buttonTooltip;
>
> public void anyMethod() {
>      if(buttonTooltip.isSupported()) {
>          buttonTooltip.set("Don't click this button!");
>      }
> }
>
> What does this mean:
> The JSR must provide a general property API. But I think that such an
> API will make sense. Working with properties is great and if the
> properties provide change listeners and methods to bind properties
> this will be a great benefit.
>
> What do you think?

In Thermostat we had the need to support both Swing and SWT, which are
very different.

What we did was to create an "abstract" View, to the end result of
basically a [Model] [View] [View Controller] [Controller].

The View knows about the specific types, but the controller doesn't, it
just happens to speak with the view via their own contract, which
includes an event system.

This is very similar to what you describe with properties in fact, and
it seems wot work very well (although our first iteration of this was a
bit clumsy), but those properties are just another abstraction.

Another idea I was exploring was to make everything event based, so the
event bus becomes a duplex channel (View <-> Controller). The advantage
here is that any view that register for a specific event is notified, so
you can actually have more views interested in a single event.

Cheers,
Mario

12
Loading...