public interface ComponentXML
By allowing you to keep layout information and property settings in an XML format, Component XML enables non-developers to build and maintain portions of your application, either by editing screens within Reify or by directly editing the XML itself.
Unlike the similar GWT "UIBinder" technology, Component XML does not require a compilation step. XML screen definitions can be generated on the fly, modified at runtime, stored in a database, and in all other ways treated as a dynamic resource. See the section "Dynamic Component XML" for details.
To create a Smart GWT component in XML code, you create a tag with the component's class name. You can set that component's properties either as tag attributes:
    <Button title="Click me" width="200" />
  
  or in nested tags:
  
    <Button> 
      <title>Click me</title>
      <width>200</width>
    </Button> 
  
  
  To set a property that is an Array of simple types (like int, or String), repeat tags like
 so (for DynamicForm.colWidths):
  
  <DynamicForm>
      <numCols>2</numCols>
      <colWidths>250</colWidths>
      <colWidths>*</colWidths>
  </DynamicForm>
  
  To set a property that takes an Array of complex objects, use the property name as a
  container tag, then create further nested tags for the objects in the array, like so (for
  ListGrid.fields):
  
  <ListGrid>
      <fields>
          <ListGridField name="accountName" ... />
          <ListGridField name="accountType" ... />
      </fields>
  </ListGrid>
  
  This same approach works for creating nested layouts, such as placing a ListGrid in a VLayout:
  <VLayout>
      <members>
          <ListGrid .. />
      </members>
  <VLayout>
  
  Referring to previously defined components
To refer to another component by ID in XML, use <Canvas ref=/>. For example:
  <Canvas ID="myCanvas"/>
  <Canvas ID="myCanvas2"/>
  <VLayout>
      <members>
          <Canvas ref="myCanvas"/>
          <Canvas ref="myCanvas2"/>
      </members>
  </VLayout>
  
  
  Save your Component XML as a file called screenName.ui.xml under
  webroot/shared/ui/.  Placing your .ui.xml file in this directory makes it visible to
 the system; the location of this directory can be configured in server.properties
  by setting
  the project.ui property.  screenName can be any valid identifier (no spaces,
  dashes or periods - underscores OK).
  
If you have multiple top-level tags (eg, your code is similar to the example above under "Referring to previousy defined components") use <isomorphicXML> as a top-level container tag - this has no impact on processing and is just an idiom to make your file valid XML, since XML does not allow multiple top-level tags in a document.
  Component XML screens are then loaded using the ScreenLoaderServlet.  The default SDK comes
  with this servlet already registered at 
  
  projectBase/sc/screenLoader.  If you've modified web.xml
  or only included some of the default servlets, you may need to add it now - see the 
  
  Installation Instructions.
  
To create an application that consists of just the imported mockup, just add a <script src> tag pointing to the ScreenLoader servlet and referring to the screenName you used when you saved your file. For example, add the following to your bootstrap .html file:
     <script src="sc/screenLoader?screenName=screenName"></script>
  
  
  If you want to load screens dynamically, or if you want to load more than one screen, use
 RPCManager.loadScreen().  See the section
 on "Multiple screens and global IDs"
  below.
  
  You can retrieve the components in your loaded screen in order to add event handlers to
  them, call APIs on them, place them into layouts you programmatically create, and in general
 add dynamic behavior.  Retrieve the components via the Canvas.getById() API
  (note, when working with multiple screens, be sure to see the upcoming section about managing
  global IDs).
  
