Subject: Re: [xsl] On Sourceforge: Cool: Saxon driving a GUI, interactive XSLT From: Gunther Schadow <gunther@xxxxxxxxxxxxxxxxxxxxxx> Date: Fri, 19 Nov 2004 15:14:31 -0500 |
M. David Peterson wrote: > There are several posts I need to follow-up on but this post > caught my eye in particular as it seems that your project and a > combination of projects that various members of the Saxon.NET team are > working may have a lot in common. David, thanks for your note. Do you have a list of the other projects? I went into the XSL list archives, and couldn't find anything from subject line keyword search (GUI, Swing, SWT). But I haven't followed too closely for a while. Always happy to chat and peek into other preople's ideas and code. If you browse the CVS today, you won't find this GUI stuff yet, because Sourceforge hasn't updated its CVSweb snapshot yet. Here are some quick explanations about the approach. You can define a simple SWT GUI like this: <display> <shell> <gridLayout numColumns="2"/> <label>Tell me:</label> <text id="data"><gridData grabExcessHorizontalSpace="true"/>more</text> <button>OK<handle event="selection"/></button> <button>CANCEL<handle event="selection"/></button> <pack/> <open/> </shell> </display> When you run the swt.xsl transform on this, up pops the following window: +---------------------------------+ | [_][-][x]| +---------------------------------+ | Tell me: [more________________] | | | | [OK] [CANCEL] | +---------------------------------+ You can click the OK button and the transformer is called back with a snippet such as: <event name="org.eclipse.swt.events.SelectionEvent" target="button"/> which you can catch by templates such as this: <xsl:template mode="event" match="event[@name='org.eclipse.swt.events.SelectionEvent' and @target='button']" xmlns:event="java:org.eclipse.swt.events.SelectionEvent" xmlns:button="java:org.eclipse.swt.widgets.Button" xmlns:textbox="java:org.eclipse.swt.widgets.Text"> <!-- the event Java object --> <xsl:param name="event" select="/.."/> <!-- the button element in the GUI document above --> <xsl:param name="current" select="/.."/> <!-- fetch the Java button object --> <xsl:param name="object" select="fn:get-object-by-element($current)"/> <!-- do something with all of that --> <buttonPressed buttonObjectText="button:getText($object)" buttonElementText="$current/text()" textboxObjectText="textbox:getText(fn:get-object-by-id('data'))" textboxElementText="$current/ancestor::*//*[@id='data']/text()"/> </xsl:template> Now assume we do the following actions after the GUI has started: 1.) change the text in the text box to "Hello Saxon!" 2.) click the O.K. button then, when the GUI stops (e.g., by closing the SWT Shell window), you get the following output: <display gid="1ef3"> <shell gid="1e30"> <gridLayout gid="201a" numColumns="2"/> <label gid="203b">Tell me:</label> <text gid="2145" id="data"><gridData gid="2138" grabExcessHorizontalSpace="true"/>more</text> <button gid="2345">OK<handle event="selection"/></button> <button gid="234b">CANCEL<handle event="selection"/></button> </shell> </display> <buttonPressed buttonObjectText="OK" buttonElementText="OK" textboxObjectText="Hello Saxon!" textboxElementText="more"/> As you can see, in the event handler you have access to the event object as well as to the node of the original GUI document that had created the GUI object that fired the event. You can get to any GUI objects through the hash-map that stores the object under the key generate-id() of the node that created the object and optionally also under the @id key that you can specify on any such element. In the event handlers, you can do pretty much anything. Including traversing the GUI objects and creating an XML dump of them reflecting their possibly changed state. Of course, sensible patterns would have to be developed as to how one should handle events. This is subject to further discovery. One could do monolithic XSLT everything, or one could do MVC style and call some Java model objects. Of course, one could register Java event handlers such that those events don't cause <event> nodes to be transformed. The transform that creates all these GUI elements from the input is itself generated from a file that defines the GUI framework and Java object to use. That way, adaption to SWT or Swing or whatever else is quite simple. Here is an example of the definition of the SWT elements that I used in the example above: <framework ...> <element name="shell" class="org.eclipse.swt.widgets.Shell"> <constructor method="wa:makeShell"/> <action name="pack" method="pack"/> <action name="open" method="open"/> </element> <element name="label" class="org.eclipse.swt.widgets.Label"> <constructor args="swt:NONE()"/> <property name="text()" method="setText"/> </element> <element name="text" class="org.eclipse.swt.widgets.Text"> <constructor args="swt:NONE()"/> <property name="text()" method="setText"/> </element> <element name="button" class="org.eclipse.swt.widgets.Button"> <constructor args="swt:NONE()"/> <property name="text()" method="setText"/> </element> <element name="gridLayout" class="org.eclipse.swt.layout.GridLayout"> <constructor args="" xmlns:composite="java:org.eclipse.swt.widgets.Composite"> <xsl:sequence select="composite:setLayout($parent,$object)"/> </constructor> <property name="@numColumns" setter="setInt" field="numColumns"/> <property name="@makeColumnsEqualWidth" setter="setBoolean" field="makeColumnsEqualWidth"/> </element> <element name="gridData" class="org.eclipse.swt.layout.GridData"> <constructor args="" xmlns:control="java:org.eclipse.swt.widgets.Control"> <xsl:sequence select="control:setLayoutData($parent,$object)"/> </constructor> <property name="@grabExcessHorizontalSpace" setter="setBoolean" field="grabExcessHorizontalSpace"/> <property name="@grabExcessVerticalSpace" setter="setBoolean" field="grabExcessVerticalSpace"/> <property name="@horizontalSpan" setter="setInt" field="horizontalSpan"/> <property name="@verticalSpan" setter="setInt" field="verticalSpan"/> <xsl:variable name="gridDataAlignmentCodes" xmlns:data="java:org.eclipse.swt.layout.GridData"> <code code="beginning" value="{data:BEGINNING()}"/> <code code="end" value="{data:END()}"/> <code code="center" value="{data:CENTER()}"/> <code code="fill" value="{data:FILL()}"/> </xsl:variable> <property name="@verticalAlignment" setter="setInt" field="verticalAlignment" map="gridDataAlignmentCodes"/> <property name="@horizontalAlignment" setter="setInt" field="horizontalAlignment" map="gridDataAlignmentCodes"/> </element> <event name="selection"> <listener name="org.eclipse.swt.events.SelectionListener" register="addSelectionListener"> <method name="widgetSelected"/> </listener> </event> </framework> Hope this has helped some of the questions you might have. thanks, -Gunther -- Gunther Schadow, M.D., Ph.D. gschadow@xxxxxxxxxxxxxxx Associate Professor Indiana University School of Informatics Regenstrief Institute, Inc. Indiana University School of Medicine tel:1(317)630-7960 http://aurora.regenstrief.org
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] On Sourceforge: Cool: Sax, M. David Peterson | Thread | Re: [xsl] On Sourceforge: Cool: Sax, M. David Peterson |
Re: [xsl] Sorting and Paging in one, Kyle Himmerick | Date | RE: [xsl] position() test for proce, Wendell Piez |
Month |