|
|
![]() |
|
|||||
|
|||||||
|
|
|||||||
Proposed UIML Change: <restructure> tagSend comments to Cara Struble (cara@harmonia.com)Authors: Marc Abrams and Cara Struble revised 23 April 2001 AbstractWith the UIML 2.0a language version, one could only describe a user interface (UI) with a static structure. Proposed here is a change which allows the UI structure to change dynamically over time.MotivationIn UIML 2.0a, the entire structure of a UI was represented in the <structure> element by enumerating a tree of <part> elements. For example, using the Java AWT/Swing vocabulary for UIML, a UI containing a window with a button and a panel is described like this:<structure> <part class="JFrame" name="F"> <part class="JButton" name="B"/> <part class="JPanel" name="A"/> </part> </structure>(Shown above is a fragment of the entire UIML file. Also needed are a <style> element to set properties like the text of the button and a <behavior> element to define the actions occuring when the button is clicked.) Suppose when the initial UI is displayed, we wanted only the button to appear. When the user clicks the button, the panel appears. In UIML 2.0a, this is achieved by setting the visible property of the panel to false initially (in the <style> element), and including a rule in the <behavior> element that changes the visible property to true upon a button click. So the general method of representing UIs in which parts appear and disappear is to set the visibility attribute to control what a user sees in the UI at any given time. While this works, there are several disadvantages for UIs containing large numbers of parts (e.g., thousands of UI parts on a few screens, or thousands of screens): The
entire set of UI parts must be known ahead of time, so that they can
be enumerated in the <structure> element of one UIML document.
A UIML renderer has no easy way of telling which UI parts are initially visible, and the lifetime of parts. ("Lifetime" means the period of time from when it is first visible to the user until the time when it is made invisible for the last time.) This presents a problem to a renderer striving for an efficient implementation that minimizes the startup delay in displaying the initial UI and minimizes memory by freeing unneeded parts. When one reads a UIML document, it can be hard to tell what parts of the UI are visible, because one must read through the <property> tags that set visibility. A rendering engine processes all UI parts in the <structure> element, even if they are never visible during a particular use of the application. This presents a problem to renderers that are interpreters and strive to minimize startup delay. (This problem can be solved with renderers that use lazy evaluation of source tags by splitting the one logical UIML document into different physical files, and using the source attribute in UIML to include the physical files in each other. [In lazy evaluation, the renderer does not read a file named in the source attribute until the element containing the source is actually needed to portray the UI.] The disadvantage is that UIML authors must be congizant of the advantages of using multiple files, when ideally the author should not have to worry about this.) Proposed ChangeChange #1: <restructure>First, the semantics of UIML are changed to include the concept of a virtual UI tree. During the lifetime of a UI, the parts comprising the UI may change. (All parts that exist but are invisible to an end user are still part of the tree.) The parts present in the UI have a hierarchical relationship, therefore forming a tree. At any moment during the UI lifetime, one could enumerate the tree of parts that currently exist, and this is the virtual UI tree. Each node in this tree corresponds to a <part> element in the UI generated by UIML. We call the tree "virtual" because it may or may not be physically represented as a data structure on a computer, depending on how a rendering engine is implemented.The initial value of the virtual UI tree is the content of the <structure> element in a UIML document. During the UI lifetime, the virtual UI tree can be modified by deleting nodes or adding nodes using the <restructure> tag. (The <restructure> tag is so-named because it modifies the <structure> section's representation in the virtual UI tree.) The <restructure> tag can only appear inside an <action> element in UIML. Syntax of <restructure>The syntax of <restructure> follows:<restructure at-part="[part-name1]" how="append|cascade|replace|delete" where="first|last|before|after" where-part="[part-name2]" source="[template-location]">The <restructure> element may not contain a body if one of the following holds: The
source attribute is present
how="delete" is present Semantics of <restructure>The semantics of <restructure> are to modify the virtual UI tree as follows:how="delete": Delete from the current virtual UI tree the subtree rooted at the part named part-name1. Also delete any properties or rules of the part. There can be no body for <restructure>. Attributes where, where-part, and source cannot be used.how="append", "cascade", "replace": Suppose the current virtual UI tree contains a part named P of class C . Then suppose an <action> element is executed containing <restructure at-part="P" how="H" where="W" where-part="WP" > with <template name="T"> inside it. The result is equivalent to the virtual tree obtained from a UIML document whose <structure> element matches the current virtual tree, and the UIML element corresponding the part P is <part name="P" class="C" source="T" how="H" where="W" where-part="WP">. In other words, the effect is as if the part P named in the at-part attribute of <restructure> named the <template> inside <restructure> in P's source attribute. Change #2: "where" AttributeThere is one additional change to UIML proposed. Each part element that contains the source attribute in UIML will also have two additional attributes:where="first|last|before|after" where-part="[part-name]"The where attribute can only be used when the source attribute is present and how="cascade" or how="append" is present. The where-part attribute can be used only when where="before" or where="after" is used. The attributes have the following semantics. Let the part element containing where be <part name="P" ...> If
attribute where="first" is present: All children
of part P in the <template> named in the source attribute
must be inserted as children of part P before the existing children.
If attribute where="last" is present: All children of the part P in <template> named in the source attribute must be inserted as children of part P after the existing children. If attribute where="before" and where=part="[part-name]" is present: All children of part P in the <template> named in the source attribute must be inserted as children of part P before the child of P with part name part-name. If attribute where="after" and where=part="[part-name]" is present: All children of part P in the <template> named in the source attribute must be inserted as children of part P after the child of P with part name part-name. ExamplesConsider the button and panel introduced at the beginning of the proposal, where the panel contains three components: a label, a text field, and a check box. The UIML looks like this:<structure> <part class="JFrame" name="F"> <part class="JButton" name="B"/> <part class="JPanel" name="A"> <part class="JLabel" name="L1"/> <part class="JTextField" name="TF"/> <part class="JCheckbox" name="C"/> </part> </part> </structure>Append Examples
<restructure at-part="A" how="append" where="first"> <template name="T1"> <part> <part class="JLabel" name="L2"/> </part> </template> </restructure>The panel now contains the parts in this order: A.T1.L2, L1, TF, C. Note: the naming convention used for parts that are added from a template is discussed in another proposal.
<restructure at-part="A" how="append" where="after" where-part="TF"> <template name="T2"> <part> <part class="JLabel" name="L3"/> <part class="JTextArea" name="TA"/> </part> </template> </restructure> (Alternately, one could have used where="before" where-part="C".) The order of parts in the panel is now A.T1.L2, L1, TF, A.T2.L3, A.T2.TA, C.
<restructure at-part="A" how="append" where="before" where-part="C"> <template name="T3"> <part> <part class="JLabel" name="L4"/> </part> </template> </restructure>
<restructure at-part="A" how="append"> <template name="T4"> <part> <part class="Label" name="L1"/> </part> </template> </restructure> There is already a part named L1 as a child of A, but the part L1 being added gets renamed to A.T4.L1, so now the panel A has the following children: A.T1.L2, L1, TF, A.T2.L3, A.T2.TA, A.T3.L4, C, A.T4.L1.Replace Example
<restructure at-part="A" how="replace"> <template name="T5> <part> <part class="JLabel" name="L1"/> <part class="JTextField" name="TF"/> </part> </template> </restructure> The set of children of A in the virtual UI tree is replaced with the set of children listed in the restructure tag. So now the panel has only the following children: A.T5.L1, A.T5.TF.Cascade Example
<restructure at-part="A" how="cascade" where="last"> <template name="T6"> <part> <part class="JLabel" name="L1"/> <part class="JLabel" name="L5"/> </part> </template> </restructure> Since A already has a child named L1 (A.T5.L1), the L1 in template T6 is not used, but part L5 from the template is added as a child of A. So A's children are now A.T5.L1, A.T5.TF, A.T6.L5. Note that when checking for a part with the same name, only the last part of a dotted name is checked, so A.T5.L1 matches L1.Delete Example
<restructure at-part="A" how="delete"/> Implementation ConsiderationsA rendering engine will initially render the parts in the <structure> element, although a renderer may do lazy evaluation if <structure> contains the source attribute to refer to external files. Thus a UIML author should put as little as possible into the <structure> element, and add the remaining elements via <restructure> elements.If the target platform is markup, a UIML renderer might need to simulate the effect of <restructure> on the server side to regenerate a new markup language file, send it to the client browser, and cause the browser to be refreshed.
© 1999-2001 UIML.org (all rights reserved) |