RCP应用篇之Eclipse表单

来源:互联网 发布:php工厂模式单例模式 编辑:程序博客网 时间:2024/05/17 16:43

AVA.SWT/JFace: RCP应用篇之Eclipse表单(二)

《Eclipse SWT/JFACE 核心应用》 清华大学出版社 24 Eclipse表单

24.2.3 SWT 程序中使用表单
    上文提到过,表单不仅可以使用在 Eclipse 插件开发和 RCP 开发中,也可以应用在任何 SWT/JFace 的 UI 界面程序中。演示代码如下:
package com.testrcp.myrcp.forms;

import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;

public class NonEclipse {

public static void main(String[] args) {
   Display display = new Display();
   Shell shell = new Shell(display);
   shell.setText("SWT表单示例");
   shell.setLayout( new FillLayout());
   //创建表单工具对象
   FormToolkit toolkit = new FormToolkit(shell.getDisplay());
   //通过表单工具对象创建可滚动的表单对象
   ScrolledForm form = toolkit.createScrolledForm(shell);
   form.setLayout( new GridLayout());
   //设置表单文本
   form.setText("Hello, Non Eclipse 表单");
   toolkit.createLabel(form,"text");
   shell.pack();
   shell.open();
   while (!shell.isDisposed()) {
    if (!display.readAndDispatch())
     display.sleep();
   }
   toolkit.dispose();
   display.dispose();
}
}

    显示效果如下:


    SWT程序中应用了 FormToolkit 对象,就可以显示出表单的效果了,所做的只是导入表单所使用的类包即可。

24.2.4 获得表单工具对象(FormToolkit)一般方法
◇ 通过 Display 对象来创建:
FormToolkit toolkit = new FormToolkit(Display().getCurrent());

◇ 若在多页表单中不要使用new的方式,而要通过 IManagedForm 对象获得:
FormToolkit toolkit = managedForm.getToolkit();

    获得了FormToolkit 就可以使用该对象的 createXXX 方法来创建各种所需的控件了。

24.3 表单的各种控件

24.3.1 可滚动的表单(ScrolledForm)
    通过SWT的学习已经了解到,若想放置一个基本的控件,首先要有一个放置控件的容器,不管是一个窗口(Shell)还是一个普通的面板(Composite),都可以作为容器来放置控件。对 Eclipse 表单来说,也有对应的表单容器,最基本的就是 ScrolledForm 对象。
    可滚动的表单(ScrolledForm)是放置其他表单控件的容器,可以实现带滚动的效果。与其他控件相比,ScrolledForm 比较特殊的是,它也有两种方式获得:
◇ 如是在 FormPage 中,可以利用 createFormContent 方法的 IManagedForm 对象获得:
ScrolledForm form = managedForm.getForm();

◇ 如果是在其他地方,例如视图中,可以通过 FormToolkit 对象的 createForm 方法获得:
ScrolledForm form = toolkit.createScrolledForm(parent);

    另外,ScrolledForm 还可以设置标题栏、设置背景图片等使内容区可滚动的设置来仿照Web网页效果。例如,以下代码所示为设置了ScrolledForm对象的背景图片:
ScrolledForm form = toolkit.createScrolledForm(parent);
// 设置表单文本
form.setText("Hello, Eclipse 表单");
// 设置表单的背景图片
form.setBackgroundImage(MyRCPPlugin.getImageDescriptor("icons/form_bg.gif").createImage());

