知识大全 关于Eclipse插件开发之定制向导(图)

Posted 向导

篇首语:要须心地收汗马,孔孟行世目杲杲。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 关于Eclipse插件开发之定制向导(图)相关的知识,希望对你有一定的参考价值。

关于Eclipse插件开发之定制向导(图)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

   Invokatron的历史    首先 我们详细说明一下Invokatron本身 在前面的文章中我们讨论过 Invokatron是一个生成Java代码的的图形工具 你可以简单地通过拖放操作建立类的方法 拖入的方法被编辑的方法(也就是插件) 调用 我们将让数据来驱动应用程序的设计 在后面一篇文章中 我们将开发这个GUI 现在我们需要做的是 找到插件将输入和存储的重要数据 它通常被称为应用程序的模型(model) 在设计这个系统的时候 我们需要考虑下面一些内容     · 哪些细节数据需要保存?    · 这些数据在内存中用什么来表现?POJO JavaBean还是EJB?    · 这些数据的存储格式是怎样的?数据库表 XML文件 属性文件还是串行二进制文件?    · 输入数据的方式有哪几种?用 新建文件 向导还是在文档属性页面上使用弹出对话框 用编辑器绘制 在文本编辑器中输入的其它向导?    在我们继续工作之前必须回答这些问题 不可能有适合所有项目的答案 它完全依赖于你的需求 在我们的例子中 我做出了一些随意的 可能有问题的决定 如下所示     · 一个Java类 它包含类名 程序包 超类(superclass)和实现接口 我们以它为基础 在后面的文章中添加更多数据     · 我将把数据表现为扩展Properties类的类 它建立了编辑器的 文档类     · 我将使用的格式是属性文件 很容易使用Properties类来分析它     · 在 新建文件 向导中 我将先寻找数据 接着让用户改变属性窗口或文本编辑器中的数据 这个步骤将在下一篇文章中完成      Document(文档)类    下一步是编写文档类 建立一个新程序包(invokatron model)和一个新类(InvokatronDocument) 下面是我们的文档类的开头     public class InvokatronDocument  extends Properties    public static final String PACKAGE = package ;  public static final String SUPERCLASS = superclass ;  public static final String INTERFACES = interfaces ;      使用Properties类可以更简单地分析和保存我们的数据 Getter和 setter不是必须的 但是如果你想要 也可以加上它们 这个类还没有完成 我们将添加一个接口 在后面的部分中Eclipse需要使用它     有了这个类之后 我们要获取一个属性就非常简单了     String package =document getProperty(InvokatronDocument PACKAGE);     定制向导    请看一看前面的文章中所出现的向导 你应该记得 我们可以通过点击(我们自己添加的)工具条按钮或者菜单项来访问它 图 是它的界面    >    它只有一个页面 右上角没有图片 我们想输入更多的信息 并提供一个很好的图片 换句话说 我们希望定制这个向导     我们来分析一下这个向导 请打开InvokatronWizard java文件 请注意这个类是如何扩展Wizard并实现INewWizard接口的 你应该理解它里面的很多方法 为了定制向导 我们简单地调用或重载其中的某些方法 下面是一些重要的方法      生命周期方法    我们应该重载这些方法 把初始化和析构(destruction)代码插入向导中     · Constructor(构造函数) 向导实例化的时候 在Eclipse给它传递信息之前调用 向导的一般初始化实现 通常你希望调用 美化方法 (后面有描述)并设置对话框的默认值     · init(IWorkbench workbench IStructuredSelection editorSelection): Eclipse调用它为向导提供工作台的信息 请重载它 保存IWorkbench和对象的句柄供以后使用 如果它是一个编辑器向导而不是新向导 我们最好把当前的编辑器选项作为第二个参数     · dispose() Eclipse调用它执行清理工作 重载它来清除向导使用的资源     · finalize() 清除代码 可能使用dispose()代替      美化方法    这些方法都是用于装饰向导窗体的     · setWindowTitle(String title) 设置窗体的标题行字符串     · setDefaultPageImageDescriptor(ImageDescriptor image) 用于提供显示在向导的所有页面右上方的图片     · setTitleBarColor(RGB color) 指定标题栏用什么颜色      按钮方法    这些方法控制着向导按钮的实用性和行为     · boolean canFinish() 重载它用于指定Finish(完成)按钮是否激活(根据向导的状态)     · boolean performFinish() 重载它来实现向导的根本的业务逻辑 如果向导没有完成(错误的条件) 就返回false     · boolean performCancel() 重载它 在用户点击Cancel(取消)按钮的时候进行清除操作 如果向导不能终止 则返回false     · boolean isHelpAvailable() 重载它用于指定Help(帮助)按钮是否可视     · boolean needsPreviousAndNextButtons() 重载它来指定Previous(前一步)和Next(后一步)按钮是否可视     · boolean needsProgressMonitor() 重载它来指定进度条部件是否可视 当点击Finish按钮调用performFinish()方法的时候 它就会出现      页面方法    这些方法控制着页面的外观     · addPages() 向导显示的时候调用 重载它给向导插入新页面     · createPageControls(Composite pageContainer) Eclipse调用它来实例化所有的向导页面(用前面的addPages()方法已经添加的页面) 重载它给向导添加持续可视的窗体小部件(除页面之外的部件)     · IWizardPage getStartingPage() 重载它来检测哪个页面是向导的第一个页面     · IWizardPage getNextPage(IWizardPage nextPage) 在默认情况下 点击Next按钮将进入addPages()所提供的数组中的下一个页面 你可能希望根据用户选择进入不同的页面 重载它来计算后一个页面     · IWizardPage getPreviousPage(IWizardPage previousPage) 与getNextPage()类似 用于计算前一个页面     · int getPageCount() 检索addPages()添加的页面的数量 在典型情况下 你不必重载它 除非你希望显示页面的数量和形式      其它有用的方法    这些都是有用的辅助方法     · setDialogSettings(IDialogSettings settings) 你可以载入对话框的状态 并通过在init()中调用这个方法来设置这些值 在典型情况下 这些设置可以作为向导字段的默认值 请查看DialogSettings类了解更详细的信息     · IDialogSettings getDialogSettings() 当我们需要数据的时候 就调用这个方法来检索它 在performFinish()的对话框的末尾 你再次可以把数据保存到文件中     · IWizardContainer getContainer() 对于检索Shell 运行的后台线程 刷新窗口等非常有用      向导页面方法    你已经看到了 向导是由一个或多个页面组成的 这些页面扩展了WizardPage类 并实现了IWizardPage接口 为了定制单独的页面 你必须了解很多方法 下面是一些重要的方法     · Constructor 用于实例化页面     · dispose() 重载它用于实现清除代码     · createControl(Composite parent) 重载它来给页面添加控件     · IWizard getWizard() 用于获取父向导对象 对于调用getDialogSettings()是有用处的     · setTitle(String title) 调用它来设置显示在向导标题区域中的字符串     · setDescription(String description) 调用它来提供标题下面显示的文本内容     · setImageDescriptor(ImageDescriptor image) 调用它来提供页面右上方出现的图片(用于代替默认的图片)     · setMessage(String message) 调用它来显示描述字符串下方的消息文本 这些文本是用于警告或提示用户的     · setErrorMessage(String error) 调用它来高亮度显示描述字符串下方的消息文本 它一般意味着向导不能继续 除非错误被修正     · setPageComplete(boolean plete) 如果为true Next按钮就可视     · performHelp() 重载它来提供内容敏感的帮助信息 当点击Help按钮的时候向导会调用它      编写向导的代码    有了这些方法之后 我们就能够开发出具有极大的灵活性的向导了 我们现在修改以前建立的Invokatron向导 给它添加一个页面来请求用户输入初始的文档数据 我们还给向导添加了一个图片 新代码是粗体的     public class InvokatronWizard extends Wizard  implements INewWizard   private InvokatronWizardPage page;  private InvokatronWizardPage page ;  private ISelection selection;    public InvokatronWizard()   super();  setNeedsProgressMonitor(true);  ImageDescriptor image =AbstractUIPlugin imageDescriptorFromPlugin( Invokatron icons/InvokatronIcon GIF );  setDefaultPageImageDescriptor(image);      public void init(IWorkbench workbench IStructuredSelection selection)   this selection = selection;      在构造函数中 我们打开了进度条 并设置了向导的图片 你可以下载并保存下面的图片    >  请把这个图片保存在Invokatron/icons文件夹之下 为了更容易载入这个图片 我们使用了便捷的AbstractUIPlugin imageDescriptorFromPlugin()方法     请注意 你应该知道 尽管这个向导是INewWizard类型的 但是并非所有的向导都是用于建立新文档的 你可以参考其它一些资料来了解如何建立 独立的 向导的信息     下面是addPages()方法     public void addPages()   page=new InvokatronWizardPage(selection);  addPage(page);  page = new InvokatronWizardPage (selection);  addPage(page );      在这个方法中 我们添加了一个新页面(InvokatronWizardPage ) 我们在后面编辑它 下面是用户点击向导的 完成 按钮的时候执行的一些方法     public boolean performFinish()   //首先把所有的页面数据保存在变量中  final String containerName = page getContainerName();  final String fileName =page getFileName();  final InvokatronDocument properties = new InvokatronDocument();  properties setProperty(InvokatronDocument PACKAGE page getPackage());  properties setProperty(InvokatronDocument SUPERCLASS page getSuperclass());  properties setProperty(InvokatronDocument INTERFACES page getInterfaces());    //现在调用完成(finish)方法  IRunnableWithProgress op =new IRunnableWithProgress()   public void run(IProgressMonitor monitor)  throws InvocationTargetException   try   doFinish(containerName fileName properties monitor);   catch (CoreException e)   throw new InvocationTargetException(e);   finally   monitor done();      ;  try   getContainer() run(true false op);   catch (InterruptedException e)   return false;   catch (InvocationTargetException e)   Throwable realException =e getTargetException();  MessageDialog openError(getShell() Error realException getMessage());  return false;    return true;      为了保存数据 我们必须做一个后台事务 该事务是由向导的容器(Eclipse工作台)来执行的 并且必须实现IRunnableWithProgress接口 包含(唯一)一个run()方法 传递进来的IProgressMonitor允许我们报告事务的进度 实际的数据保存工作在一个辅助方法(doFinish())中进行     private void doFinish(String containerName String fileName Properties properties   IProgressMonitor monitor)  throws CoreException   // 建立一个示例文件  monitor beginTask( Creating + fileName );  IWorkspaceRoot root = ResourcesPlugin getWorkspace() getRoot();  IResource resource = root findMember(new Path(containerName));  if (!resource exists() || !(resource instanceof IContainer))   throwCoreException( Container \\ + containerName + \\ does not exist );    IContainer container =(IContainer)resource;  final IFile iFile = container getFile(new Path(fileName));  final File file =iFile getLocation() toFile();  try   OutputStream os = new FileOutputStream(file false);  properties store(os null);  os close();   catch (IOException e)   e printStackTrace();  throwCoreException( Error writing to file + file toString());      //确保项目已经刷新了 该文件在Eclipse API 之外建立  container refreshLocal(IResource DEPTH_INFINITE monitor);    monitor worked( );    monitor setTaskName( Opening file for editing );  getShell() getDisplay() asyncExec(new Runnable()   public void run()   IWorkbenchPage page =PlatformUI getWorkbench() getActiveWorkbenchWindow() getActivePage();  try   IDE openEditor(page iFile true);   catch (PartInitException e)       );  monitor worked( );      我们还做了很多工作     · 我们检索了自己希望保存文件的位置(用Eclipse的IFile类)     · 我们还获取了该File     · 我们把属性保存到了这个位置     · 接着我们让Eclipse工作台刷新项目 这样就可以显示该文件了     · 我们最后调度了一个事务 它在以后执行 这个事务包括在编辑器中打开那个新文件     · 在整个过程中 我们通过调用IProgressMonitor对象(它是作为参数传递进来的)的方法来提示用户目前的进展情况     最后一个方法是一个辅助的方法 当该文件保存失败的时候 它在向导中显示错误信息     private void throwCoreException(String message) throws CoreException   IStatus status =new Status(IStatus ERROR Invokatron IStatus OK message null);  throw new CoreException(status);        向导可以捕获CoreException异常 接着可以把它所包含的Status对象显示给用户看 向导不会被关闭     编写新的向导页面的代码    下一步 我们编写InvokatronWizardPage 它的整个类都是全新的     public class InvokatronWizardPage extends WizardPage   private Text packageText;  private Text superclassText;  private Text interfacesText;    private ISelection selection;    public InvokatronWizardPage (ISelection selection)   super( wizardPage );  setTitle( Invokatron Wizard );  setDescription( This wizard creates a new + file with * invokatron extension );  this selection = selection;      private void updateStatus(String message)   setErrorMessage(message);  setPageComplete(message == null);      public String getPackage()   return packageText getText();    public String getSuperclass()   return superclassText getText();    public String getInterfaces()   return interfacesText getText();      上面的构造函数设置了页面的标题(在标题栏下方高亮度显示)和描述(在页面标题的下方显示) 我们还有一些辅助方法 updateStatus处理页面特定的错误信息的显示 如果没有错误信息 就意味着页面完成了 因此 下一步 按钮就可以使用了 还有数据字段内容的getter(获取)方法 下面是createControl()方法 它建立了页面的所有可视化组件     public void createControl(Composite parent)   Composite controls =new Composite(parent SWT NULL);  GridLayout layout = new GridLayout();  controls setLayout(layout);  layout numColumns = ;  layout verticalSpacing = ;    Label label =new Label(controls SWT NULL);  label setText( &Package: );    packageText = new Text(controls SWT BORDER | SWT SINGLE);  GridData gd = new GridData(GridData FILL_HORIZONTAL);  packageText setLayoutData(gd);  packageText addModifyListener(  new ModifyListener()   public void modifyText(ModifyEvent e)   dialogChanged();    );    label = new Label(controls SWT NULL);  label setText( Blank = default package );    label = new Label(controls SWT NULL);  label setText( &Superclass: );    superclassText = new Text(controls SWT BORDER | SWT SINGLE);  gd = new GridData(GridData FILL_HORIZONTAL);  superclassText setLayoutData(gd);  superclassText addModifyListener(new ModifyListener()   public void modifyText(ModifyEvent e)   dialogChanged();    );    label = new Label(controls SWT NULL);  label setText( Blank = Object );    label = new Label(controls SWT NULL);  label setText( &Interfaces: );    interfacesText = new Text(controls SWT BORDER | SWT SINGLE);  gd = new GridData(GridData FILL_HORIZONTAL);  interfacesText setLayoutData(gd);  interfacesText addModifyListener(  new ModifyListener()   public void modifyText(ModifyEvent e)   dialogChanged();    );    label = new Label(controls SWT NULL);  label setText( Separated by );    dialogChanged();  setControl(controls);      为了编写这段代码 你必须了解SWT(请你自己查看一些这方面的资料) 基本上 这个方法建立了标签和字段 并把它们放置到网格布局上 字段发生改变的时候 就调用dialogChanged()来验证它的数据     private void dialogChanged()   String aPackage = getPackage();  String aSuperclass = getSuperclass();  String interfaces = getInterfaces();    String status = new PackageValidator() isValid(aPackage);  if(status != null) updateStatus(status);  return;      status = new SuperclassValidator() isValid(aSuperclass);  if(status != null) updateStatus(status);  return;      status = new InterfacesValidator() isValid(interfaces);  if(status != null) updateStatus(status);  return;      updateStatus(null);          这个工作是在三个工具类 PackageValidator SuperclassValidator和 InterfacesValidator的帮助下完成的 接下来我们编写这些类      验证类    验证可以在插件的用户输入数据的任何部分中进行 因此 把验证代码放入可重复使用的类中是有意义的 这样就不用把它复制到多个位置 下面是一个验证类的例子     public class InterfacesValidator implements ICellEditorValidator    public String isValid(Object value)    if( !( value instanceof String) )  return null;    String interfaces = ((String)value) trim();  if( interfaces equals( ))  return null;    String[] interfaceArray = interfaces split( );  for (int i = ; i < interfaceArray length; i++)    IStatus status = JavaConventions validateJavaTypeName(interfaceArray[i]);  if (status getCode() != IStatus OK)  return Validation of interface + interfaceArray[i] + : + status getMessage();    return null;        其它的验证类与它非常类似     Eclipse类库中的另外一个极好的类是JavaConventions 它为我们验证数据!它包含了很多验证方法 例如     · validateJavaTypeName() 检查类和接口的名称     · validatePackageName() 检查程序包的名称     · validateFieldName() 检查数据成员的名称     · validateMethodName() 检查方法的名称     · validateIdentifierName() 检查变量的名称     现在我们不需要ICellEditorValidator接口 但是在以后的文章中 我们是需要它的      结果    到目前为止 我们拥有了一个可以工作的向导 它拥有一张图片和两个页面 第二个页面建立了原来的Invokatron文档 图 显示了结果    >   定制的向导     闪亮的发明    我们可以看到 通常是数据驱动应用程序的 外表(Presentation)也是很重要的 丑陋的发明难以出售 但是闪亮的发明可能容易出售 但是数据是我们这些程序员实现的非常本质的东西     在本文中 我们首先决定了自己将处理的数据 然后 我们以定制向导的方式来获取这些数据 下一篇文章将继续讲解显示的问题 包括定制的编辑器和属性页面 cha138/Article/program/Java/ky/201311/28130

相关参考

知识大全 开发Eclipse插件

开发Eclipse插件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在本文中DavidGall

知识大全 Eclipse经典开发教程插件安装

Eclipse经典开发教程插件安装  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Eclipse

知识大全 Eclipse 3.0 简介和插件开发示例

Eclipse3.0简介和插件开发示例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Eclip

知识大全 开发一个调试 JSP 的 Eclipse 插件

开发一个调试JSP的Eclipse插件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  JAVA调

知识大全 基于Eclipse开发轻量级Spring插件

基于Eclipse开发轻量级Spring插件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  摘要

知识大全 Eclipse插件开发中的Java项目模型

Eclipse插件开发中的Java项目模型  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Jav

知识大全 Eclipse插件开发中实现刷新和重编译介绍

Eclipse插件开发中实现刷新和重编译介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  在做

知识大全 eclipse插件的三种安装方法

   将插件直接拷贝到eclipse的plugins(有时候还包括features)目录下然后重启一下eclipse在eclipse的插件库中(>Help>S

知识大全 Eclipse插件的外挂安装方法

Eclipse插件的外挂安装方法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Eclipse平

知识大全 Eclipse基础--plugin插件安装

Eclipse基础--plugin插件安装  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Ecl