You can then add event handlers normally. For example, say there is a ListGrid with ID "mainGrid" and a DynamicForm with ID "editForm" in the same screen, and you want to populate the form with whatever record is clicked on in the grid:
    ListGrid grid = (ListGrid)Canvas.getById("mainGrid");
    final DynamicForm form = (DynamicForm)Canvas.getById("editForm");
    grid.addRecordClickHandler(new RecordClickHandler() {
        public void onRecordClick(RecordClickEvent event) {
            form.editRecord(event.getRecord());  
        }
    });
  
  
  
  You can also add a loaded screen to an existing layout container.  For example, perhaps you've
 already written parts of the application via normal coding techniques, and now you want to take
  a screen defined in Component XML and place it in a particular Layout you've already created
 ("existingLayout" below) - just use Layout.addMember() as usual:
  
  
     existingLayout.addMember(Canvas.getById("componentId"));
  
  
  
 Component XML files can also refer to components you have created programmatically, and
 incorporate
 them into layouts.  For example, if you have created a ListGrid component with ID "theGrid",
 you could
 refer to that grid using a <Canvas ref=""/> tag, which can be used anywhere
 a
  Canvas is expected.  For example:
  
  <VLayout ... >
      <members>
            <Canvas ref="theGrid"/>
      </members>
  </VLayout>
  
  Note that this approach requires that the referenced component has been created before
  loadScreen is called.
  
  Component XML files can declare Actions to take in response to events.  An 
  Action is a declarative method call on this or some other component, with or 
  without parameters.  Being declarative, actions have some advantages over procedural code:
  they make your application easier to understand and easier to maintain, and they allow 
  tools such as Reify to understand and edit your event handling logic.
  
  To take a simple example, this is how you would declare an Action to display
 a record in a DetailViewer when that record is
 clicked in a ListGrid.
  
    <ListGrid dataSource="Customer" autoID="customerGrid">
       ...
      <recordClick>
        <Action target="customerDetailGrid" name="viewSelectedData" mapping="viewer"/>
      </recordClick>
    </ListGrid>
  
  The three elements of this declaration:target and name are both required attributes of any
 Action,
  and they must be valid.  If target does not refer to a valid component, or 
  name is not the name of a valid method on that component, you will generate a 
  runtime error.  Note, the rules around describing valid actions in the 
 Declaring Events and Actions section of the ComponentSchema 
  article apply to Reify only.  When building applications through Reify,
  only methods marked action="true" will appear in the list of valid actions for
  a given target component.  However, any documented method can be called as an 
  Action in manually-created Component XML, as can any registered 
  string method,
  
 Event handlers can also invoke workflow
 processes, which are a special
  kind of multi-step Action.  You specify a workflow process like this (see the
 Process documentation for details of what
 goes inside the 
  <Process> tag)
  
    <ListGrid dataSource="Customer" autoID="customerGrid">
       ...
      <recordClick>
        <Process>
           ...
        </Process>
      </recordClick>
    </ListGrid>
  
  
  Finally, you are not limited to one Action per event: you can declare any 
  number of Actions and/or Processes inside an event handler 
  declaration.
  
  Parameters are defined in an Action declaration in the mapping
  attribute.  This attribute is optional; if the target action method does not require 
  parameters, this attribute can be omitted.  If provided, mapping should be a
  comma-separated list of values.  Each of these values is either:
this, which is a reference to the source component 
      (ie, the component upon which the Action is being defined)new Date()Actions
  are declared inside event handler declarations that correspond to Smart GWT event methods.
  These methods are passed parameters, and these parameters are available, 
  via the mapping, to any contained Action.  Providing the correct
  mapping requires that you know the name of the parameter you are interested in, and this 
  information is present in the documentation.
  
  To take the above example, we want to call viewSelectedData() on the
  DetailViewer, so looking at the documentation for 
 DetailViewer.viewSelectedData(), we can see that it takes a single parameter of 
 type ListGrid or TileGrid, or the ID of a ListGrid
  or TileGrid.  This parameter tells the DetailViewer which 
  component's selected data to show, so we want to pass in the ListGrid itself,
  the component we are declaring this Action on.
  
  One way to do this would be to use a mapping of "this".  As you can see from 
  the example above, though, there is another way.  If we look at the documentation for the 
 event method wrapping our Action - ListGrid.recordClick() - we will see
  that it is passed a number of parameters, the first of which is a pointer to the 
  ListGrid itself.  As the documentation shows, this parameter is called "viewer".
  Therefore, we can use a mapping of "viewer".  If we were declaring an 
 Action to call a method that requires a Record
 parameter, we can
  look at the documentation for recordClick() again and note that it is also 
  passed the record just clicked, in a parameter called record.  So our mapping 
  for that Action would be "record".
  
  
  A Component XML screen created in Reify or via the
 Balsamiq importer will assign global IDs to all
 components
  generated from your mockup so that you can retrieve them by ID to add event handlers and
  call APIs.   However if you build an application out of multiple screens built at different
  times, these IDs can collide, which will cause components to overwrite each other as they
  each try to use the same ID.
  
 To solve this, the RPCManager.loadScreen() API will ignore global IDs on loaded
  components, assigning them sequential generated IDs instead (which will never collide). 
  Instead of using global IDs, the callback for loadScreen() will automatically provide
  you with the outermost component of a loaded screen, and that outermost component will
 provide access to other components by their original IDs via Canvas.getByLocalId().
  