24.3.2 可折叠的面板(ExpandableComposite)
可折叠的面板显示效果:

    在MyFormView的createPartControl方法中添加以下代码可以实现上述效果:
   //设置表单的布局
   form.getBody().setLayout( new TableWrapLayout());
  
   //创建可折叠的面板
   ExpandableComposite expcomp = toolkit.createExpandableComposite(form.getBody(), ExpandableComposite.TREE_NODE);
   //定义字符串
   String txt = "在Web网页的UI体系中,最常见的也是效果最好的就是使页面中的部分区域中的内容可以折叠和展开,Eclipse表单也提供了可折叠的面板(ExpandableComposite)来实现相同的功能.";
   //创建一个标签并显示字符串
   Label client = toolkit.createLabel(expcomp, txt, SWT.WRAP);
   //为折叠面板设置设置标题
   expcomp.setText("这是一个可折叠的面板(ExpandableComposite)");
   //expcomp.setToggleColor( Display.getCurrent().getSystemColor( SWT.COLOR_DARK_BLUE));
   // 将Label作为折叠面板折叠区的内容
   expcomp.setClient(client);
   // 为折叠面板添加展开/折叠时的监听器
   expcomp.addExpansionListener(new ExpansionAdapter() {
    public void expansionStateChanged(ExpansionEvent e) {
     // 根据控件的新尺寸重新定位和更新滚动条
     form.reflow(true);
    }
   });

    通过以上代码,总结出创建可折叠面板时所需要注意的问题:
    (1)在表单中添加各种控件之前,需设置表单的布局,否则不会正确的显示控件。获得表单所在面板的方法是 getBody,然后就可以使用设置面板的方法设置布局了。例如,本例中设置的布局为 TableWrapLayout 布局,这种布局在之前还未使用过,它是专门为表格所设计的布局,布局的效果类似于网页中使用的表格布局,该布局的具体知识将在表单的高级应用部分详细讲述。当然,表单除了可以使用TableWrapLayout布局外,也可以使用之前学习的FillLayout、GridLayout等布局,这要视不同的情况而定。
    (2)创建可折叠面板时,使用了FormToolkit对象以下所示的方法:
ExpandableComposite createExpandableComposite(Composite parent, int expansionStyle)

    其中,parent为创建该面板的父面板,本例中父面板为表单面板。expansionStyle为可折叠面板的样式,可使用的样式如下表:


    (3)创建可折叠面板时,并不是直接创建使用 ExpandableComposite 的构造方法来创建可折叠面板对象,而是通过表单工具类 FormToolkit 对象中的 createExpandableComposite 方法创建的,这样做更适合创建表单的控件。下面是该方法的源代码:
/**
* Creates an expandable composite as a part of the form.

* @param parent
*            the expandable composite parent
* @param expansionStyle
*            the expandable composite style
* @return the expandable composite widget
*/
public ExpandableComposite createExpandableComposite(Composite parent,
    int expansionStyle) {
   ExpandableComposite ec = new ExpandableComposite(parent, orientation,
     expansionStyle);
   ec.setMenu(parent.getMenu());
   adapt(ec, true, true);
   ec.setFont(boldFontHolder.getBoldFont(ec.getFont()));
   return ec;
}

    从源代码中可以看出,通过 FormToolkit 对象来创建面板,可以不用管表单的菜单、字体等设置,该方法中已经使用了默认的设置。这样就隐藏了表单底层一些实现,通过使用很简单的代码就可以创建出表单所需的控件。
    这种通过 FormToolkit 表单创建控件的方法非常重要。因为在表单中,所有的控件都是通过 FormToolkit对象的 createXXX 方法来创建,XXX 表示不同的控件。以下列举了在表单中创建之前学习SWT时一些常用控件的方法:
◇ Button createButton(Composite parent,String text,int style):创建按钮,其中text为按钮显示文字。
◇ Composite createComposite(Composite parent,int style):创建面板。
◇ Label createLabel(Composite parent,String text,int style):创建标签。
◇ Label createSeparator(Composite parent,int style):创建分隔符标签。
◇ Table createTable(Composite parent,int style):创建表格。
◇ Text createText(Composite parent,String value,int style):创建文本框。
◇ Tree createTree(Composite parent,int style):创建树。
    这样,在表单中创建各种控件时,都需要使用这些方法来创建。

    (4)通过 ExpandableComposite 对象的 setText 方法可以设置折叠面板的标题。另外,最重要的是设置折叠面板显示的控件是通过 setTextClient(Control textClient)方法来设置的,其中textClient可以是任何的 Control 类及其子类。除了这最基本的方法外,ExpandableComposite 还有其他一些常用的方法:
