New in Ext GWT 3.0

JavaScript libraries Ext JS and Ext GWT are known, among other things, for one of the best sets of visual components - both in design and cross-browser compatibility, and in stability. Therefore, the hands themselves are drawn to any project on GWT to add Ext and replace boring Google widgets with nice shapes and windows.

However, the integration of Ext GWT and GWT still left much to be desired - in fact, the second version of Ext GWT completely supersedes all means of compiling the GWT interface, offering its own APIs for everything, including event processing. Therefore, for the third version of the library, now available as developer preview, Sencha developers are actively rewriting the Ext JS scripting legacy using GWT's patterns and idioms. The main expected advantage is a more correct integration with GWT and, as a result, a more compact and optimized interface code: JavaScript and CSS are generated and obfuscated at the stage of GWT compilation using the deferred binding mechanism, which eliminates code fragments that are not used in current project.

Implement widgets using Appearance


One of the patterns adopted from GWT is Appearance, which allows you to select a widget, its layout, style and connecting logic into independent and replaceable parts. This approach allows you to easily change the styles and themes of widgets, and even their layout - for example, to use either div or button as a DOM implementation of a button. Here is the simplest example of applying the Appearance pattern to a simple div button where you can change the text and icon:

public interface Appearance {
    void render(SafeHtmlBuilder sb);
    void onUpdateText(XElement parent, String text);
    void onUpdateIcon(XElement parent, Image icon);
}
public static class DefaultAppearance implements Appearance {
    public interface Style extends CssResource {
      String testButton();
      String testButtonText();
      String testButtonImage();
    }
    public interface Resources extends ClientBundle {
	  @Source("DefaultAppearance.css")
	  Style style();
    }
    public interface Template extends XTemplates {
      @XTemplate(source = "DefaultAppearance.html")
      SafeHtml template(Style style);
    }
    private final Style style;
    private final Template template;
    public DefaultAppearance() {
      this((Resources) GWT.create(Resources.class));
    }
    public DefaultAppearance(Resources resources) {
      this.style = resources.style();
      this.style.ensureInjected();
      this.template = GWT.create(Template.class);
    }
    @Override
    public void onUpdateIcon(XElement parent, Image icon) {
      XElement element = parent.selectNode("." + style.testButtonImage());
      element.removeChildren();
      element.appendChild(icon.getElement());
    }
    @Override
    public void onUpdateText(XElement parent, String text) {
      parent.selectNode("." + style.testButtonText()).setInnerText(text);
    }
    @Override
    public void render(SafeHtmlBuilder sb) {
      sb.append(template.template(style));
    }
}

The nested Style interface represents the rendering style of the component. By default, it links to the external file DefaultAppearance.css - this connection is set in the Resources interface. Finally, the third nested interface, Template, represents the layout of the component, and is connected by default to the external file DefaultAppearance.html. In the constructor of the DefaultAppearance object, you can override the implementation of the Resources interface, thereby replacing the style or theme of the component. In a similar way, you can change the Template template, or even the entire DefaultAppearance object - the widget just needs to know the simple Appearance interface to delegate to it the setting of parameters or the processing of events.

As a result, Ext GWT gives us three extension points through which we can affect the display of the widget: by changing its CSS style, HTML markup, or by completely redefining the Appearance object and the mechanism by which it interacts with the DOM to render the widget. Thanks to the Appearance pattern, all these aspects are neatly separated from each other.

JavaBean objects as data models


Finally, it will be possible to abandon the ModelData interface, in which it was necessary to wrap any JavaBean objects earlier so that they can serve as data models. In the Store and Loader, it may become possible to use any objects that are not bound by any interface contracts and do not extend specialized classes. All this is achieved through deferred binding magic - the code for accessing specific fields of the object is generated at the stage of GWT compilation. So far, there are no examples of a new API for working with repositories and bootloaders, but the innovation is demonstrated by the example of another innovation - a redesigned XTemplate template engine:

interface TemplateTest extends XTemplates {
    @XTemplate("
{name}
") SafeHtml renderCustomer(Customer customer); @XTemplate(source="template.html") SafeHtml renderCustomerExternal(Customer customer); } ... TemplateTest template = GWT.create(TemplateTest.class); SafeHtml html = template.renderCustomer(customer);

The fields of any transferred object can now be used directly in the body of the template - for example, the customer.name field is used in the above code. To test this code, I did not even have to declare any meta-interfaces - everything needed is generated magically at the compilation stage. The template itself, as can be seen from the example, can be contained either in the value string of the XTemplate annotation, or in an external file whose name is placed in the source field of the same annotation. The result of using the template is safe HTML - safe in the sense that the received SafeHtml accurately handles possible sources of XSS attacks in the transmitted fields and values.

UiBinder: declarative interface layout


Another long-awaited function is integration with UiBinder, the existing mechanism for marking up an interface with XML, which still exists with GWT 2.0. It allows you to extract the layout of components into an external XML file, making it declarative and structured and separating it from the interface logic prescribed in the Java code. Until now, UiBinder was available only for standard GWT widgets and containers, but now Ext GWT developers are actively working on integrating their own components with it. The main problem, due to which the API has not yet been completely fixed and even moved to a separate jar file, is the difficulty of setting containers using LayoutData - the current implementation of UiBinder does not allow you to write your own parsers for XML markup attributes. The developers of Ext GWT and GWT are now in the process of coordinating changes to the GWT that will make this possible.


It is easy to see that the proposed layoutData field syntax is somewhat reminiscent of CSS styles in attributes. For this mechanism to work, you need to connect the gxt-uibinder-3.0.0-SNAPSHOT.jar and uibinder-bridge-2.3.0-SNAPSHOT.jar libraries to the project. However, I must say that I did not manage to test the given example - GWT stubbornly refused to convert the layoutData contents unknown to it to the BorderLayoutData object.

Conclusion


Other minor amenities in the new version of the library include:
  • event processing mechanism unified with GWT - no listeners, standard handlers;
  • graphics translated from Flash to JavaScript - examples from the Ext GWT Explorer application available in the distribution package, as usual, impress with their lickiness and speed;
  • some simplifications in containers and layouts - LayoutContainer containers are now tightly associated with Layout layouts (RowLayoutContainer, BorderLayoutContainer, etc.), which somewhat simplifies their configuration and provides typical security.

In conclusion, I note that the current version of Ext GWT 3.0 works in conjunction with GWT 2.3.0, and requires at least Java 1.6 for successful compilation, which is also due to the requirements of GWT itself. The root package of the library has also changed - in the spirit of the recent rebranding of com.extjs, it has been replaced by com.sencha. Developers promise to release new versions of developer preview once every few weeks, however, they note that these versions only demonstrate new features and an API that has not yet been fixed, and therefore are not recommended for use in development.

References




Also popular now: