Render, Visibitily, Enablity evaluation

Hi

When using JSF to build web applications, I simply set attributes rendered, visible or enabled to a value or a function that evaluates it. Every time a component is rendered, functions are evaluated and the programmer does not need to think in that any more.

Rendering, setting visibility or enabling a component in Vaadin seems to be not so easy. Component attributes can be set in 3 scopes:

  • session. Example: change of value in another component
  • application. Example: change in permissions for current user in another session
  • externally. Example: change of a value in parameter db table

Session changes are easier to handle by using listeners. Use of listeners may complicate a lot the simplicity of the application.

Application and external changes are not so easy to handle. I suppose Application scoped data are stored in static variables, but I don’t know how to fire events from a session to all the other sessions. In the case of external changes, no event can be fired.

I think the simplest way is the ability to override isEnabled, isReadOnly, and isVisible functions with custom status evaluators.

If you think not, which is the recommended Vaadin way to handle this?

Thanks

I think you are a bit confused about the way you should approach the application development with Vaadin. Vaadin allows you to do application development, almost like desktop application methodology. You don’t need to worry about session handling etc. Please have a look at the book on Vaadin to get some ideas.

Ok Syam, that’s right when you are dealing with desktop applications, but when the application is shared with many users, and component visibility may depend on many things which can change between one page update and the next one, visibility must be evaluated every time, not just when the component is created.

Vaadin application acts exactly as Desktop one, so you don’t have to worry about sharing. If multiple users open your web application - multiple application class and other components instances will be created and maintained separately for every user. So just code exactly as you usually do for the desktop Swing app.

Every user gets their own session of the application, thus they share only static fields. Every component belongs to one user, so if you set it visible for one person, it doesn’t affect anyone else in any matter.

Ok, all of you are right. Vaadin applications are like Swing applications.

The only point I wanted to remark is web applications are IMO more complex than destop ones:

  1. You have to load and unload components for not to overload browser and communication channel; something very like to ancient overlays. And that makes more difficult to separate the component loading logic from the application view

  2. Web applications use much more enabling, disabling, hide and show components than desktop applications

  3. Desktop applications tend to load the desktop box CPU; web applications put a lot of work in the user browser but much more for all the users in the server

After some time working with JSF, I think that putting apart the logic to evaluate those attributes and put in the hands of the rendered machine the ability to call them when needed is a good choice.

IDE WYSIWYG designers work with Swing components as they are. You cannot extend them if you want your IDE work with them. Vaadin components are used programatically and there is not a great problem to extend them to override isEnabled, isReadOnly and isVisible. I think that should be lighter for the server and clearer for the developer.

It would be great if Vaadin could include support for it. For instance, like this:

  1. add to the Component interface this method
    void setRenderEvaluator(RenderEvaluator renderEvaluator, RenderEvaluatorType type);

  2. create an interface and an enum
    interface RenderEvaluator {
    boolean isRight();
    }
    enum RenderEvaluatorType{
    VISIBLE, READ_ONLY, ENABLED //other evaluator types could be easily added
    }

  3. sample implementation in a component for the enabled property:
    private boolean enabled;
    private RenderEvaluator enabledEvaluator;

public void setRenderEvaluator(RenderEvaluator renderEvaluator, RenderEvaluatorType type){
if(type == RenderEvaluatorType.ENABLED)
enabledEvaluator=renderEvaluator;

}

public boolean isEnabled(){
return (renderEnabled==null? enabled : renderEnabled.isRight());
};

I’d like to read your opinions about this. Even if you think this is of no use.

Vaadin handles the communication for you and also makes sure only the needed components are visible in the browser. Additionally only data for visible components are transferred to the client (browser). So you do not have to worry about this.

I would say this is largely dependent on how the application is designed and not if it is a web application or desktop application. If you are making a large business system I do not see why the web version should be fundamentally different from the desktop version. You are facing the same issues and trying to solve the same problems.

All components are not rendered every time part of the screen is updated. Only the ones that have been “changed” are rendered. Thus overriding isVisible(), isEnabled() etc or adding a RenderEvaluator will not work as you expect as it will not be called for all components on the screen.

Additionally I think you will run into serious performance issues at some point independent of the framework you are using if you keep re-checking if components should be visible or not all the time. You would probably be better of using some sort of notifier-listener framework to actually update only when an event takes place and only the components really affected. JMS could probably be used for this.

If you really want to execute some code whenever the client sends some info to the server there is the TransactionListener which is called for every request. There it would be possible to e.g. loop through all components that are currently in the application and update any flags needed. Updating flags there using setEnabled()/setVisible() etc would also cause the component to actually be updated.

I would not go down this path as it will most likely cause troubles in the end. I would settle with an application that does the access control when populating the view (i.e. first time the user opens it) and otherwise only when really needed, i.e. when the user opens something for editing or similar. Of course your requirements may be different than my preferences.

May be, we are confused about your thinking pattern. Would you please write a tiny web application using Vaadin and then, discuss these issues based on that application as an example? (Or, you can even copy a simple one from the examples).

Yes, I’ll do it. But for now, I’m in my first steps with Vaadin, dealing with simpler tasks. When I have migrated something serious enough, I’ll be back on this.