This allows you to add loaded screens to existing layouts, attach event handlers and take other programmatic actions, all without ever establishing global IDs.
  A typical application that uses screens stored in Component XML will have several such
 screens, or in some cases, hundreds or thousands.  RPCManager.cacheScreens() can be
  used to load a set of screen definitions without actually creating any UI components - a
 subsequent call to RPCManager.createScreen() is used to actually create the screen
  when needed.  These two APIs provide the same global ID management facilities as
  loadScreen().
  
 As discussed in the Smart GWT Architecture
 overview, screen
  definitions are typically very small, and should be loaded entirely up front or in very
  large batches.  Further, screen definitions have essentially negligible runtime
  overhead until the screen is actually created.
  
Therefore, use the following best practices for screen loading, even if you have very few or only one screen defined in Component XML:
RPCManager.cacheScreens()
  RPCManager.createScreen().
  cacheScreens(), loading sets of screens that are likely to be used
       together.
  
  Components can be dynamically provided on the server side by using the API defined in
 ScreenLoaderServlet.addDynamicScreenGenerator()
 which allows adding DynamicScreenGenerators to the system for providing the .ui.xml files on
 the fly:
  
  ScreenLoaderServlet.addDynamicScreenGenerator(new DynamicScreenGenerator() {
       public String getScreen(String id) {
 
         if (id.equals("testDynamicScreenPrefix3")) {
             return null;
         }
 
         id=id.replace("testDynamicScreen","");
         return "
  
 Whenever the system needs a screen in future, it will first call the registered
 DynamicScreenGenerator's
  getScreen(String) method for providing the given screen; Only if all queried 
 DynamicScreenGenerators returns null, will proceed to use the normal system for
 obtaining 
  the screen instances.
  
NOTE:
In the provided example we register a DynamicScreenGenerator which will be called for each screen the system tries to load, if it starts with "testDynamicScreenPrefix", except the screen with id "testDynamicScreenPrefix3" for which we return null.
While registering a DynamicScreenGenerator is the first choice since is compatible with ScreenLoaderServlet's ability to load several screens in a single HTTPRequest, there are two additional ways to load Component XML screens - you can create a .jsp that uses the JSP tags that come with the SDK:
     <%@ taglib uri="http://www.smartclient.com/taglib" prefix="isomorphic" %>
     <isomorphic:XML>
        ... Component XML ...
     </isomorphic:XML>
  
  Or you can use the server-side API com.isomorphic.XML.toJS():
      XML.toJS("<isomorphicXML xmlns:xsi=\"nativeType\">" +
                   componentXMLCode +                                 
                   "</isomorphicXML>");
  
  However these two approaches will allow to only load one screen at a time.
  The JSP code above and the programmatic call to XML.toJS() both return a JavaScript code,
 which is the response that RPCManager.loadScreen() expects.  The
  XML.toJS() API can be easily combined with 
 direct use of the server-side
 DataSource API to build
  a version of the ScreenLoaderServlet that can retrieve Component XML from a database
  or any Java API.
  
  For static Component XML screens (cannot be changed at runtime), you can optionally run the
  XML.toJS() process as a build step to save a small amount of runtime overhead in XML to JS
 translation.  Use RPCManager.loadScreen()
 to load the resulting JavaScript by
 overriding the RPCRequest.actionURL to
 point to the generated JavaScript file.
  Note that the overhead is minor enough that this is not worth doing unless you have a very
  large deployment and a very large number of static Component XML files.
  
XML parsing errors, which happen when XML is not well-formed and would be rejected by any standard XML parser, are reported in the server-side log, and, when possible, also in the client-side log within the "Results" tab of the Developer Console.
 If you are loading a screen via the RPCManager.loadScreen() API, you can see the
  response from the server in the RPC tab of the Developer Console - this will show you issues
  such as a misplaced ScreenLoaderServlet (HTTP response code will be 404 - Not Found) or
  responses that contain server exception details instead of the expected JavaScript response.
  
You can also use the "Eval XML" section in the "Results" tab of the Developer Console to interactively experiment with Component XML ("Eval XML" button) and as a means of seeing the generated JavaScript ("Show JS" button).
  Component XML files support embedding references to messages loaded from ResourceBundles via
  the same JSTL-like <fmt> syntax as is used for DataSource .ds.xml files.  See
  DataSource localization for details.
  
 If you define a new component class com.mycompany.MyListGrid which is a subclass
 of the
 built-in component ListGrid, and you register your class for reflection,
  you can create it in XML as shown below:
  
     <ListGrid constructor="com.mycompany.MyListGrid" width="500"/>
  
  
  By using the <ListGrid> tag you advertise that properties should be interpreted 
  as ListGrid properties.  By specifying constructor
  you tell SmartGWT what class to create. 
  
  Your custom component (e.g. com.mycompany.MyListGrid) may have additional
  properties which are not present in the standard superclass (e.g. ListGrid).
  You can set such properties in XML as if they were pre-defined properties:
  
     <ListGrid constructor="com.mycompany.MyListGrid" myProperty="false"/>
  
  
  In this case, the BeanFactory code
  will ultimately call MyListGrid.setMyProperty(false); in order
  to set the property. Since BeanFactory knows that the property
  takes a boolean, it will automatically convert the string value "false" to a
  boolean, using the type conversions described below.
  
Instead of relying on the automatic type conversions, you can force a property to be interpreted as a given type by using the "xsi:type" attribute:
  <ListGrid>
      <constructor>com.mycompany.MyListGrid</constructor>
      <myProperty xsi:type="xsd:boolean">false</myProperty>
  </ListGrid>
  
  
  The same notation works when you want to declare that an entire subobject has a given type.
  For example, this would cause the custom property "myListGrid" to have a live
 ListGrid instance as its value.  All of the properties
 on the <myListGrid> tag
  will be correctly interpreted as ListGrid properties and have the correct types.
  
  <Canvas>
      <myListGrid xsi:type="ListGrid" width="500" height="600"/>
  </Canvas>
  
  For your reference: "xsi" stands for "XML Schema Instance"; this notation derives from XML Schema standards for explicitly specifying type inline.
  Instead of using the constructor and xsi:type attributes for
 custom components and custom properties, you can create a ComponentSchema that
  describes the custom component.  Declaring a component schema allows you to use your
  component just like the built-in SmartGWT components, and also allows your component to
  be used within Reify.
  
  The BeanFactory code
  uses a reflection-like mechanism to discern the type which a SmartGWT
  property requires, and automatically
  converts supplied values to the required type when possible. In cases where
  conversion is impossible, an IllegalArgumentException is
  thrown.
  
Where the setter for a property takes a primitive type (boolean, double, float, int, or long), any "null" value supplied will be converted to 0 (for the numeric types) or false (for boolean). Conversely, if the setter takes the boxed version of the type (Boolean, Double, etc.), any primitive value supplied will be auto-boxed. Note that byte, short and char properties are not currently handled.
  Properties which take numeric types will convert other numeric
  types, as well as strings, using standard Java APIs (e.g.
  Integer.valueOf()).  Boolean "true" will be converted to 1, and false to 0.
  If the supplied value cannot be converted to the numeric type, an
  IllegalArgumentException will be thrown.
  
  Properties which take a Date type will convert from strings using
  DateUtil.parseInput(String).
  
 Properties which take Enum types will convert from strings using
 Enum.valueOf().
  However, any dashes ("-") in the string will be converted to underscores, and
  the string will be converted to upper-case if necessary. If the string does not match
  one of the Enum values, an IllegalArgumentException will be thrown.
  
Properties which take Array types will convert arrays where the individual values can be converted to the appropriate type. If a single value is supplied, it will be wrapped in an array.