◇ setActiveToggleColor(Color c):设置鼠标移动到面板的标题上时标题的颜色。
◇ setBackground(Color bg):设置标题的背景色。
◇ setForeground(Color fg):设置标题的前景色。
◇ setExpanded(boolean expanded):设置折叠或展开状态。
◇ isExpanded():获得当前折叠面板的状态,true表示展开,false表示折叠。

    (5)最后使用 ExpandableComposite 对象时一定要注册 addExpansionListener 监听器,这将会使展开和折叠面板时重新布局,否则将不能显示折叠和展开的效果。

24.3.3 内容区(Section)
     内容区(Section)设可折叠的面板(ExpandableComposite)子类。除了具有 ExpandableComposite 类可折叠的特性外,还可以设置不同的标题颜色、标题栏的分割线和标题栏的控件等。


    在MyFormView的createPartControl方法中添加以下代码可以实现上述效果:
   //创建内容区域,使用TWISTIE样式,并且使用TITLE_BAR显示背景的标题
   Section section = toolkit.createSection(form.getBody(), Section.TWISTIE|Section.TITLE_BAR|Section.DESCRIPTION);
   //设置标题文字
   section.setText("这是一个内容区(Section)");
   //创建一个面板,作为内容折叠区放置的控件
   Composite sectionClient = toolkit.createComposite(section);
   sectionClient.setLayout( new GridLayout());
   @SuppressWarnings("unused")
   Button bt1 = toolkit.createButton(sectionClient, "CheckBox 1", SWT.CHECK);
   @SuppressWarnings("unused")
   Button bt2 = toolkit.createButton(sectionClient, "CheckBox 2", SWT.CHECK);
   //设置内容区控件
   section.setClient(sectionClient);
   toolkit.createCompositeSeparator(section);
   section.setDescription("这是在标题栏下的一段描述");
   section.addExpansionListener(new ExpansionAdapter() {
    public void expansionStateChanged(ExpansionEvent e) {
     // 根据控件的新尺寸重新定位和更新滚动条
     form.reflow(true);
    }
   });
   //创建带图标的超链接
   ImageHyperlink imageHyperlink = toolkit.createImageHyperlink(section,SWT.CENTER);
   //设置超链接的图标
   imageHyperlink.setImage( PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD).createImage());
   //将该图标超链接添加到内容区的工具栏中
   section.setTextClient( imageHyperlink );

    通过以上代码可以看出创建内容区的方法需要注意以下几点:
◇ 创建 Section 对象是通过 FormToolkit 的 createSection 方法创建的。
◇ 样式中若选用 Section.TITLE_BAR 则显示带背景颜色的标题,否则与滚动面板的效果一样。
◇ 通过使用 setClient 方法,可以为内容区添加所折叠显示的控件。
◇ 也可以设置内容区的描述信息。例如以下代码:
   //使用Section.DESCRIPTION常量,表示显示描述信息
   Section section = toolkit.createSection(form.getBody(), Section.TWISTIE|Section.TITLE_BAR|Section.DESCRIPTION);
   section.setDescription("这是在标题栏下的一段描述"); // 设置描述信息

    添加了描述信息后,内容区描述信息显示在标题的下方。

◇ 可以设置内容区的分割线,例如以下代码:
   toolkit.createCompositeSeparator(section); // 通过工具类来创建分割线


◇ 在 Eclipse 开发环境中的很多 Section 中,都会有一个帮助按钮显示在 Section 的标题栏的右端,非常美观且方便使用。


    要添加这样的按钮,只需要使用以下方法即可:
   section.setTextClient( Control textClient );
    其中,textClient 为任何一个 Control 类型的控件,可以是按钮、工具类、链接或者带图标的链接都可以显示在内容区标题栏的工具类中。例如,以下所示为内容区添加了一个图像超链接(ImageHyperlink)的代码。图像超链接也是一种表单的控件,将在下文介绍。
   //创建带图标的超链接
   ImageHyperlink imageHyperlink = toolkit.createImageHyperlink(section,SWT.CENTER);
   //设置超链接的图标
   imageHyperlink.setImage( PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_NEW_WIZARD).createImage());
   //将该图标超链接添加到内容区的工具栏中
   section.setTextClient( imageHyperlink );

24.3.4 超链接(Hyperlink)
    超链接(Hyperlink)是 Eclipse 表单中非常重要的一个控件,页面效果与在普通网页中看到的超链接非常类似,是一种带有下划线标记的标签,当获得鼠标焦点时可以变为手型,并且单击后可以响应鼠标单击事件,在网页中链接所具备的特征。
    超链接有两种,一种是只有文本的超链接(Hyperlink),一种是即可带图标又可带文本的超链接(ImageHyperlink)。事实上,ImageHyperlink是Hyperlink的子类。

1. 文本超链接
    文本超链接(Hyperlink)是最简单的超链接,可以使用 FormToolkit 以下所示的方法创建:
   //创建超链接,文字可以折行显示
   Hyperlink textLink = toolkit.createHyperlink(linkComp,"这是一个文本超链接",SWT.WRAP);
   //注册超链接事件监听器
   textLink.addHyperlinkListener( new IHyperlinkListener(){
    public void linkEntered(HyperlinkEvent e) {
     //光标进入超链接区域
    }
    public void linkExited(HyperlinkEvent e) {
     //光标离开超链接区域
    }

    public void linkActivated(HyperlinkEvent e) {
     //单击超链接激活时
     System.out.println("超链接被激活");
    }
   
   });

2. 图片超链接
    带有图片的超链接(ImageHyperlink)除了可以设置文本外,还可以设置链接所显示的图片。
   //创建带有图片的超链接
   ImageHyperlink imageLink = toolkit.createImageHyperlink( linkComp ,SWT.WRAP );
   //设置超链接的图标
   imageLink.setImage( Activator.getImageDescriptor("icons/alt_window_32.gif").createImage() );
   //设置超链接的文本
   imageLink.setText("这是一个图片超链接");
   //设置当鼠标放到超链接上时的图标
   imageLink.setHoverImage( Activator.getImageDescriptor("icons/samples.gif").createImage());
   //注册超链接监听器,使用HyperlinkAdapter适配器对象
   imageLink.addHyperlinkListener( new HyperlinkAdapter(){
    public void linkActivated(HyperlinkEvent e) {
     System.out.println("超链接被激活");
    }
   });
   linkSection.addExpansionListener(new ExpansionAdapter() {
    public void expansionStateChanged(ExpansionEvent e) {
     // 根据控件的新尺寸重新定位和更新滚动条
     form.reflow(true);
    }
   });

3. 超链接组(HyperlinkGroup)
    如果一个表单中有很多个超链接,此时就需要有一套管理机制来集中管理这些超链接,这就是超链接组(HyperlinkGroup)。每个超链接通过 add 方法添加到 HyperlinkGroup 中,使用 FormToolkit 对象创建超链接时,已经自动将该链接添加到超链接组中,此时通过 getHyperlinkGroup() 方法可以获得表单中超链接组。例如以下代码:
   //创建超链接,文字可以折行显示
   Hyperlink textLink = toolkit.createHyperlink(linkComp,"这是一个文本超链接",SWT.WRAP);
   //创建带有图片的超链接
   ImageHyperlink imageLink = toolkit.createImageHyperlink( linkComp ,SWT.WRAP );
   //获得超链接组
   HyperlinkGroup group = toolkit.getHyperlinkGroup();

    这样获得 HyperlinkGroup 对象后,就可以统一为所有的超链接进行设置和处理。HyperlinkGroup 提供如下方法:
◇ setActiveBackground(Color newActiveBackground):设置激活超链接时的背景色。
◇ setActiveForeground(Color newActiveForeground):设置激活超链接时的前景色。
◇ setBackground(Color newBackground):设置超链接的背景色。
◇ setForeground(Color newForeground):设置超链接的前景色。
◇ setHyperlinkUnderlineMode(int Mode):设置超链接下划线的样式。
◇ getLastActivated():获得上一次所激活的超链接。

     这样,通过 HyperlinkGroup 对象,可以统一对链接组中的链接进行统一的设置和管理。

24.3.5 表单文本(FormText)
    FormText 针对文本能够提供以下功能:
◇ 支持无格式文本的自动换行。
◇ 支持将无格式文本中任意一个以http://开头的文本自动转换为超链接控件。
◇ 支持带有 XML 标记的文本。


1. 超链接转化
    以下代码为使用普通的文本转化成超链接的代码:
   //创建一个表单本文对象,true表示当该表单获得焦点时,将超级链接的焦点设置为可见
   FormText formText = toolkit.createFormText(form.getBody(), false);
   //定义一个字符串,其中包含http://格式的字符
   String text = "这是无格式的文本"+"这是带有超链接的文本 http://www.eclipse.org 将自动转化为超链接,<a> >";
   //设置文本false表示不转化tag标记,true表示转化超链接
   formText.setText(text, false, true);
   //注册单击超链监听器
   formText.addHyperlinkListener(new HyperlinkAdapter(){
    //当单击链接时
    public void linkActivated(HyperlinkEvent e) {
     //打印出单击的超链接地址
     System.out.println("单击了该超链接:"+e.getHref());
    }
   });

代码运行后的效果如图:


    使用 FormText 转化超链接时主要注意以下几个问题:
◇ FormText 对象只将 http:// 及其以后的字符转化成超链接,使用空格结束超链接。
◇ 使用以下所示的方法设置文本和转化的规则:
public void setText(String text, boolean parseTags, boolean expandURLs)
    其中,text 为显示的字符串;parseTags 若为 true 表示将 xml 格式的标记转化成表单的格式;expandURLs 所为 true 则将 http:// 开头格式的文本自动转化为超链接,否则将以普通文本方式显示。
◇ 若想判断不同的超链接,可以为表单文本注册 Hyperlink 事件,通过 e.getHref() 可以获得单击超链接的目标地址。

2. XML 标记


    Views 目录下的 demo.xml 内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<form>
<p vspace="false">这是一个段落,使用"p"标记,可以使用 <a href="action1">超链接</a> ,也可以 
   <b>加粗</b> 文本. 还可以显示图片 <img href="image1"/> 功能很强大。
</p>
<li style="text" value="1.">这是一组文本列表,使用"li"标记,与段落一样 可以使用 <a href="action1">超链接</a> ,也可以 
   <b>加粗</b> 文本. 还可以显示图片 <img href="image1"/> 功能也很强大。
</li>
<li style="text" value="2.">这是第二个列表</li>
<li style="text" value="3." bindent="20" indent="40">这是第三个列表</li>
<li >这是一个无序列表,默认为"bullet"样式</li>
<li style="image" value="image1">这是带有图片的无序列表</li>
<p><span color="headColor" font="head">这是改变了文本的颜色字体的文本</span></p>
<p>这是添加了控件的文本<control href="myControl"></control></p>
</form>

    读取 demo.xml 并显示的代码如下:
   //创建一个表单本文对象,true表示当该表单获得焦点时,将超级链接的焦点设置为可见
   FormText formText = toolkit.createFormText(form.getBody(), false);
   //注册单击超链监听器
   formText.addHyperlinkListener(new HyperlinkAdapter(){
    //当单击链接时
    public void linkActivated(HyperlinkEvent e) {
     //打印出单击的超链接地址
     System.out.println("单击了该超链接:"+e.getHref());
    }
   });

   //设置文本所需要使用图片,使用第一参数为图片的key,该值可被xml标记中的<img>标记中的href引用
   formText.setImage("image1",Activator.getImageDescriptor("icons/samples.gif").createImage());
   //设置文本中所需要使用的字体,第一个参数表示字体的key,值可被<span>的font属性引用
   formText.setFont("head",form.getFont());
   //设置文本中所需要使用的颜色,第一个参数表示颜色的key,值可被<span>的color属性引用
   formText.setColor("headColor",form.getForeground());
   //设置文本中所引用的控件,第一个参数表示控件的key,值可被<control>的href属性引用
   formText.setControl("myControl",toolkit.createButton(form.getBody(),"这是一个按钮",SWT.NONE));
   //装载该与MyFormView.java同文件夹下的demo.xml文件
   InputStream is = MyFormView.class.getResourceAsStream("demo.xml"); //$NON-NLS-1$
   if (is!=null) {//若存在该文件
    //设置表单文本输入数据流
    formText.setContents(is, true);
    try {
     //最后关闭数据流
     is.close();
    }
    catch (IOException e) {
    }
   }

    下面具体分析以下 xml 文件中每个标记所表示的意义。当使用文本中包含一些 FormText 所支持的标记时,应该使用<form></form>作为根标记,在根标记中可以添加一个或多个其他常见的标记,比如<p>或<li>。
◇ <p>表示一个段落文本,可用的属性有:
    ⊙ vspace:如果设置为false,表示垂直方向上文本换行后将不留空隙,默认为true。例如以下代码:
<p vspace="false">这是一个段落</p>

◇ <li>表示一个列表,可表示有序的或无序的。可用的属性如下:
    ⊙ vspace:与<p>标记中的属性意义相同。
    ⊙ style:列表的类型,若为无需的可以设置为 bullet(默认值),此时每个列表将以一个圆点显示。若设置为有序可以使用 text,则配合 value 属性可以设置序号。也可以设置带有图片的列表,可以使用 image,同时配合 value 属性设置图片的 key 值。
    ⊙ value:配合 style 类型为 text 和 image 来使用,对 bullet 不起作用。
    ⊙ indent:列表文本的缩进的像素值。
    ⊙ bindent:列表标号缩进的像素值。

    在每个<p>和<li>标记中又可以使用以下这些标记加粗、显示图片、显示超链接的效果:
◇ img:将转化为图片,其中图片的地址使用 href 属性,图片的地址为 setImage 方法中所设置的 key 值,还可以设置属性 align,值可以为 top、middle、bottom。例如以下代码:
<img href="image1" align="middle"/>
其中,image1为 FormText 对象通过 setImage 方法设置的 key 值,如下:
formText.setImage("image1", Activator.getImageDescriptor("icons/samples.gif").createImage());

◇ a:将转换为超链接,其中也使用 href 作为超链接的目标地址。例如:
<a href="action1">超链接</a>

◇ b:表示加粗文本显示。例如:
<b>加粗</b>

◇ br:强制换行。
◇ span:可以设置一段文本的颜色和字体,与<img>标记的用法类似,属性有 color 和 font,值使用 setColor 和 setFont 代码中所设置的 key 值,例如:
<span color="headColor" font="head">这是改变了文本的颜色字体的文本</span>
其中,headColor 为 FormText 对象通过 setColor 方法设置的 key 值,如下:
formText.setColor("headColor", form.getForeground());
其中,head 为 FormText 对象通过 setFont 方法设置的 key 值,如下:
formText.setFont("head", form.getForeFont());

◇ control:此标记为 Eclipse 3.1 新增加的特性,可以将 Control 控件转化为文本中的控件。与 img 标记用法相同,通过 setControl 方法中设置的 key 值来获得控件的引用。例如以下代码可以为文本中添加控件的标记:
<control href="myControl"></control>
其中,myControl 为 FormText 对象通过 setControl 方法设置的 key 值,如下所示:
formText.setControl("myControl", tookit.createButton(form.getBody(), "这是一个按钮", SWT.NONE));

3. 使用表单文本所注意的问题
    虽然表单文本(FormText)已经提供了一些简单的转化的标记,但使用时还有以下问题需要注意:
◇ 不能嵌套标记,例如在<span>标记中不能出现<b>标记,虽然这在 html 中是允许的,但在 FormText 中却不能这样使用。
◇ 在 Eclipse 3.1 以后的版本中,可以将文本剪切、复制到剪贴板上,但对于图片和控件却不能剪切或复制。
◇ 相对于复杂 html 标记而言,FormText 的解析还比较简单。若使用复杂的 html 标记则还需要使用 Browser 浏览器控件。

24.4 表单的布局管理器
    在使用表单时,专门针对表单的特殊布局效果设计了两个新布局:
◇ 表格布局(TableWrapLayout)。
◇ 列布局(ColumnLayout)。

    这两个布局都是基于 SWT 提供的布局。这些布局管理器实现了公共接口,也可以用于 SWT 的面板容器中,但通常与 UI 表单一起使用。

    这些布局的目的是以类似与 Web 浏览器的方式管理表单布局。控件是根据表单宽度布置的。其目标是尽量保持表单的宽度并通过使表单垂直增大(根据需要使用滚动条)来弥补空间不足。