XSWT for Eclipse form layout

XSWT is an XML-based GUI-description language for SWT. The XSWT engine uses Java reflection to actually construct a user interface, so it is automatically compatible with current and future SWT controls. An eclipse editor for XSWT files is included.

現在開發的產品中用戶界面也是用XML定義的,但是界面定義很不靈活。XSWT網站上介紹說XSWT是和SWT元素一一對應的,應該有很大的靈活性。

xswt的下載地址是:http://xswt.sourceforge.net/cgi-bin/xswt/download
也可以使用Eclipse的Update Manager從http://xswt.sourceforge.net/updates 在線更新。

下載了一個試用了一下,總體感覺還好。但是好像項目還沒有開發完,文檔沒有。而且官方網站上說支持Groovy腳本語言的功能好像還沒有提供。期待中。。。。

以下是一個我寫的示例代碼,演示了在XSWT中如何處理事件。
/*******************************************************************************
 * $Header$
 * $Revision$
 * $Date$
 *
 *==============================================================================
 *
 * Copyright (c) 2001-2004 XYZ Technologies, Ltd.
 * All rights reserved.
 *
 * Created on 2004-11-27
 *******************************************************************************/

import java.io.InputStream;
import java.util.Map;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import com.swtworkbench.community.xswt.XSWT;


/**
 * TODO此處填寫 class 信息
 *
 * @author Yanfei (mailto:[email protected])
 */
/*
 * 修改歷史
 * $Log$
 */
public class XSWTDialogTest {

    /**
     *
     */
    public XSWTDialogTest() {
        super();
    }
   
    public static void main(String[] args) throws Exception{
        Display display = new Display();
        final Shell shell = new Shell(display);
        shell.setLayout(new GridLayout());
       
        InputStream in = XSWTDialogTest.class.getResource("JavaEditorPreferencePage.xswt").openStream();
        Map controls = XSWT.create(shell, in);

        Button button1 = (Button) controls.get("button1");
        button1.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                MessageDialog.openInformation(shell, "Message", "button1 selected");
            }

            public void widgetDefaultSelected(SelectionEvent e) {
               
            }
        });

        shell.setSize(600, 600);
        shell.open();
        while(!shell.isDisposed())
            if(!display.readAndDispatch())
                display.sleep();
        display.dispose();
    }

}

