• Home
  • About
  • Sample Apps
  • Videos
  • J1 Session-Blog: Return of the Puzzlers (Schlock and Awe)

    June 3rd, 2009

     

    Dressed in boiler suites, Joshua Bloch (Google Inc.) and Neal Gafter (Microsoft) put on quite a show in which they present a series of traps to be avoided in the Java language…

     

    Joshua Bloch (Google Inc.) and Neal Gafter (Microsoft)

     

    •    First problem: What does Boolean (Strings) do? Answer: Depends on the value of a particular system property – which is obviously completely horrible.
    •    Second problem: Overriding addAll/add of a HashSet is dangerous. Something we should all know because (for example) addAll may be implemented in terms of add. Answer is to create a so-called forwarding set, in which the inhertance characteristics of the implementation are defined by us. A class whose self-use patterns are not explicitly defined and documented should not be inherited from. Google collections provides a suite of forwarding classes.
    •    Third problem: Unpredictable behaviour caused by invoking a public (overridable) method in a constructor. Apparently Brian Goetz has made this mistake.
    •    Fourth problem: Searching which depends on a comparator is broken. In the example the comparator is broken because autoboxed integers cannot be tested for equality with. In addition, Comparator must implement total ordering, which in this example is broken because of the auto-boxing.
    •    Fifth problem: Initialization error caused by invoking enum constructor when a static variable has not been initialized.
    •    Sixth problem: Memory leak caused by assigning a large number of values to non-static thread locals. Thread local contains a weak hashmap.  This is a complicated one to follow. One obvious moral: Don’t use non-static inner classes.
    •    Seventh problem: Problem caused when two versions of a class contain different constant definitions. Contants are inlined in Java. However, null is not considered a constant in this sense.

    Overall: As we’d expect, nasty little problems which are likely to occur at some point in the developer’s life. Bloch suggests using “FindBugs”, which will apparently detect all of the above problems.


    J1 Session-Blog: Ajax vs. JavaFX Technology

    June 3rd, 2009

    First note that the speakers Ben Galbraith and Don Almaer are co-founders of ajaxian.com, which is clearly an AJAX-shop. They claim that Web technologies and Java went stagnent in the UI space. Ajax and JavaFX have the characteristics of a renaissance. They structure the talk in the form of a “discussion” or a series of arguments, where one supposedly pits the advantages of said technology against the other.

     

    •    Argument #1: Java performs way faster than JavaScript; on the other hand JavaScript is getting faster all the time (V8 team at Google); plus apps like Google wave demonstrate that performance is good enough.
    •    Argument #2: Responsiveness improved by worker-threads in a Java GUI. Yet using “web workers” we can overcome the limitation of JavaScript to a single thread. Demo of Pictastic proves the point. Having said that, web workers are still 10 times slower than Java; plus the API is extremely limited. In “web worker”, worker threads don’t share state, which is way safer than the totally flexible Java approach.
    •    Argument #3: GC way more advanced in Java. On the other hand, incremental GC in Mozilla is improving all the time. A lousy fact of the JVN is having to determine how much memory the app requires (or how much is available) wherever the app is deployed.
    •    Argument #4: Graphical capabilities of Java surpass what web apps can do. But performance of Bubblemark benchmark app shows that Google chrome achieves 100 frames per second. By comparison JavaFX achieves 24 FPS. With vector graphics Chrome is back down to 30 FPS. What the speakers don’t consider is that JavaFX is a very new and to-date under-optimised technology.
    •    Argument #5: An Ajax 3D demo “metatunnel” is pretty impressive. Most browsers, apparently, are offering 3D extensions. It’s still at the experimental stage, however. JavaFX, on the other hand, has nothing to show in 3D.
    •    Argument #6: Java is weak on fonts. The speakers claim that can’t use native fonts in Java (is this true? I seem to remember supplying Java with some additional fonts some years back.) Control over fonts in the Ajax world is even more limited, however.
    •    Argument #7: JavaFX provides “amazing” video support. Counter argument: Flash plugin us ubiquitous and surpasses JavaFX in terms of maturity. Open Web Video offers sophisticated video functions.
    •    Argument #8: Binding in JavaFX is compact and elegant. Web toolkits are very clumsy by comparison. The speakers quickly mention Mixins, Animation and Effects. All of this is way easier in JavaFX…
    •    Argument #9: Legitimate critisisms are raised about JavaFX syntax. Speakers suggest that JavaScript is actually easier and closer to Java than JavaFX Script. And, of course, JavaFX totally lacks widgets like table/tree. Web toolkits even provide some very cool layout management and tools for constructing GUIs.
    •    Argument #10: Tooling superior in the Java world.
    •    Argument #11: Deployment. Web wins here, obviously, except for significant browser incompatibilities. Applets, Mac etc. are lousy too, however.

     

    Conclusion: A pretty damning result for JavaFX, which is for the most part justified (at least today.) What the speakers fail to do, however, is talk more fairly about the significant problems faced by AJAX developers on a daily basis.


    What’s Needed Besides the Presentation Model?

    October 14th, 2008

    In the previous chapter we discussed how a simple presentation model framework can substantially reduce the implementation effort for complex user interfaces while at the same time delivering a clean and maintainable software design. However, the presentation model framework is still not sufficient for an efficient implementation of the presentation layer. What else do we need? We can identify the following areas:

    • Attaching user interface components to model properties can be quite cumbersome . Some kind of binding infrastructure takes care of this.
    • Configuring user interface components through a low-level API takes too many lines of code and does not guarantee consistency. A component factory helps to do this with less code and more consistency.
    • Validation can be a tricky beast. Adding validation in the presentation layer is required for better feedback but leads to duplication of business layer validation logic.
    • The design of ergonomic, consistent and visually attractive form-based user interfaces is a challenging task. Furthermore, coding such user interfaces can take way too long without a decent infrastructure.

    Binding
    Generally speaking, the term “binding” denotes how to keep to properties in sync. In the case of user interfaces one property is hosted by a view component and the other one is exposed by the presentation respectively domain model. As we have seen in our examples this is a two-way sychronization. Without a binding infrastructure you have at least to register an event listener at the user interface component which gets notified about value changes and sets the model property accordingly. Additionally, the user interface component needs to register as an observer to the model property and update the visualization correspondingly. A binding infrastructure can replace multiple lines of code to accomplish the above with a single line of code which is even more expressive and comprehensible. Model properties can be visualized in quite different ways. For example, an integer value could be visualized as a number literal in a text field or as a selection a radio box, check box group, or a combo box. The binding infrastructure should cope with all these variations.
    If user input is not to be immediately commited to the model property the binding infrastructure can buffer these value changes. Finally, the binding infrastructure has to care for value conversions back and forth, e.g. the input field component only accepts strings but the model property is a number.
    For Swing there are several binding infrastructures available: probably the most popular one is JGoodies Binding. JSR 295 is another approach, a reference implementation of which can be found here.

    Component Factory
    The components of common user interface toolkits such as the Swing library expose a large number of properties. Usually, a developer has to configure a component instance to her needs by setting the necessary properties one by one. This not only leads to many lines of code but consistency is also hard to achieve even within the same view. For example, the input field for a customer id should look and behave the same within and across several applications. A component factory both encapsulates the creation and configuration of generic and domain specific user interface components. Even for small projects a component factory is highly recommended.

    Validation
    Rich Internet Applications do not demand more validation but more frequent validation. With this type of application a user would like to get immediate feedback as he uses the application. The implementation of such fine granular feedback is much more demanding than with a classical web application which gets validated once when submitting the entire form. In order to give immediate feedback, the presentation layer has to validate immediately on user input. Nevertheless, the business layer cannot trust the presentation layer upon validation and therefore it again has to validate all data in its services. Unfortunately, this might lead to code duplication. Clever modularization can factor out the validation code which can the be shared between the presentation and business layer. However, sharing is only possible if you have the same run-time environment for the presentation and business layer. In a scenario where your business logic is implemented in Java and your presentation layer is based on JavaScript you are out of luck and forced to reimplement parts of your validation in JavaScript.
    Basically, there are two types of validation, syntactical and semantical. Syntactical validation should be hosted in the presentation layer in any case, even at the cost of code duplication. You can simply not afford to call a validation service with every user keystroke. Syntactical validation can usually be expressed descriptively and hence it might be sufficient that the business layer just returns a formal description of the validation which is interpreted in the presentation layer. This helps to avoid code duplication. With semantical validation it’s a different story. It is recommended to provide this type of validation as a business service. Semantic validation probably means to access further services or a database. Duplicating this code in the presentation layer is not only expensive but also incurs a performance penality when triggering serveral client-server round-trips. An example for a validation framework for Swing is JGoodies Validation.

    Form Layout
    Designing ergonomic and visually attractive form-based user interfaces is far from trivial. If you have ever tried to achieve this with the basic Swing components and the gridbag layout manager you know what I am talking about. Granted, there are better layout managers, e.g. MiG, JGoodies Forms, the GroupLayout Manager, or the new ULC form component. If you are looking for a comparison of different layout managers, the layout manager showdown has a nice overview. Using these layout managers it is definitely easier to design forms but if you have to implement dozens of densily crowded forms it is still a drag. The problems are efficiency and consistency. Most likely your applications features a few basic form patterns, e.g. a master detail view, search view, etc. Even with an advanced layout manager there is too much design variability for a developer which hampers efficiency and certainly does not lead to a consistent user interface., especially when developing in a team. Therefore, it is recommended to build project (or company) -specific form components which kind of hard-code the layout. This easily pays off with increased development efficiency and user interface consistency. In a recent project we identified the common user interface patterns upfront (we call it meta design) and implemented the necessary form components. As a result, the developers are way more efficient and the user interface of this application (featuring hundreds of form views) is surprisingly consistent.

    The presentation model is indispensible for realizing the complex user interfaces of Rich Internet Applications. It takes very little infrastructure (implemented as a framework), even when extending the presentation model approach with application components for a hierarchical decomposition of complex user interfaces. If you add binding, a component factory, validation and meta design to that your Rich Internet applications will be ahead of those from your competitors with respect to time to market and visual attractiveness.

    Part 1: MVC and the Brave New World of RIA
    Part 2: The World Needs More Models
    Part 3: A Simple View on Complex Stuff
    Part 4: Hierarchies
    Part 5: Presentation Model Framework
    Part 6: What’s Needed Besides the Presentation Model


    Presentation Model Framework

    September 19th, 2008

    In the previous chapter we looked at the implementation of a non-trivial application composed of several application components. If you had a closer look at the code fragments in chapter 3 you probably realized that even for a simple application component quite some boiler plate code was required to make it work. The presentation model contains infrastructure code that takes care of property listener handling, e.g. registering property change listeners and distributing property changes to listeners. It also has to delegate most property requests to the business object. These tasks can easily be extracted into a base class and handled generically.
    In addition, the base class can provide infrastructure such as:

    • Creation, proper initialization, and management of a hierarchy of application components: the root application component is responsible for property change listener management, i. e. all sub-application components delegate to the root application component rather than managing this all over the hierarchy, which simpifies debugging a lot.
    • Breaking cycles: the execution of a property change listener should not trigger (directly or indirectly) the same property change listener.
    • Undo/Redo support: The presentation model is a Java bean and all state transitions are performed by property changes. Hence, undo/redo support is really easy to implement on a generic basis. The abstract presentation model just records all property changes and can undo or redo them on request.

    This leads to a simple presentation model framework with only a few hundred lines of code. It is independent of any widget library, although the current implementation includes configurable table and tree models based on the ULC widget library. They should be easily replaceable by model implementations of some other component library.

    The view code is even more cumbersome. Despite being pretty straightforward way too many lines of code are needed for implementing the view. How can this be simplified?

    • Creating the layout can be accomplished by using either a declarative or programmatic approach. For the declarative approach one would need some XML schema for defining the components and layout of the user interface. At run-time, an interpreter creates the UI based on the XML description. The programmatic approach requires at least a layout class which is tailored to form-based user interfaces. Examples are JGoodies Forms or the new form infrastructure in UltraLightClient ‘08.
    • Connecting the widgets to the presentation model and vice versa can be vastly simplified by utilizing some binding infrastructure. We will talk about binding in the next chapter.
    • The remaining tasks are easy to implement and require little code: proper initialization of the view (most initializations are triggered by the presentation model anyway), forwarding events to the presentation model that are not yet taken care of by the binding infrastructure (e.g. button actions), and reacting to changes in the presentation model (e.g. enabling/disabling portions of the user interface accordingly).

    Now lets have a look at the code for the example from chapter 3. For the programmatic layout of the form I used a simple form layout class.

    The core code for the presentation model looks almost like the example given in chapter 3 (boiled down to three model properties for the sake of simplicity). Thanks to the presentation model framework, the number of lines of code is cut almost in half (now less than 150 lines of code incl. comments and blank lines).

    public class SimpleFormPresentationModel extends AbstractPresentationModel {
        private Person fPerson;
        private ErrorList fErrorList;
     
        public final static String PERSON_NAME = "person.name";
        public final static String PERSON_FIRST_NAME = "person.firstName";
        public final static String ERROR_LIST = "errorList";
     
        private final static String[] PREFIXES = {"PERSON", "UNIVERSITY"};
     
        public SimpleFormPresentationModel() {
            fHasChangedEnabler = new ULCHasChangedEnabler();
        }
     
        public void basicInit() {
            fErrorList = new ErrorList();
            fireAllPropertiesChanged(PREFIXES);
            addPropertyChangeListener(this, getAllPropertyNames(PREFIXES));
            super.basicInit();
        }
     
        public void update(String propertyName, Object oldValue, Object newValue) {
            if (propertyName.equals(PERSON_FIRST_NAME)) {
                validatePerson(PERSON_FIRST_NAME);
                firePropertyChanged(PERSON_NAME, getPersonName(getPerson()));
            }
        }
     
        public Person getPerson() {
            return fPerson;
        }
     
        protected void setPerson(Person person) {
            fPerson = person;
            fireAllPropertiesChanged(PREFIXES);
            fHasChangedEnabler.reset();
            setFocusToProperty(PERSON_FIRST_NAME);
        }
     
        public String getPersonName(Person person) {
            return person != null ? person.getFirstName() + " " + person.getLastName() : "";
        }
    }

    Some functionality is based on conventions which can be customized by overriding the appropriate methods. Properties are “exported” by declaring the path as a string constant, e.g. PERSON_NAME. The business object is referenced by an instance variable. The prefixes of the property constant names are kept in the string array PREFIXES. This way, properties can easily be retrieved by reflection. This is used to fire property change events or register event listeners for all properties.

    Theview class is also reduced to half the lines of code. This is mainly due to the form layout class and the binding infrastructure.

    public class SimpleFormPane implements IPropertyChangeListener {
        private FormLayout fFormLayout;
        private ULCBoxPane fFormPane;
        private ULCTextField fName;
        private ULCTextField fFirstName;
        private SimpleFormPresentationModel fFormPresentationModel;
        private Binding fBinding;
        private Color fErrorColor = new Color(255, 0, 0, 192);
     
        public SimpleFormPane(SimpleFormPresentationModel formPresentationModel) {
            fFormPresentationModel = formPresentationModel;
        }
     
        public ULCComponent getPane() {
            if (fFormLayout == null) {
                createForm();
                fBinding = new Binding(fFormPresentationModel);
                fBinding.bindText(PERSON_NAME, fName);
                fBinding.bindText(PERSON_FIRST_NAME, fFirstName);
            }
            return fFormPane;
        }
     
        private ULCBoxPane createForm() {
            if (fFormLayout == null) {
                fFormLayout = new FormLayout(FormLayout.NULL_RESOURCE_RESOLVER, "PersonForm");
                fName = new ULCTextField(20);
                fFirstName = new ULCTextField(20);
                fFormLayout.addComponent("Name", PERSON_NAME, "Name:", fName, true, "1EE");
                fFormLayout.addComponent("FirstName", PERSON_FIRST_NAME, "First Name:", fFirstName, "1EE");
                fFormPane = new ULCBoxPane(true);
                fFormPane.add("et", fFormLayout.getPane());
            }
            return fFormPane;
        }
     
        public void update(String property, Object oldValue, Object newValue) {
           if (property.equals(LOADED)) {
                fFirstName.requestFocus();
                fLoadButton.setEnabled(!(Boolean)newValue);
            } else if (property.equals(FOCUS)) {
                ULCComponent component = fFormLayout.getComponent((String)newValue);
                if (component != null) {
                    component.requestFocus();
                }
            } else if (property.equals(ERROR_LIST)) {
                ErrorList errorList = (ErrorList)newValue;
                for (at.diefaehre.argo.util.validation.Error error : errorList) {
                    ULCComponent component = fFormLayout.getComponent(error.getProperty());
                    if (component != null) {
                        if (error.isError()) {
                            component.setBackground(fErrorColor);
                        } else {
                            component.setBackground(Color.white);
                        }
                    }
                }
                setFocusToFirstError(errorList);
            }
        }
     
        private void setFocusToFirstError(ErrorList errorList) {
            if (errorList.hasErrors()) {
                for (String field : new String[]{PERSON_FIRST_NAME, PERSON_LAST_NAME, PERSON_UNIVERSITY_ID}) {
                    if (errorList.containsError(field)) {
                        ULCComponent component = fFormLayout.getComponent(field);
                        if (component != null) {
                            component.requestFocus();
                            break;
                        }
                    }
                }
            }
        }
    }

    Now, what does it take to add undo/redo to this example? As mentioned before, the abstract base class for the presentation model already contains generic undo/redo support. All we have to do is offering undo or redo in the user interface. I simply had to add two additional buttons for that, which call undo resp. redo on the presentation model. In addition, the view has to enable or disable the undo/redo buttons if undo/redo is possible or not. The abstract presentation model triggers this event conveniently. The extensions to the presentation model are minimal. It has to reset undo/redo when loading or saving the business object and it sets the focus in the view to the component which was affected by undo/redo.

    How does the presentation model fit into an application which needs to render live data. Actually, the presentation model can also handle this scenario quite nicely. There is only one issue to consider. The data feed can be considered as yet another model which the presentation model can subscribe to. Thereby the presentation model is notified about any relevant model changes. However, these model events most likely occur outside of the UI event thread (e.g. posted by some server) and therefore they cannot be processed synchronously by the presentation model which runs in the UI event thread. The solution is quite simple. The presentation model stores these events in a queue which is processed prior to the next event that occurs in the event thread, i.e. the next event that is going to be processed synchronously. While processing the asynchronous model events the undo/redo recording has to be temporarily suspended since these events are not created by the user and therefore undo/redo is pointless.

    The presentation model framework is available Presentation Model Framework. It solves many design issues in rich user interfaces and also helps developers to focus on implementing cool and ergonomic user interfaces rather than dealing with design and infrastructure issues. The framework is also independent of the user interface component library. The only exception are the table and tree model adapter classes which are specific to the ULC component library. It should be pretty simple to replace them with an implementation for the user interface component library of your own liking. Also included in the download are a number of examples which demonstrate how to use the presentation model framework. These examples were implemented with the ULC component library. In order to compile and run them you also need to download the ULC component library. You can get a free evaluation license for ULC here. Additionally, the examples need some infrastructure code (e.g. binding, form layout and validation support) which comes with the download. This infrastructure code has been extracted from a larger project and stripped down to minimize dependencies. Hence, they do not really serve as an example.

    In the last chapter we will have a look at additional infrastructure which even more simplifies implementing rich user interfaces.

    Part 1: MVC and the Brave New World of RIA
    Part 2: The World Needs More Models
    Part 3: A Simple View on Complex Stuff
    Part 4: Hierarchies
    Part 5: Presentation Model Framework
    Part 6: What’s Needed Besides the Presentation Model


    Hierarchies

    February 26th, 2008

    Canoo’s CTO Bruno Schäffer is speaking at SD West 08 on “Design Patterns for Rich Internet Applications”.

    SD West 08

    The following blog post outlines some of the concepts that he will cover in his talk. This is part four of a series of blog posts:

    As we have seen in the previous posts of this blog post series, the presentation model clearly assigns responsibilities within the presentation layer. For simple user interfaces this approach is more than good enough. However, simple user interfaces are not really the domain of Rich Internet Applications (RIA). How can we tackle complex user interfaces using the presentation model approach? Let’s have a look at a non-trivial user interface:

    Screenshot

    It shows a typical master-detail view, further enhanced by a tree navigation on the left-hand side. The user can select different aspects of a person in the tree which brings up the corresponding form on the right hand side.
    A naïve approach would be to create a single presentation model for the entire view. While implementing the presentation model you will soon realize that there is just too much state and behaviour to be captured in a single presentation model.

    If a view is too complex, we have to split it up into manageable sub-views, each with a presentation model of its own. The combination of sub-view with its presentation model is called “application component”. An application component communicates with its environment only via the presentation model, i.e. the presentation model acts as an observer to other application components (resp. their presentation models).

    A complex user interface can now be decomposed into a number of fairly independent application components. Independence means, that these application components can be employed or reused in different contexts. Independence is facilitated by relying on the observer pattern for communication with other application components.
    How do you build a complex user interface from a set of application components. You simply arrange the application components in a hierarchy. Each application component is responsible for the creation of all directly known application components. Views and presentation models have to be aware of this hierarchy. An abstract base class for view resp. presentation model can factorize this.

    The component hierarchy for our example user interface shown above looks like this:

    Component hierarchy

    Views are marked red and presentation models are blue.

    As you can see not every view needs to come with a presentation model of its own. In this case the form view hooks up to the presentation model of the navigation view. A change in the tree selection will be broadcasted by the navigation presentation model. The form view updates itself accordingly by bringing the corresponding view to the front.

    In addition, application components are perfect candidates for testing. Each application component can be tested independently (as described in part three). Testing a user interface made up from a hierarchy of application components can be considered as integration testing. It still focuses on the behaviour of the presentation models, though. An integration test case first creates the presentation model hierarchy and then tests the behaviour of the model hierarchy. The view code in this hierarchy is still trivial and therefore rarely need dedicated test cases.

    Application components have another advantage. They are perfect candidates to be assigned as an independent task to a developer.

    There are still some challenges left, such as clean initialization for presentation models and views when creating a hierarchy of application components or distribution of update events in this hierarchy without ending up in infinite update cycles.

    In the next blog post, we will have a look at a simple framework which supports building user interfaces with application components. We will also see how easy it is to generically add undo/redo to an application.

    Part 1: MVC and the Brave New World of RIA
    Part 2: The World Needs More Models
    Part 3: A Simple View on Complex Stuff
    Part 4: Hierarchies
    Part 5: Presentation Model Framework
    Part 6: What’s Needed Besides the Presentation Model


    A Simple View on Complex Stuff

    February 11th, 2008

    Canoo’s CTO Bruno Schäffer is speaking at SD West 08 on “Design Patterns for Rich Internet Applications”.

    SD West 08

     

    The following blog post outlines some of the concepts that he will cover in his talk. This is part three of a series of blog posts:

    So far we discussed the deficiencies of plain MVC for complex user interfaces and how the presentation model approach can remedy this situation. The presentation model assumes most of the former responsibilities of the view/controller pair. What remains for the view/controller pair? Frankly spoken, not much:

    • The view is responsible to create the user interface components and arrange them in a layout.
    • All relevant events triggered by the user interface components are redirected to the appropriate methods of the presentation model
    • The view is an observer of the presentation model. It has to react to the relevant changes to the presentation model and update the user interface accordingly.

    Creating the user interface (besides design and ergonomical aspects) is trivial but cumbersome to code. However, we have the opportunity to employ some markup language for specifiying the UI. Markup language are not really suited to specify presentation logic, but since this is coded in the presentation model, views can easily be built this way. Examples for UI markup languages are SwiXml , ULC XML or XUL.

    Redirecting events to the presentation model and reacting to changes of the presentation model is also pretty straightforward in most cases. The standard scenarios can be covered by generic infrastructure known as binding. I will discuss some aspects of binding in a later blog post.

    Now let us have a look at a simple example to illustrate the concepts discussed so far.The example is based on the ULC component library, but the basic concepts can easily be transfered to most common component libraries. Here is a screenshot of the application to show what it looks like:

    Screenshot showing a simple view

    The application allows a user to load a record into the form, edit it and save it. There are two business objects involved, pertaining to the person and university. The presentation logic is simple: first name and last name must not be empty and the university id must relate to an existing university record. Validation is immediate, e.g. if the user enters the university id the university name field will be updated immediately. The presentation model captures the necessary state and logic. Below you can see the implementation stripped down to the properties personName and personFirstName (the observer infrastructure is left out too). It is fairly simple: since the presentation model is a Java Bean, we need to provide setters and getters which map to the person object referenced by the presentation model. The property personName has only a getter since it is a read only property. The setter validates the property and updates the errorList property accordingly.


    public class SimpleFormPresentationModel {
        private Person fPerson;
        private ErrorList fErrorList;
     
        public final static String PERSON_NAME = "personName";
        public final static String PERSON_FIRST_NAME = "personFirstName";
        public final static String ERROR_LIST = "errorList";
     
        public SimpleFormPresentationModel() {
            fireAllPropertiesChanged();
        }
     
        public String getPersonFirstName() {
            return getPerson().getFirstName();
        }
     
        public void setPersonFirstName(String firstName) {
            getPerson().setFirstName(firstName);
            validate(PERSON_FIRST_NAME);
            firePropertyChanged(PERSON_NAME, getPersonName(getPerson()));
        }
     
        public String getPersonName(Person person) {
            return person != null ? person.getFirstName() + " " + person.getLastName() : "";
        }
    }

    The view class is pretty straightforward. Basically, it creates the UI, hooks up the UI components to the presentation model and reacts to the changes of the presentation model. The implementation uses the UltraLightClient component library. The stripped down view class (incl. some convenience methods) looks like this:

    public class SimpleFormPane implements IPropertyChangeListener {
        private ULCBoxPane fFormPane;
        private ULCTextField fName;
        private ULCTextField fFirstName;
        private SimpleFormPresentationModel fFormPresentationModel;
        private Color fErrorColor = new Color(255, 0, 0, 192);
     
        private static final String[] UI_FIELDS = new String[]{"firstName"};
     
        public SimpleFormPane(SimpleFormPresentationModel formPresentationModel) {
            fFormPresentationModel = formPresentationModel;
        }
     
        public ULCComponent getPane() {
            if (fFormPane == null) {
                fFormPane = createForm();
                fFormPresentationModel.addPropertyChangeListener(PERSON_NAME, this);
                fFormPresentationModel.addPropertyChangeListener(PERSON_FIRST_NAME, this);
                addValueChangedListener(PERSON_FIRST_NAME, fFirstName);
            }
            return fFormPane;
        }
     
        private void addValueChangedListener(final String property, final ULCTextComponent textComponent) {
            textComponent.addValueChangedListener(new IValueChangedListener() {
                public void valueChanged(ValueChangedEvent event) {
                    if (textComponent instanceof ULCTextField && ((ULCTextField)textComponent).getDataType() != null)  {
                        fFormPresentationModel.setProperty(property, ((ULCTextField)textComponent).getValue());
                    } else {
                        fFormPresentationModel.setProperty(property, textComponent.getText());
                    }
                }
            });
        }
     
        private ULCBoxPane createForm() {
            ULCBoxPane boxPane = new ULCBoxPane(2, 1, 5, 5);
            boxPane.add(2, "cc", new ULCLabel(HTMLUtilities.convertToHtml("<strong>Person Data</strong>")));
     
            boxPane.add("rc", new ULCLabel("Name:"));
            fName = new ULCTextField();
            fName.setEnabled(false);
            boxPane.add("ec", fName);
     
            boxPane.add("rc", new ULCLabel("First Name:"));
            fFirstName = new ULCTextField();
            boxPane.add("ec", fFirstName);
     
            boxPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
            return boxPane;
        }
     
        public void update(String property, Object oldValue, Object newValue) {
            if (property.equals(PERSON_NAME)) {
                fName.setText((String)newValue);
            } else if (property.equals(PERSON_FIRST_NAME)) {
                fFirstName.setText(((String)newValue));
            } else if (property.equals(ERROR_LIST)) {
                ErrorList errorList = (ErrorList)newValue;
                    for (at.diefaehre.argo.pm.util.Error error : errorList) {
                    ULCComponent component = getComponent(error.getProperty());
                    if (component != null) {
                        if (error.isError()) {
                            component.setBackground(fErrorColor);
                        } else {
                            component.setBackground(Color.white);
                        }
                    }
                }
                setFocusToFirstError(errorList);
            }
        }
     
        private void setFocusToFirstError(ErrorList errorList) {
            for (String field : UI_FIELDS) {
                if (errorList.containsError(field)) {
                    ULCComponent component = getComponent(field);
                    if (component != null) {
                        component.requestFocus();
                        break;
                    }
                }
            }
        }
     
        private ULCComponent getComponent(String name) {
            ULCComponent component = null;
            try {
                component = (ULCComponent)PropertyUtils.getProperty(this, name);
            } catch (Exception e) {
            }
            return component;
        }
     
        public ULCTextField getName() {
            return fName;
        }
     
        public ULCTextField getFirstName() {
            return fFirstName;
        }
    }

    What would test cases for this simple scenario look like? The view contains no real logic and therefore we do not need to write any test cases. However, we should make sure that the presentation model updates its properties correctly (incl. validation) and triggers the appropriate update events. Tests for our presentation model could look like this:


    @Test
    public void testValidFirstName() {
        attachPropertyChangeRecorder(fPresentationModel);
        fPresentationModel.setPerson(Service.getService().getPersonById(1));
        fPresentationModel.setProperty(PERSON_FIRST_NAME, "Bruno");
        assertFalse(fErrorList.hasErrors());
        testPropertyChangeMap(PERSON_NAME, PERSON_FIRST_NAME, ERROR_LIST);
    }
     
    @Test
    public void testInvalidFirstName() {
        attachPropertyChangeRecorder(fPresentationModel);
        fPresentationModel.setPerson(Service.getService().getPersonById(1));
        fPresentationModel.setProperty(PERSON_FIRST_NAME, "");
        assertTrue(fErrorList.hasErrors());
        assertEquals("firstName", fErrorList.getError().getProperty());
        assertEquals(1, fErrorList.getError().getErrorNr());
        testPropertyChangeMap(PERSON_NAME, PERSON_FIRST_NAME, ERROR_LIST);
    }

    The first test case starts with attaching a person to the presentation model and then sets the personFirstName property. There are two checks: one whether no errors have been produced and the other checks whether all expected update events have been triggered. For this an event recorder is attached (attachPropertyChangeRecorder()) and testPropertyChangeMap verifies the expected update events.

    As shown above, this blog post looked at simple views and how they are implemented with a presentation model running underneath. The above example demonstrated the concepts introduced so far. Obviously, there are still some drawbacks to this simple approach. It will not easily scale to more complex user interfaces (e.g. a master detail view with tabbed forms) and contains quite a lot of repetitive code. In the next blog post, we will investigate how more complex user interfaces can be tackled.

    Part 1: MVC and the Brave New World of RIA
    Part 2: The World Needs More Models
    Part 3: A Simple View on Complex Stuff
    Part 4: Hierarchies
    Part 5: Presentation Model Framework
    Part 6: What’s Needed Besides the Presentation Model


    The World Needs More Models

    February 1st, 2008

    Canoo’s CTO Bruno Schäffer is speaking at SD West 08 on “Design Patterns for Rich Internet Applications”.

    SD West 08

    The following blog post outlines some of the concepts that he will cover in his talk. This is part two of a series of blog posts:

    In part one we discussed why plain MVC is not suited for Rich Internet Applications. The presentation model extends MVC to better fit the needs of applications with complex presentation logic. Martin Fowler first described the basic idea of this approach. The presentation model inserts an additional model between the business model (i.e. business object) and the view-controller duo. It captures the state of the user interface and handles the presentation logic. The business object is not directly accessible to the view anymore. The presentation model offers only those business object properties to the view that are relevant to rendering the user interface. The presentation model may map the properties of several business objects. If the business object does not serve as the model in MVC, it does not need to provide any observer infrastructure and can stay a real POJO.
    In traditional MVC you have either equip the business object with some observer infrastructure, employ some kind of decorator for the business object which handles view notifications (e.g. a dynamic proxy) or define an aspect.

    illustration.jpg

    What state must be captured by the presentation model? Basically, it is the entire mutable state of the user interface. For example, the mutable state of a checkbox is whether it is

    • selected/not selected,
    • and enabled/not enabled

    (visibility might be another relevant state). The background color of a checkbox is not relevant to most UIs and hence not a mutable property which needs to be captured by the presentation model. Complex state such as a table model or tree model can easily be delegated to a sub-presentation model. Common UI toolkits provide default implementations for these models so there is no need to re-implement them in the presentation model.
    Now, how does the view react to changes in the presentation model? It is pretty simple: the presentation model is fully observable and the view gets notified of the changes by the observer pattern. This approach can even cover non-trivial scenarios, such as the following one:

    Screenshot

    The user just selected a different row in the table and the user interface has now ask the user whether any modifications should be saved. Changing the selection state is a responsibility of the presentation model. However, the presentation model is not supposed to directly pop up a dialog, but it can trigger an update event and the responsible view will react to that by displaying the dialog. The action buttons in the dialog will then call the appropriate methods in the presentation model.

    The observer pattern not only provides broadcast communication among classes but it also helps to decouple classes. On the other hand, one has to be aware of its drawbacks. In languages with static type checking it may circumvent the type checking by relying on a generic update method. Debugging also tends to be harder since one has to step through the observer infrastructure. In addition, trying to understand code with nested listeners (i.e. update listeners which themselves trigger update events again) is not really fun. At least try to avoid updating properties within a bean by means of the observer pattern.
    At start-up time the view needs to get the entire presentation state in order to render the initial state of the user interface. For this, the presentation model can trigger update events for all its properties.

    With the presentation model it is now clear to developers where to put all the presentation logic and therefore the implementation is more straightforward and uniform. Another big advantage is improved testability. As I mentioned in take one, automatic testing of user interfaces is expensive both at development and run-time. The presentation model substantially improves this situation. Most UI testing can be accomplished by just developing and executing unit tests on the presentation model without the need to run the user interface. These tests are way easier to implement since they only change properties of the presentation model and test properties resp. update events.

    Since the presentation model covers most of the former responsibilities – what remains to be done for the view? Part three “A Simple View on Complex Stuff” will discuss this. We will also look at a simple example. Stay tuned!

    Part 1: MVC and the Brave New World of RIA
    Part 2: The World Needs More Models
    Part 3: A Simple View on Complex Stuff
    Part 4: Hierarchies
    Part 5: Presentation Model Framework
    Part 6: What’s Needed Besides the Presentation Model


    MVC and the Brave New World of RIA

    January 28th, 2008

    Canoo’s CTO Bruno Schäffer is speaking at SD West 08 on “Design Patterns for Rich Internet Applications”.

    SD West 08

    The following blog post outlines some of the concepts that he will cover in his talk. This is part one of a series of blog posts:

    Rich Internet Applications pick up the ball where plain Web applications dropped it: they promise to bring the power of desktop applications to the Web. Desktop applications almost went out of fashion with the advent of Web applications. But most people still prefer the rich user interface (UI) and interactivity of desktop applications such as Outlook compared to their Web-based siblings such as GMail and Yahoo! Mail. In many cases the convenience of ubiquity compensates for the inferior or cumbersome user interface.

    MVC diagram

    Client-server applications with rich user interfaces first emerged at the beginning of the nineties. Usually implemented in C++ or Smalltalk, they followed a fat-client approach, the predominant client-server architecture at this time. The principal way to organize the presentation layer of such applications was the MVC model. The concept was first proposed by Trygve Reenskaug (see http://heim.ifi.uio.no/~trygver/2007/MVC_Originals.pdf) for the Smalltalk environment. As with any proven object-oriented design, MVC splits up the responsibilities of a user interface component into domain data (Model), rendering (View), and event handling (Controller). Quite often, view and controller are merged together, though.

    Today’s GUI component libraries still make use of MVC. For example, most non-trivial UI components in Swing employ some sort of MVC. However, if one tries to apply MVC to complex (form-based) applications, which is typical for desktop or Rich Internet Applications, experience shows that criteria such as clean design, maintainability, or reusability cannot be met. There are several reasons:

    1. What is the model of a form based application with a rich UI? Most developers point to the business object to be rendered in the form as the model. A form-based RIA has more model states than just the business object, though. This additional state is usually kept in the view class and increases the complexity of the view.
    2. The presentation logic of a Rich Internet Application is vastly more complex compared to a traditional Web application. The presentation logic has to deal with more events caused by extended interactivity. Another feature of RIAs is an up-to-date rendering of the presentation state. For example, UI components may be enabled/disabled or visible/invisible depending on the state of the application. This is also part of the additional model state as mentioned above. On top of that, RIAs feature instant validation (without interrupting a user’s flow of work by throwing a modal dialog into their face). This “silent” validation has to be handled (at least partly) by the presentation logic as well. Naïve design puts all of these aspects into the view class. As a result, the view class becomes overly complex, hardly reusable, and difficult to maintain.
    3. Automated testing of such view classes can only be accomplished by running the user interface. Tests are executed by triggering user events through a test tool or accessing the components through a library (e.g. Jemmy for Swing component library). This way of testing is slow and fragile: running hundreds or thousands of UI tests takes quite some time and changes to the user interface are likely to break the tests resulting in false negatives.

    As a company specializing in RIA, we have witnessed quite a few transitions from plain ugly Web applications to the brave new world of RIA. Some of our observations:

    • Typical Web developers have not heard of MVC and try to design RIAs like they would design a typical HTML application.
    • Seasoned developers who may have had some experience with fat client-server applications try to apply MVC concepts in the same way that they did in the nineties, without adapting to the new scenario.

    Both approaches have their weaknesses and lead to poor results. In part two of this blog post series – “The world needs more models” – we will discuss possible remedies to this situation.

    Part 1: MVC and the Brave New World of RIA
    Part 2: The World Needs More Models
    Part 3: A Simple View on Complex Stuff
    Part 4: Hierarchies
    Part 5: Presentation Model Framework
    Part 6: What’s Needed Besides the Presentation Model