内容


使用 Eclipse Forms 让应用程序获得新生

不使用嵌入式浏览器就可获得 Web 风格的外观

Comments

背景

Eclipse Forms 是什么?在回答这个问题之前,我先向您展示一下 Eclipse Forms 的自然用法。您是否曾经使用 Eclipse 构建过插件?如果是,那么您可能认识下面这个整洁的用户界面。

图 1. PDE 的 manifest 编辑器
PDE 的 manifest 编辑器
PDE 的 manifest 编辑器

此编辑器是 Eclipse 插件开发环境(PDE)的一部分。它是第一个采用 Eclipse Forms 的编辑器,并且仍然是 Eclipse Forms 的一个范例实现。因此,我们得到了 Eclipse Forms 的一个视觉外观,那应该如何定义它呢?

Eclipse 为人熟知的原因在于能够让在它上面构建的应用程序具有原生应用程序的外观。这可能要归功于 Eclipse 的构建基础:Standard Widget Toolkit (SWT)。在其核心中,SWT 提供了一个可移植的轻量级原生 部件集,可以在不同的平台上运行。Eclipse Forms 的设计初衷是提供一种新风格的、常见于 HTML 创建工具中的用户交互。Eclipse Forms 的任务是跨所有 Eclipse 项目为创建可移植 Web 风格的 UI 提供支持。

现在可以开始介绍典型的 Hello World 示例了,后面对各种 Eclipse Forms 小部件进行描述,最后介绍一个更具体的真实示例。

Hello, Forms

开始学习新东西的好方法自然是通过一个简单的 Hello World 示例。关于 Eclipse Forms 需要了解的重要一点是,实际上您可以在能够使用 SWT 小部件的任何位置使用它的小部件。在这个简单的示例中,我们将在 Eclipse 视图中使用 Eclipse Forms。

图 2. Hello World
Hello World
Hello World
清单 1. Hello World — Eclipse Forms 版本(Snippet1.java)
public class FormView extends ViewPart {
  private FormToolkit toolkit;
  private ScrolledForm form;

  public FormView() {}

  public void createPartControl(Composite parent) {
    toolkit = new FormToolkit(parent.getDisplay());
    form = toolkit.createScrolledForm(parent);
    form.setText("Hello World");
  }
  
   public void setFocus() {
      form.setFocus();
   }

   public void dispose() {
      toolkit.dispose();
      super.dispose();
   }
 }

在清单 1 中,我们拥有一个典型的 Eclipse 视图(扩展了 ViewPart)。但是,在 createPartControl(...) 方法中,我们创建了 FormToolkit 的一个新实例。FormToolkit 负责创建 SWT 控件并进行调整以便在 Eclipse Forms 环境中使用。使用 Eclipse Forms 时,您会频繁地使用这个工具类。在下一行中,我们创建了一个新表单(基于 ScrolledForm),该表单用作表单相关内容的容器。这就是使用 Eclipse Forms 的技巧。上面清单中使用的代码可以用作一个模板,以后实践 Eclipse Forms 时可以用到。

Forms 使用一览

Eclipse Forms 之旅的下一站是介绍它所提供的实际使用的小部件。我们将介绍每个小部件并提供一小段代码片段演示其用法。最后,我们还将讨论如何调整现有的小部件以便整合到基于 Eclipse Forms 的应用程序中。

Form 和 ScrolledForm

我们要讨论的前两种基本的小部件是 forms 类型:FormScrolledForm。这些 forms 小部件可看作 Eclipse Forms 的基础并充当内容的容器(见图 3)。它们拥有标题、可选图像、可选标题下拉菜单和其他一些有用的特性(见清单 2)。

图 3. Form 示例
Form 示例
Form 示例
清单 2. Form 示例(Snippet2.java)
...
public void createPartControl(Composite parent) {
  toolkit = new FormToolkit(parent.getDisplay());
  form = toolkit.createForm(parent);
  form.setText("Snippet2");
  TableWrapLayout layout = new TableWrapLayout();
  form.getBody().setLayout(layout);
  
  toolkit.createLabel(form.getBody(), "Snippet2");
}
...

ExpandableComposite

这个小部件是一个简单的复合程序,允许显示或隐藏(即,折叠或展开)其子元素。可以选择展开形状的样式(旋转或树形),您可以根据需要选用(见图 4 和清单 3)。

图 4. ExpandableComposite 示例
ExpandableComposite 示例
ExpandableComposite 示例
清单 3. ExpandableComposite 示例(Snippet3.java)
...
public void createPartControl(Composite parent) {
  toolkit = new FormToolkit(parent.getDisplay());
  form = toolkit.createScrolledForm(parent);
  form.setText("Snippet3");
  TableWrapLayout layout = new TableWrapLayout();
  form.getBody().setLayout(layout);
  
  ExpandableComposite composite = 
    toolkit.createExpandableComposite(
      form.getBody(), 
      ExpandableComposite.TREE_NODE|
      ExpandableComposite.CLIENT_INDENT);
  composite.setText("Expand Me");
  String text = "Lots of text, Lots of text," +
  Lots of text, Lots of text, Lots of text," +
  Lots of text, Lots of text, Lots of text," +
  Lots of text, Lots of text";
  Label label = toolkit.createLabel(composite, text, SWT.WRAP);
  composite.setClient(label);
  TableWrapData td = new TableWrapData();
  td.colspan = 1;
  composite.setLayoutData(td);
  composite.addExpansionListener(new ExpansionAdapter() {
    public void expansionStateChanged(ExpansionEvent e) {
      form.reflow(true);
    }
  });
}
...

Section

section 是一种特殊类型的可展开复合程序,用于添加标题下面的可选描述。Eclipse Forms 中使用 Section 对信息分组,它可能是 Eclipse Forms 中最常用的小部件。如果您需要使用描述区中的图像或超链接,您可以在描述区中使用控件。

图 5. Section 示例
Section 示例
Section 示例
清单 4. Section 示例(Snippet4.java)
...
public void createPartControl(Composite parent) {
  toolkit = new FormToolkit(parent.getDisplay());
  form = toolkit.createScrolledForm(parent);
  form.setText("Snippet4");
  TableWrapLayout layout = new TableWrapLayout();
  form.getBody().setLayout(layout);
    
  Section section = new Section(form.getBody(), Section.TITLE_BAR | Section.TWISTIE);
  section.setText("Snippet4");
  Label label = toolkit.createLabel(section, "Snippet4", SWT.WRAP);
  section.setClient(label);
  TableWrapData td = new TableWrapData();
  td.colspan = 1;
  td.grabHorizontal = true;
  section.setLayoutData(td);
}
...

Hyperlink 和 ImageHyperlink

Hyperlink 部件用于实现基于用户单击文本 — 或悬停在文本上 — 的操作。如果您曾经使用过 HTML,就会发现这与 <a> 标记的概念非常类似。在 Eclipse Forms 中,超链接可以与 HyperlinkGroup 关联,后者管理普通颜色或激活颜色之类的事件。

图 6. Hyperlink 示例
Hyperlink 示例
Hyperlink 示例
清单 5. Hyperlink 示例(Snippet5.java)
...
public void createPartControl(Composite parent) {
  toolkit = new FormToolkit(parent.getDisplay());
  form = toolkit.createScrolledForm(parent);
  form.setText("Snippet5");
  TableWrapLayout layout = new TableWrapLayout();
  form.getBody().setLayout(layout);
    
  HyperlinkGroup group = new HyperlinkGroup(parent.getDisplay());
  
  Hyperlink link = new Hyperlink(form.getBody(), SWT.NONE);
  link.setBackground(form.getBackground());
  link.setText("Snippet5");
  link.addHyperlinkListener(new HyperlinkAdapter() {
    public void linkActivated(HyperlinkEvent e) {
      System.out.println("Snippet5");
    }
  });
    
  ImageHyperlink imageLink = new ImageHyperlink(form.getBody(), SWT.NONE);
  imageLink.setBackground(form.getBackground());
  imageLink.setText("Snippet5");
  imageLink.setImage(Activator.getImageDescriptor("icons/sample.gif").createImage());
  imageLink.addHyperlinkListener(new HyperlinkAdapter() {
    public void linkActivated(HyperlinkEvent e) {
      System.out.println("Snippet5");
    }
  });
    
  group.add(link);
  group.add(imageLink);
}
...

FormText 和 ScrolledFormText