以下是定義界面的XSWT文件:
<?xml version="1.0" encoding="UTF-8"?>
<xswt xmlns:x="http://sweet_swt.sf.net/xswt">
 <import xmlns="http://sweet_swt.sf.net/xswt">
  <package name="java.lang"/>
  <package name="org.eclipse.swt.widgets"/>
  <package name="org.eclipse.swt.layout"/>
 </import>
 <x:children>
  <composite>
   <layoutData x:class="gridData" grabExcessHorizontalSpace="true" grabExcessVerticalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.FILL"/>
   <layout x:class="gridLayout" marginHeight="0" marginWidth="0"/>
   <x:children>
    <label text="Java Editor settingx:"/>
    <tabFolder>
     <layoutData x:class="gridData" grabExcessHorizontalSpace="true" grabExcessVerticalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.FILL"/>
     <x:children>
     
      <composite x:id="appearance">
       <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL"/>
       <layout x:class="gridLayout" numColumns="2"/>
       <x:children>
        <label text="Displayed &amp;tab width:"/>
        <text x:style="BORDER" text="4" textLimit="3"><layoutData x:class="gridData" widthHint="20"/></text>
        <label text="Print margin col&amp;umn:"/>
        <text x:style="BORDER" text="80" textLimit="3"><layoutData x:class="gridData" widthHint="20"/></text>
        <button x:id="button1" x:style="CHECK" text="Synchroni&amp;ze outline selection on cursor move (editor must be reopened)"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button selection="true" x:style="CHECK" text="Show overview &amp;ruler"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button x:style="CHECK" text="Show lin&amp;e numbers"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button selection="true" x:style="CHECK" text="Highlight &amp;matching brackets"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button selection="true" x:style="CHECK" text="Hi&amp;ghlight current line"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button x:style="CHECK" text="Sho&amp;w print margin"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <composite><layoutData x:class="gridData" heightHint="5"/></composite>
        <composite>
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" horizontalSpan="2"/>
         <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
         <x:children>      
          <label text="Appearance color optionx:"><layoutData x:class="gridData" horizontalSpan="2"/></label>       
          <list selection="0" x:style="BORDER|SINGLE">
           <layoutData x:class="gridData" heightHint="100" widthHint="220"/>
           <!-- x:p0 specifies the 0th constructor argument for the String passed to add() (ie: the string's value). -->
           <add x:p0="Line number foreground"/>
           <add x:p0="Matching brackets highlight"/>
           <add x:p0="Current line highlight"/>
           <add x:p0="Print margin"/>
           <add x:p0="Find scope"/>
           <add x:p0="Linked position"/>
           <add x:p0="Link"/>
          </list>
          <composite>       
           <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.BEGINNING"/>
           <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
           <x:children>
            <label text="C&amp;olor:"/>
            <button><layoutData x:class="gridData" widthHint="40"/></button>
           </x:children>
          </composite>
         </x:children>
        </composite>    
       </x:children>
      </composite>
      <tabItem text="Appeara&amp;nce" control="appearance"/>

      <composite x:id="syntax">
       <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" horizontalSpan="2"/>
       <layout x:class="gridLayout" numColumns="2"/>
       <x:children>      
        <group text="Background color:">
         <layoutData x:class="gridData"/>
         <layout x:class="gridLayout" numColumns="3"/>
         <x:children>
          <button selection="true" x:style="RADIO" text="S&amp;ystem default"><layoutData x:class="gridData" verticalAlignment="GridData.BEGINNING"/></button>
          <button x:style="RADIO" text="C&amp;ustom:"><layoutData x:class="gridData" verticalAlignment="GridData.BEGINNING"/></button>
          <button><layoutData x:class="gridData" widthHint="40"/></button>
         </x:children>
        </group>
        <composite><layoutData x:class="gridData" heightHint="0" widthHint="0"/></composite>
        <label text="Fo&amp;reground:"><layoutData x:class="gridData" horizontalSpan="2"/></label>       
        <list x:style="BORDER|SINGLE">
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.FILL"/>
         <add x:p0="Multi-line comment"/>
         <add x:p0="Single-line comment"/>
         <add x:p0="Keywords"/>
         <add x:p0="Strings"/>
         <add x:p0="Others"/>
         <add x:p0="Task Tags"/>
         <add x:p0="Javadoc keywords"/>
         <add x:p0="Javadoc HTML tags"/>
         <add x:p0="Javadoc links"/>
         <add x:p0="Javadoc others"/>
        </list>       
        <composite>       
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.BEGINNING"/>
         <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
         <x:children>
          <label text="C&amp;olor:"/>
          <button><layoutData x:class="gridData" widthHint="40"/></button>
          <button x:style="CHECK" text="&amp;Bold"><layoutData x:class="gridData" horizontalSpan="2"/></button>          
         </x:children>
        </composite>
        <label text="Preview:"><layoutData x:class="gridData" horizontalSpan="2"/></label>          
        <text x:style="BORDER"><layoutData x:class="gridData" grabExcessHorizontalSpace="true" grabExcessVerticalSpace="true" horizontalAlignment="GridData.FILL" horizontalSpan="2" verticalAlignment="GridData.FILL"/></text> 
       </x:children>
      </composite>  
      <tabItem text="Synta&amp;x" control="syntax"/>

      <composite x:id="code_assist">
       <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL"/>
       <layout x:class="gridLayout" numColumns="2"/>
       <x:children>
        <composite>
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" horizontalSpan="2"/>
         <layout x:class="gridLayout" marginWidth="0" numColumns="2"/>
         <x:children>
          <button selection="true" x:style="RADIO" text="Completion inser&amp;ts"/>
          <button x:style="RADIO" text="Completion over&amp;writes"/>
         </x:children>
        </composite>
        <button selection="true" x:style="CHECK" text="Insert single &amp;proposals automatically"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button selection="true" x:style="CHECK" text="Show only proposals &amp;visible in the invocation context"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button x:style="CHECK" text="Present proposals in a&amp;lphabetical order"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button selection="true" x:style="CHECK" text="Automatically add import instead of &amp;qualified name"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button x:style="CHECK" text="&amp;Fill argument names on method completion"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button enabled="false" selection="true" x:style="CHECK" text="&amp;Guess filled argument names"><layoutData x:class="gridData" horizontalIndent="20"/></button>
        <button selection="true" x:style="CHECK" text="&amp;Enable auto activation"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <label text="Auto activation dela&amp;y:"/>
        <text x:style="BORDER" text="500" textLimit="4"><layoutData x:class="gridData" widthHint="30"/></text>
        <label text="Auto activation &amp;triggers for Java:"/>
        <text x:style="BORDER" text="." textLimit="4"><layoutData x:class="gridData" widthHint="30"/></text>
        <label text="Auto activation triggers for &amp;Javadoc:"/>
        <text x:style="BORDER" text="@" textLimit="4"><layoutData x:class="gridData" widthHint="30"/></text>
        <composite>
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" horizontalSpan="2"/>
         <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
         <x:children>      
          <label text="Code assist colo&amp;r optionx:"><layoutData x:class="gridData" horizontalSpan="2"/></label>       
          <list x:style="BORDER|SINGLE">
           <layoutData x:class="gridData" heightHint="100" widthHint="180"/>
           <add x:p0="Completion proposal background"/>
           <add x:p0="Completion proposal foreground"/>
           <add x:p0="Method parameter background"/>
           <add x:p0="Method parameter foreground"/>
           <add x:p0="Completion overwrite background"/>
           <add x:p0="Completion overwrite foreground"/>
          </list>       
          <composite>       
           <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.BEGINNING"/>
           <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
           <x:children>
            <label text="C&amp;olor:"/>
            <button><layoutData x:class="gridData" widthHint="40"/></button>
           </x:children>
          </composite>
         </x:children>
        </composite>    
       </x:children>
      </composite>
      <tabItem text="&amp;Code Assist" control="code_assist"/>

      <composite x:id="annotations">
       <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL"/>
       <layout x:class="gridLayout" numColumns="2"/>
       <x:children>
        <button selection="true" x:style="CHECK" text="Analyze annotations &amp;while typing"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <button selection="true" x:style="CHECK" text="Indicate annotations solvable with &amp;Quick Fix in vertical ruler"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <composite><layoutData x:class="gridData" heightHint="5"/></composite>
        <composite>
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" horizontalSpan="2"/>
         <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
         <x:children>      
          <label text="Annotation &amp;presentation:"><layoutData x:class="gridData" horizontalSpan="2"/></label>       
          <list x:style="BORDER|SINGLE">
           <layoutData x:class="gridData" heightHint="100" widthHint="150"/>
           <add x:p0="Errors"/>
           <add x:p0="Warnings"/>
           <add x:p0="Tasks"/>
           <add x:p0="Search Results"/>
           <add x:p0="Bookmarks"/>
           <add x:p0="Others"/>
          </list>       
          <composite>       
           <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.BEGINNING"/>
           <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
           <x:children>
            <button selection="true" x:style="CHECK" text="Show in &amp;text"><layoutData x:class="gridData" horizontalSpan="2"/></button>
            <button selection="true" x:style="CHECK" text="Show in overview &amp;ruler"><layoutData x:class="gridData" horizontalSpan="2"/></button>
            <label text="C&amp;olor:"/>
            <button><layoutData x:class="gridData" widthHint="40"/></button>
           </x:children>
          </composite>
         </x:children>
        </composite>    
       </x:children>
      </composite>
      <tabItem text="Annotation&amp;s" control="annotations"/>

      <composite x:id="typing">
       <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL"/>
       <layout x:class="gridLayout"/>
       <x:children>
        <button selection="true" x:style="CHECK" text="S&amp;mart cursor positioning at line start and end"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <composite><layoutData x:class="gridData" heightHint="5"/></composite>
        <group text="Select options for automatic text modifications">
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL"/>
         <layout x:class="gridLayout"/>
         <x:children>
          <button selection="true" x:style="CHECK" text="&amp;Wrap Java strings"/>
          <button selection="true" x:style="CHECK" text="Pasting fo&amp;r correct indentation"/>
          <button x:style="CHECK" text="Ins&amp;ert space for tabs (see Code Formatter preference page)"/>
          <button selection="true" x:style="CHECK" text="Close strin&amp;gs"/>
          <button selection="true" x:style="CHECK" text="Close &amp;brackets and parenthesis"/>
          <button selection="true" x:style="CHECK" text="Cl&amp;ose braces"/>
          <button selection="true" x:style="CHECK" text="Close Java&amp;docs and comments"/>
          <button selection="true" x:style="CHECK" text="Add Javadoc &amp;tags"><layoutData x:class="gridData" horizontalIndent="20"/></button>
         </x:children>
        </group> 
       </x:children>
      </composite>
      <tabItem text="T&amp;yping" control="typing"/>

      <composite x:id="hovers">
       <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" horizontalSpan="2"/>
       <layout x:class="gridLayout" numColumns="2"/>
       <x:children>      
        <label text="&amp;Hover key modifier preferencex:"><layoutData x:class="gridData" horizontalSpan="2"/></label>       
        <list x:style="BORDER|SINGLE">
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.FILL"/>
         <add x:p0="Best Match"/>
         <add x:p0="Javadoc"/>
         <add x:p0="Problems"/>
         <add x:p0="Source"/>
         <add x:p0="Variable Values"/>
        </list>       
        <composite>       
         <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL" verticalAlignment="GridData.BEGINNING"/>
         <layout x:class="gridLayout" marginHeight="0" marginWidth="0" numColumns="2"/>
         <x:children>
          <button selection="true" x:style="CHECK" text="&amp;Enabled"><layoutData x:class="gridData" horizontalSpan="2"/></button>          
          <label text="Key &amp;Modifier:"></label>
          <text x:style="BORDER"><layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL"/></text>
          <label text="Description:"><layoutData x:class="gridData" horizontalSpan="2"/></label>
          <text x:style="BORDER|READ_ONLY" text=""><layoutData x:class="gridData" grabExcessHorizontalSpace="true" grabExcessVerticalSpace="true" heightHint="60" horizontalAlignment="GridData.FILL" horizontalSpan="2" verticalAlignment="GridData.FILL"/></text>
         </x:children>
        </composite>
       </x:children>
      </composite>  
      <tabItem text="Ho&amp;vers" control="hovers"/>

      <composite x:id="navigation">
       <layoutData x:class="gridData" grabExcessHorizontalSpace="true" horizontalAlignment="GridData.FILL"/>
       <layout x:class="gridLayout" numColumns="2"/>
       <x:children>
        <button selection="true" x:style="CHECK" text="S&amp;upport hyperlink style navigation for &quot;Open Declaration&quot;"><layoutData x:class="gridData" horizontalSpan="2"/></button>
        <label text="Hyperlink style navigation key &amp;modifier:"/>
        <text x:style="BORDER" text="Ctrl"><layoutData x:class="gridData" widthHint="100"/></text>
       </x:children>
      </composite>
      <tabItem text="Nav&amp;igation" control="navigation"/>

     </x:children>
    </tabFolder>
   </x:children>
  </composite>
 </x:children>
</xswt>

以下付上XSWT郵件列表中關於event handling的對話:

From: ted stockwell <emorning@ya...>
Event Handling?  
2004-11-16 05:07
 Hi all,
 
 I just now downloaded XSWT and took a quick look around.  
 One thing that is not obvious to me is how to handle events.
 For instance, how do I handle a button selection?
 
 TIA,
 ted stockwell
 

From: Jan Petersen <jpetersen@in...>
Re: Event Handling?  
2004-11-16 05:34
 On Tue, 16 Nov 2004 07:07:46 -0600
  "ted stockwell" <emorning@ya...> wrote:
 > Hi all,
 > 
 > I just now downloaded XSWT and took a quick look around.
 >  One thing that is not obvious to me is how to handle
 > events.
 > For instance, how do I handle a button selection?
 
 Ted,
 
 This is not _really_ part of XSWT, but it"s relatively easy
 to set up. One of the many nice features in XSWT is that
 you can do:
 
 <button x:id="myButton" x:id.event="myEvent" text=...
 
 Then, when you reference your id"d widgets in your java
 code, you can do something like:
 
 String eventString = (String)widget.getData("event");
 
 Now you have the string value of the attribute
 "x:id.event". The remaining part is to convert the string
 value to an SWT event (via reflection for instance) and to
 do a addListener(...) on the widget.
 
 Hope this helps
 
 
 Jan
 

From: David J. Orme <djo@co...>
Re: Event Handling?  
2004-11-16 07:37
 Nice to see you here, Ted!
 
 On Tuesday 16 November 2004 07:07 am, ted stockwell wrote:
 > I just now downloaded XSWT and took a quick look around.  
 > One thing that is not obvious to me is how to handle events.
 > For instance, how do I handle a button selection?
 
 Right now, here"s how this works:
 
 In the XSWT file:
 
 <button x:id="buttonName" text="Click me"/>
 
 In your Java code:
 
 InputStream in = getClass().getResource("bounds_example.xswt").openStream();
 Map controls = XSWT.create(shell, in);
 Button aButton = (Button) controls.get("buttonName");
 aButton.addSelectionListener(new MySelectionListener());
 
 In other words, any SWT control with an x:id will be in the Map that 
 XSWT.create() returns, indexed by the ID string.  Then you can do whatever 
 you want with it.
 
 This is very workable, if a bit cumbersome.  There have been several proposals 
 floated to improve this.
 
 1) Have XSWT generate an interface with getter methods corresponding to every 
 x:ID attribute.  Have a version of XSWT.create() that returns a dynamic proxy 
 implementing this interface that looks at the name of the method, does the 
 Map lookup for you, and returns the appropriate object.
 
 This would eliminate the typecast and would enable the compiler to catch 
 coding errors more effectively.
 
 2) Something along the lines of what Jan mentioned (originally suggested by Ed 
 Burnette in the XSWT bug report), where you have an engine that looks up 
 event names based on the x:id or possibly based on an extended attribute 
 initialized using x:id.eventhandlername="value" and automatically sets the 
 event handler using Java reflection.  So you could write:
 
 Map controls = XSWT.create(shell, in);
 EventManager.hookup(controls, aControllerObject);
 
 and have it all just done for you.
 
 3) And then you have the XSWT to Java compiler, which provides even more 
 interesting possibilities for event hookup because you can just generate code 
 that does it and bypass Java reflection entirely...
 
 
 Again, welcome to XSWT, Ted!
 
 Best regards,
 
 Dave Orme
 
 -- 
 Got Java?  Use SWTworkbench! <http://www.swtworkbench.com>
 
 PGP Public Key (for confidential communications):
 http://www.coconut-palm-software.com/~djo/public_key.txt


XSWT Screen Shot
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章