内容


利用 Rational Software Architect pluglet 进行快速视图的开发

Comments

概述

扩展一个基于 Eclipse 的开发环境包括创建新的视图。值得庆幸的是 IBM 有一个被很好文档化的实现它的能力(我所喜爱的参考文献在资源部分可以找到)。 有一个不是那么好的消息是 IBM® Rational® Software Architect 目前是基于 Eclipse 3.0.x 的,它需要很多的内存,而且启动一个运行时间的工作台会产生很长的时间延迟从而影响开发效率。

幸运的是,这个构建 Rational Software Architect 中的 pluglet 的特性能够让您在不启动一个新的运行工作台的情况下进行快速的尝试各种算法。不幸的是,创建 Eclipse 视图的环境是在一个插件里,而所有的插件都必须在一个运行的工作台中进行测试。

结果是 Eclipse 视图可以从 JFace viewer 中构造。同时您还可以在 pluglet 中创建 JFace viewer。因此,您可以利用 pluglet 快速开发您的视图,并且一旦您有了数据、布局设计,以及您所需要的行为,就可以将关键的组件部署到您的插件中去。

这篇文章的剩下部分展示了这些零散的片断是怎样有机结合起来的。

开始的时候您需要有一个问题的陈述。您的任务是创建一个能够提供基本度量信息的视图。从概念上讲,这个视图看起来应该跟表格1一样:

表1.基本度量信息
类名称操作的数量属性的数量是否有文档?
Class1123
Class240没有
Class321

Step 1: 步骤1:获取数据

当我创建视图时,会提出几个问题:

  • 我应该将什么样的信息置于这个视图中?
  • 布局设计是什么样的?

一个视图的复杂性的确是依赖于对它用途的期望程度。在您的例子中,您需要提供一个上下文,比如,假设这个视图的上下文是由开放模型中的一个包(package)所提供的。

在 Eclipse UML2(统一建模语言2)术语中,您要考虑在包上的 ownedMembers 操作。

一般情况下,我将通过在 Model Enumeration 例子的基础上创建一个新的 pluglet 来开始这项工作。这个 pluglet 已经有一个创建好的框架,可以在 model browser 中对当前的选择项进行挑选,因此它是一个相当好的选择(它同时还是可以立即使用的唯一选择)。

创建一个pluglet

  1. 开始创建一个 pluglet 项目,如图1所示:
图1.创建一个 pluglet 项目的向导
selecting Pluglets Project
  1. 指定一个名称 (在这个例子中为 ViewPluglets), 如图2所示:
图2.为这个 pluglet 项目命名
在 New Pluglets Project 窗口给这个项目命名
在 New Pluglets Project 窗口给这个项目命名
  1. 简单地点击Finish!

您现在可以创建一个 pluglet,通过以下步骤来创建:

  1. 选择一个 Pluglet 向导,如图3所示:
图3.选择一个 Pluglet 向导
从向导的选项中,选择 Pluglet
从向导的选项中,选择 Pluglet
  1. 给这个插件命名为 ViewTest, 如图4所示:
图4.给这个 Pluglet 命名
为这个 Pluglet 提供一个源文件、项目,以及名称
为这个 Pluglet 提供一个源文件、项目,以及名称
  1. 再次点击 Finish

修改这个 Pluglet

接下来的步骤是为 logObject 操作修改 logObject Pluglet 的源代码。

原始代码如下表所列:

 /**
  * Logs the specified object's toString() and its content
  * @param object The object to log
  * @param indent The string to prefix to the object's toString()
  */
  private void logObject(Object object, String indent) {
 // Log object
  if (null != object) {
  out.println(indent + object.toString());
  } else {
  out.println(indent + "<null>"); //$NON-NLS-1$
  }

  // Log contents
  if (object instanceof EObject) {
  Iterator contents = ((EObject)object).eContents().iterator();
  while (contents.hasNext()) {
  logObject(contents.next(), indent + "\t"); //$NON-NLS-1$
  }
  }
  }
  1. 第一个修改是要删除 logObject 的内容和 Log contents 部分的内容:
    private void logObject(Object object, String indent) {

        if (object instanceof EObject) {


        }
    }

因此,对于这一点,您已经彻底消除了这个插件例子的递归性,并且您要准备开始对这个模型提出几个问题。

  1. 通过检查和打印这个包的名称确保您还在正确的道路上进行工作:
    private void logObject(Object object, String indent) {

        if (object instanceof EObject) {
            if (object instanceof org.eclipse.uml2.Package) {
                Package p = (Package) object;
                out.println("Found a package " + p.getName() );
            }

        }
    }

因此,如果您选定了一个包,那么就可以把它的名称打印出来。

  1. 通过打开任意一个模型,选择一个模型单元,并运行这个 pluglet,从而对它进行确认。当您选择了一个包,在这个控制台中看到的应该仅仅是“找到一个包……”的消息。

既然您已经建立了您的上下文环境,您就可以对这个模型提出问题了。

  1. 对于您问题的陈述,您可以问“什么是您自己的成员?它的代码应该是这样的:
if (object instanceof EObject) {
        if (object instanceof org.eclipse.uml2.Package) {
            org.eclipse.uml2.Package p = (org.eclipse.uml2.Package) object;
            out.println("Found a package " + p.getName() );
            for (Iterator it = p.getMembers().iterator(); it.hasNext();) {
                NamedElement member = (NamedElement) it.next();
                out.println("Found member: " + member.getName());
            }
        }
    }

注意:allOwnedElements 与 getMembers 有很大的区别。allOwnedElements 是包含在这个包中所有层次的元素,而 getMembers 仅仅是针对那些“最顶端的”元素;

提出问题

  1. 既然您已经知道了这个包中的成员,您可以准备问这些问题了——你属于 UML2 类吗?如果是,你就调用 “dumpClass”程序,如您刚才所写的:
   for (Iterator it = p.getMembers().iterator(); it.hasNext();) {
        NamedElement member = (NamedElement) it.next();
        out.println("Found member: " + member.getName());
        if (member instanceof Class) {
            Class myclass = (Class) member;
            dumpClass(myclass);
        }
    }

现在,dumpClass 看起来是这样的:

     private void dumpClass(Class c) {
     }

所以,您现在处于这样一个上下文中,在这里您可以:

  • 拥有一个 UML2 类
  • 准备好对这个类提出问题

提什么样的问题呢?啊哈——回到问题的陈述,可以有下面的例子:

  • 您叫什么名字?
  • 您有多少个操作?
  • 您有多少种属性?
  • 您有文档吗?

好了,开始的三个都相对比较的简单。

  1. 首先,可以得到以下结果:
    private void dumpClass(Class c) {
        String classname = c.getName();
        int opcount = c.getOwnedOperations().size();
        int atcount = c.getOwnedAttributes().size();
    }
  1. 为了回答您有文档吗?这个问题, 最简单的方法是写下一个实用函数:
    private boolean hasDocumentation(NamedElement ne) {
        String result = "";
        for (Iterator it = ne.getOwnedComments().iterator(); it.hasNext();) {
            org.eclipse.uml2.Comment cmt = (org.eclipse.uml2.Comment) it.next();
            result = result + cmt.getBody();
        }
        return result.length() > 0;
    }

这个时候,您应该已经准备好来回答这些出现在您的问题大纲中的问题了:

    private void dumpClass(Class c) {
        String classname = c.getName();
        int opcount = c.getOwnedOperations().size();
        int atcount = c.getOwnedAttributes().size();
        boolean hasdocs = hasDocumentation(c);
    }

稍微回顾一下,您所处理的抽象类看起来好像是由一种新的类来表达的:

private class ClassMetrics {
    String name;
    int opcount;
    int atcount;
    boolean hasDocs;

    public ClassMetrics() {
        super();
    }
    public ClassMetrics(org.eclipse.uml2.Class c) {
        super();
        name = c.getName();
        opcount = c.getOwnedOperations().size();
        atcount = c.getOwnedAttributes().size();
        hasDocs = hasDocumentation(c);
    }
    public String toString() {
        return "ClassName: " + name +
                                            " Ops: " +  opcount +
                                            " Atts: " + atcount +
                                            " Docs: " + hasDocs;
    }
    private boolean hasDocumentation(NamedElement ne) {
        String result = "";
        for (Iterator it = ne.getOwnedComments().iterator(); it.hasNext();) {
            org.eclipse.uml2.Comment cmt = (org.eclipse.uml2.Comment) it.next();
            // You only want those comments with the
            // Default::Documentation stereotype applied!
            Stereotype st = cmt.getAppliedStereotype("Default::Documentation");
            if (st != null) {
                result = result + cmt.getBody();
            }
        }
        return result.length() > 0;
    }
}

如果您目光真的再远一点,您就能够构造一个为给定包返回所有度量的操作。

  1. 您的代码应该看起来跟下面所示的一样:
    // return an array of ClassMetrics
    private Object[] getPackageClassMemberMetrics(Package p) {
        List theTable = new ArrayList();
        for (Iterator it = p.getMembers().iterator(); it.hasNext();) {
            NamedElement member = (NamedElement) it.next();
            if (member instanceof Class) {
                Class myclass = (Class) member;
                theTable.add(new ClassMetrics(myclass));
            }
        }
        return theTable.toArray();
    }

这个时候是试验这些代码并确保您得到了您所希望功能的最佳时机。

试验

  1. 重构您的原始代码,使其看起来如下所示:
private void logObject(Object object, String indent) {

    if (object instanceof EObject) {
        if (object instanceof org.eclipse.uml2.Package) {
            org.eclipse.uml2.Package p = (org.eclipse.uml2.Package) object;
            out.println("Found a package " + p.getName() );
            Object[] pkgmetrics = getPackageClassMemberMetrics(p);
            for (int i = 0; i < pkgmetrics.length; i++) {
                ClassMetrics cm = (ClassMetrics) pkgmetrics[i];
                out.println(cm);
            }
        }
    }
}

从我的简单的例子中,可以得到下面的信息:

Found a package Package1
ClassName: Class1  Ops: 1 Atts: 1 Docs: true
ClassName: Class2  Ops: 2 Atts: 1 Docs: false
ClassName: Class3  Ops: 4 Atts: 3 Docs: false

非常重要的一点是您已经能够从您的包中更容易地采集信息,以及您能够提供一个包含您想要在您的视图中展示的信息的数组。

这个时候,您已经可以泰然自若地进行下一个阶段了。您知道怎么获取您想要的数据:在一定的包上下文环境中,返回包所拥有的成员(类)的度量。

第二步:构建一个 JFace viewer

JFace viewer 是构建在 SWT(标准窗口小部件工具箱)窗口部件之上的抽象层(查看参考资源可以获得更多关于 SWT 的参考资料)。在您的 pluglet 中开始构建您的 JFace viewer。

开始构建

  1. 您最初的设计方案是您要使用 TableViewer。您可以构造一个实用的函数来构建您的 viewer。

现在您还没有向表中添加数据,但是您要定义列的个数以及列头。

    public Composite showViewer(Composite parent, org.eclipse.uml2.Package p) {
        Composite c = new Composite(parent, SWT.NONE);
        c.setLayout(new FillLayout());

        Table table;
        TableViewer viewer = new TableViewer(c, SWT.MULTI | SWT.H_SCROLL
                | SWT.V_SCROLL);
        table = viewer.getTable();

        int width = 100;

        TableColumn c1 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c1.setText("Class Name");
        c1.setWidth(width);

        TableColumn c2 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c2.setText("Number of Operations");
        c2.setWidth(width);

        TableColumn c3 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c3.setText("Number of Attributes");
        c3.setWidth(width);

        TableColumn c4 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c4.setText("Has documentation");
        c4.setWidth(width);

        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        return c;
    }
  1. 现在,为了实际地显示它,您要编写更多的代码:
    private void showview(org.eclipse.uml2.Package p) {
        Shell shell = new Shell();
        shell.setText("Metrics Prototype");
        shell.setLayout(new FillLayout());

        Composite composite = showViewer(shell, p);

        shell.open();
        Display disp = shell.getDisplay();
        while (!shell.isDisposed()) {
            if (!disp.readAndDispatch())
                disp.sleep();
        }

    }
  1. 您可以通过简单地将这个函数添加到您的 logObject 程序中的方式,从您的 pluglet 中调用它。
private void logObject(Object object, String indent) {
        if (object instanceof EObject) {
            if (object instanceof org.eclipse.uml2.Package) {
                org.eclipse.uml2.Package p = (org.eclipse.uml2.Package) object;
                out.println("Found a package " + p.getName() );
                Object[] pkgmetrics = getPackageClassMemberMetrics(p);
                for (int i = 0; i < pkgmetrics.length; i++) {
                    ClassMetrics cm = (ClassMetrics) pkgmetrics[i];
                    out.println(cm);
                }
                showview(p);
            }
        }
    }
  1. 当您运行您的 pluglet 时,您看到的应该如图5所示(在这篇文章中我对视图稍微进行了尺寸的调整工作——通常情况下,我是不会这么做的。):
图5. Metrics Prototype 视图
a view with columns for class name, number of operations, and so on
a view with columns for class name, number of operations, and so on

现在您需要考虑如何将数据导入到这个 viewer 中,以及如何表达这些数据。JFace viewer 通过有两个类来提供这个信息:

  • 视图内容提供者
  • 视图标签提供者
  1. 将这些代码添加到您的 pluglet 中去:
private class MetricsContentProvider implements IStructuredContentProvider {} {
}
public class MetricsLabelProvider extends LabelProvider implements ITableLabelProvider{
}

Eclipse 会告诉您还存在一些问题——这些类必须实现一些特定的方法。Eclipse 还可以更容易地添加这些必要的方法。

  1. 6. 如果您要选择您的类名称(在这个例子中是 MetricsContentProvider),可以从这个上下文菜单中选择 Source > Override/Implement methods (并清除 Generate method comment 选项),您应该可以看到如图6所示的视图:
图6.选择重载或者实现的方法
view showing which methods are selected by default
view showing which methods are selected by default

结果是(稍微进行了整理):

    private class MetricsContentProvider implements IStructuredContentProvider {
        public Object[] getElements(Object inputElement) {
            return null;
        }
        public void dispose() {
        }
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    }
  1. 用同样的方法来处理标签提供者:
    public class MetricsLabelProvider extends LabelProvider implements
            ITableLabelProvider {
        public Image getColumnImage(Object element, int columnIndex) {
            return null;
        }
        public String getColumnText(Object element, int columnIndex) {
            return null;
        }
    }

现在,您先前所做的一些决定开始发挥作用——您要确保您已经构造了可以返回对象的数组。您将使用 MetricsContentProvider 的 getElements 程序。

  1. 进行以下的更改:
    private class MetricsContentProvider implements IStructuredContentProvider {
        public Object[] getElements(Object inputElement) {
            if (inputElement instanceof Package) {
                Package p = (Package) inputElement;
                return getPackageClassMemberMetrics(p);
            } else
                return null;
        }
        public void dispose() {
        }
        public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
        }
    }

现在,您已经获取了数据——您只需要适当地显示它们的值。那就是标签提供者 所处的位置。在一个TableViewer中,您可以同时显示图标和文本。您的问题陈述需要这个文本,因此您需要将注意力放在 getColumnText 方法上。

它可以帮助在每一行的每一列调用 getColumnText方法。在您的数据模型中对每一行所起作用的(ClassMetrics)是一个 ClassMetrics 对象。在这个列的基础上您需要返回适当的文本。对于列1,您需要这个类的名称。列2,操作的数量等等。注意 getColumnText 期望返回一个字符串,因此您可能需要进行数据处理。

  1. 对 getColumnText 最初的删减类似于:
public class MetricsLabelProvider extends LabelProvider implements
   ITableLabelProvider {

      public Image getColumnImage(Object element, int columnIndex) {
        return null;
    }
      public String getColumnText(Object element, int columnIndex) {
    // you expect the element to be an instance of a ClassMetrics object
    ClassMetrics cm = (ClassMetrics) element;
    switch (columnIndex) {
        case 0 : // the class name
                             return cm.name;
        case 1 : // the count of operations
            return ""  + cm.opcount;
        case 2 : // the count of attributes
            return "" + cm.atcount;
        case 3 : // has documentation?
            return "" + cm.hasDocs;
        default :
            return "";
        }
    }
}
  1. 在构建您的 JFace viewer 的最后步骤是将 viewer 关联到内容和标签提供者,并适当地调整您的输入(在 viewer.setContent Provider、viewer.setLabelProvider 和 viewer.setInput 中)。
    public Composite showViewer(Composite parent, Package p) {
        Composite c = new Composite(parent, SWT.NONE);
        c.setLayout(new FillLayout());

        Table table;
        TableViewer viewer = new TableViewer(c, SWT.MULTI | SWT.H_SCROLL
                | SWT.V_SCROLL);
        table = viewer.getTable();

        int width = 100;

        TableColumn c1 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c1.setText("Class Name");
        c1.setWidth(width);

        TableColumn c2 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c2.setText("Number of Operations");
        c2.setWidth(width);

        TableColumn c3 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c3.setText("Number of Attributes");
        c3.setWidth(width);

        TableColumn c4 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c4.setText("Has documentation");
        c4.setWidth(width);

        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        viewer.setContentProvider(new MetricsContentProvider());
        viewer.setLabelProvider(new MetricsLabelProvider());

        viewer.setInput(p);
        return c;
    }
  1. 用您选择的测试包调用您的 pluglet,您应该可以看到(修改以后)如图7所示的页面:
图7.带有数据的 Metrics Prototype 视图
这个视图中显示了于表1类似的信息
这个视图中显示了于表1类似的信息

这就是您所寻找的!您已经准备好利用您所学到的来创建您的插件。

步骤3:创建插件

至少您需要提供的是能够满足您的问题陈述的插件,这个插件能够贡献一个视图。这也是很容易做到的。

创建一个提供视图的插件

  1. 开始创建一个新的插件项目。给这个项目命名为 com.field.ibm.MetricsView, 如图8所示。
图8.给这个新插件项目命名
提供项目名称,内容以及设置
提供项目名称,内容以及设置
  1. 在下一个页面接受默认设置,这时您要选择您所创建插件的种类,如图9所示,它是 Plug-in with a view
图9.选择这个插件的类型
从列表中选择一个可利用的类型
从列表中选择一个可利用的类型
  1. 下一步,选择Table viewer 作为视图类型,如图10所示。
图10.选择一个视图类型
在 Main 视图设置中,选择 Table Viewer作为这个viewer的类型
在 Main 视图设置中,选择 Table Viewer作为这个viewer的类型
  1. 然后选择适当的特性,如图11所示:
图11.选择特性
选择Add Actions特性
选择Add Actions特性

事先考虑一下,为这些行为提供 hook 是值得的。或许您应该将视图中的内容导出到 CSV 或者 XML 中?(当然,那又是一个不同的文章话题)。

最后,您的插件已经创建好,如图12中浏览器中所示:

图12.查看这个插件项目
viewing the project tree details

不管您是否相信,您已经完成了创建和组装新视图的大部分重要的工作。

在您进一步完成工作之前,您需要确保您已经能够从这个插件来访问 Rational Software Architect 建模组件了。

  1. 如果您双击这个 plugin.xml,然后选择 Dependencies 标签,您应该看到如图13所示的页面:
图13.查看依赖
specifying the list of plug-ins required to operate yours
specifying the list of plug-ins required to operate yours
  1. 您需要通过 Add 按钮将“com.ibm.xtools.modeler”添加到这个列表中。

修改 Java 源代码

一旦您完成了这项工作(并保存了plugin.xml文件),您就应该准备为您的新视图考虑 Java™ 源代码了。

  1. 打开 MetricsView.java,您首先考虑的是实例内容和标签提供者。这些看起来是不是很熟悉?
    class ViewContentProvider implements IStructuredContentProvider {
        public void inputChanged(Viewer v, Object oldInput, Object newInput) {
        }
        public void dispose() {
        }
        public Object[] getElements(Object parent) {
            return new String[] { "One", "Two", "Three" };
        }
    }
    class ViewLabelProvider extends LabelProvider implements ITableLabelProvider {
        public String getColumnText(Object obj, int index) {
            return getText(obj);
        }
        public Image getColumnImage(Object obj, int index) {
            return getImage(obj);
        }
        public Image getImage(Object obj) {
            return PlatformUI.getWorkbench().
            getSharedImages().getImage(
                                                 ISharedImages.IMG_OBJ_ELEMENT);
        }
    }
  1. 也要注意 createPartControl 方法:
    public void createPartControl(Composite parent)
    {
        viewer = new TableViewer(parent,
              SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);
        viewer.setContentProvider(new ViewContentProvider());
        viewer.setLabelProvider(new ViewLabelProvider());
        viewer.setInput(getViewSite());
        makeActions();
        hookContextMenu();
        contributeToActionBars();
    }

这个看起来又比较熟悉。您现在可以把代码从您的 pluglet 中移到这个 MetricsView 类了。特别强调的是,您想要的是 ClassMetrics 类,标签和内容提供者,以及 getPackageClassMemberMetrics 方法。(只需要拷贝和粘贴。)您还需要获取部分 showViewer 代码。

(既然您刚才已经拷贝和粘贴了,我们将不会显示所有的粘贴代码,而要关注 createPartControl 的主要变化。)

  1. 当您完成了前面的工作并将 showViewer 的代码添加到了 createPartControl,您最终的版本应该看起来是这样的:
    public void createPartControl(Composite parent) {
     viewer = new TableViewer(parent,
             SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);

        Table table;
        table = viewer.getTable();

        int width = 100;

        TableColumn c1 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c1.setText("Class Name");
        c1.setWidth(width);

        TableColumn c2 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c2.setText("Number of Operations");
        c2.setWidth(width);

        TableColumn c3 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c3.setText("Number of Attributes");
        c3.setWidth(width);

        TableColumn c4 = new TableColumn(table, SWT.LEFT | SWT.READ_ONLY);
        c4.setText("Has documentation");
        c4.setWidth(width);

        table.setHeaderVisible(true);
        table.setLinesVisible(true);

        viewer.setContentProvider(new MetricsContentProvider());
        viewer.setLabelProvider(new MetricsLabelProvider());

        viewer.setInput(getPackage());

        makeActions();
        hookContextMenu();
        contributeToActionBars();
    }
  1. 为了给这个视图提供输入,需要创建一个 helper 函数:
    private org.eclipse.uml2.Package getPackage() {
        List elements = UMLModeler.getUMLUIHelper().getSelectedElements();
        Element elem = (Element) elements.get(0);
        if (elem instanceof Package) {
            return (Package) elem;
        } else     return elem.getNearestPackage();
    }

因此,如果在这个模型中您还没有选择一个包,您可以使用最近的一个!

最后,添加代码并允许您手工更新这个视图。

添加最后的代码

  1. 作为第一个步骤,无论您在哪找到它们(MetricsView.java)都应该删除action2通过插件向导添加的),并为action1 修改代码。如下所示:
    private void makeActions() {
        action1 = new Action() {
            public void run() {
                viewer.setInput(getPackage());
                viewer.refresh();
            }
        };
        action1.setText("Refresh");
        action1.setToolTipText("Refresh Metrics View");
        action1.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
            getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
    }

这可以让您在选择不同的包的时候能够强制这个视图的更新。(另一篇文章将告诉读者,如何设置当 Rational Software Architect UML model navigator 中被选择的元素发生变化时,使其自身自动更新的特性。)

  1. 为了测试您的新插件,创建一个新的运行时工作台的配置,并明确选择来启动您的新插件,如图14所示。
图14.启动您的插件
select your plugin and click Run to launch it
select your plugin and click Run to launch it
  1. 在启动这个运行时工作台以后,在您的测试模型中选择一个包,您展示的视图如15所示:
图15.选择视图进行显示
在这个Show View窗口中,选择您的视图并点击OK
在这个Show View窗口中,选择您的视图并点击OK

14.这时点击 OK可以显示您的新的度量视图!(图16)

图16.新的度量视图
您的视图现在是Modeling窗口中的一个标签
您的视图现在是Modeling窗口中的一个标签

总结

这个时候您可以为胜利欢呼了!(事实上,您可以做得更多——比如,如果您改变了选择,可以自动更新这个视图,但是那又是另外一个话题了。)


下载资源


相关主题


评论

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=237271
ArticleTitle=利用 Rational Software Architect pluglet 进行快速视图的开发
publish-date=06212007