此部件是一个只读文本控件,可以通过解析特殊的 XML 标记(与 HTML 类似)呈现包装的文本。此外,它还允许将链接(即 http://www.eclipse.org)自动解析为超链接(如果您需要的话)。

图 7. FormText 示例
FormText 示例
FormText 示例
清单 6. FormText 示例(Snippet6.java)
...
public void createPartControl(Composite parent) {
  toolkit = new FormToolkit(parent.getDisplay());
  form = toolkit.createScrolledForm(parent);
  form.setText("Snippet6");
  TableWrapLayout layout = new TableWrapLayout();
  form.getBody().setLayout(layout);
  
  FormText text = toolkit.createFormText(form.getBody(), true);
  text.setText("Read http://planet.eclipse.org", false, true);
  TableWrapData td = new TableWrapData(TableWrapData.FILL);
  td.colspan = 1;
  text.setLayoutData(td);
}
...

FormDialog

此部件是托管表单的通用对话框。如果您希望在对话框中使用 Eclipse Forms,此类可为您提供帮助(见图 8 和清单 7)。

图 8. FormDialog 示例
FormDialog 示例
FormDialog 示例
清单 7. FormDialog 示例
...
  MyFormDialog dialog = new MyFormDialog(shell);
  dialog.create();
  dialog.getShell().setSize(800, 600);
  dialog.getShell
  dialog.open();
...

调整现有的小部件

Eclipse Forms 的一个初始设计目标是,实现对现有 SWT 控件的重用。在 Eclipse Forms 中表单主体没有什么特别之处。它不断地进行复合调整。

要使用自己的 SWT 部件(该部件如果不是使用 FormToolkit 轻松创建的话),您只需对其进行调整。调整部件通过使用 FormToolkit 类完成(见图 9 和清单 8)。

图 9. 调整部件的示例
调整部件的示例
调整部件的示例
清单 8. 调整部件的示例(Snippet7.java)
...
public void createPartControl(Composite parent) {
  toolkit = new FormToolkit(parent.getDisplay());
  form = toolkit.createScrolledForm(parent);
  form.setText("Snippet7");
  TableWrapLayout layout = new TableWrapLayout();
  form.getBody().setLayout(layout);
  
  Label label1 = new Label(form.getBody(), SWT.NONE);
  label1.setText("Snippet7 (not adapted)");
    
  // note, we could've just used toolkit.createLabel(...)
  Label label2 = new Label(form.getBody(), SWT.None);
  label2.setText("Snippet7 (adapted)");
  toolkit.adapt(label2, true, true);
}
...

Forms 示例

在一个更真实的示例中,我将使用一个 Eclipse 项目。在 Eclipse Communications Framework (ECF) 项目中,我们有一个显示在线联系人的 UI。在该 UI 中,我们希望支持一些优秀的工具提示。使用 Eclipse Forms 是完成此任务的首选方法。清单 9 演示了如何使用 Eclipse Forms 创建一个自定义的工具提示。

图 10. Forms ToolTip 示例
Forms ToolTip 示例
Forms ToolTip 示例
清单 9. Forms ToolTip 示例(Snippet8.java)
...
public void createPartControl(Composite parent) {
  toolkit = new FormToolkit(parent.getDisplay());
  form = toolkit.createScrolledForm(parent);
  form.setText("Snippet8");
  TableWrapLayout layout = new TableWrapLayout();
  form.getBody().setLayout(layout);

  Label label1 = new Label(form.getBody(), SWT.NONE);
  label1.setText("Snippet8");
    
  // create a tooltip
  ToolTip tooltip = new MyTooltip(label1);
  tooltip.setPopupDelay(200);
}
...
private class MyTooltip extends ToolTip {

  public MyTooltip(Control control) {
    super(control);
  }

  protected Composite createToolTipContentArea(Event event,
      Composite parent) {
    FormToolkit toolkit = new FormToolkit(parent.getDisplay());
    FormColors colors = toolkit.getColors();
    Color top = colors.getColor(IFormColors.H_GRADIENT_END);
    Color bot = colors.getColor(IFormColors.H_GRADIENT_START);

    // create the base form
    Form form = toolkit.createForm(parent);
    form.setText("Snippet8");
    form.setTextBackground(new Color[] { top, bot }, new int[] { 100 }, true);
    GridLayout layout = new GridLayout();
    layout.numColumns = 3;
    form.getBody().setLayout(layout);

    // create the text for user information
    FormText text = toolkit.createFormText(form.getBody(), true);
    GridData td = new GridData();
    td.horizontalSpan = 2;
    td.heightHint = 100;
    td.widthHint = 200;
    text.setLayoutData(td);

    text.setText(
      "<form><p7gt;snippet8</p><p>snippet8</p></form>", 
      true, 
      false);

    // create the picture representing the user
    td = new GridData();
    td.horizontalSpan = 1;
    td.heightHint = 100;
    td.widthHint = 64;
    FormText formImage = 
      toolkit.createFormText(form.getBody(), false);
    formImage.setText(
      "<form><p><img href=\"image\"/></p></form>", 
      true, false);
    formImage.setLayoutData(td);

    Image image = 
      Activator.getImageDescriptor("icons/sample.gif").createImage();
    formImage.setImage("image", image);

    return parent;
  }
}

使用上面描述的示例,我们可以很轻松地将基于 Eclipse Forms 的工具提示集成到 ECF 中。

图 11. 工具提示正常工作
工具提示正常工作
工具提示正常工作

结束语

本文的目的是对 Eclipse Forms 做一个简要介绍并提供一些示例。通过一些易于理解的代码片段和一个可下载的样例项目,我已完成这一任务。我希望您现在能够将 Eclipse Forms 放入您的工具箱中,以便开发 Eclipse 应用程序时使用。

特别致谢 Dejan Glozic 和 User Assistance 团队,感谢他们对本文的审核。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source
ArticleID=266753
ArticleTitle=使用 Eclipse Forms 让应用程序获得新生
publish-date=11052007