java插件

eclipse rcp popup menu

文章分类:Java编程

在做RCP开发中遇到个问题,搞了大半天。代码贴出来:
Java代码 复制代码
  1. view(视图)   
  2. MenuManager menuManager = new MenuManager();   
  3. Menu menu = menuManager.createContextMenu(viewer.getControl());   
  4. MenuItem item = new MenuItem (menu, SWT.PUSH);   
  5. item.setText ("Popup");   
  6. viewer.getControl().setMenu(menu);   
  7. getSite().registerContextMenu(menuManager, viewer);  

view(视图)
MenuManager menuManager = new MenuManager();
Menu menu = menuManager.createContextMenu(viewer.getControl());
MenuItem item = new MenuItem (menu, SWT.PUSH);
item.setText ("Popup");
viewer.getControl().setMenu(menu);
getSite().registerContextMenu(menuManager, viewer);


Java代码 复制代码
  1. plugin.xml   
  2. <menuContribution   
  3.             locationURI="popup:org.eclipse.ui.popup.any">   
  4.          <command   
  5.                commandId="com.ibm.de.eclipse.menu.command.viewCmd">   
  6.             <visibleWhen>   
  7.                <reference   
  8.                      definitionId="twoSelectedCheck">   
  9.                </reference>   
  10.             </visibleWhen>   
  11.          </command>   

 

 

 

Java AWT: Popup Menu


Popup menus (also known as "context menus") are now a very common UI element in modern GUIs (Win95, CDE, etc.). The AWT in 1.0 supports only Pulldown menus (menus which are always attached to a menubar or menu-item) and needs an API to allow Java programs to be able to easily create popup menus. The primary goal for this API is to make the creation and invocation of popups extremely easy in Java programs. Additionally, we want to ensure that popups are not tightly bound to a single component and can be easily reused both within , as well as across, containment hierarchies.

Last Updated: February 3, 1997

Purpose

 

 

Popup Menu API

 

The API consists of a new subclass of Menu:

	java.awt.PopupMenu

The main addition to this subclass is a method to invoke the popup:

	public void show(Component origin, int x, int y)

This method will invoke the popup at the x,y coordinate position relative to the component parameter (the intention is that all parameters can easily be extracted from a given mouse-down event object). Popup menus must have a valid "parent" component in order to be shown. This is to ensure that a popup menu can be instantiated and cached prior to being shown (to prevent any potential slow-down during the show operation, which from the user's perspective should happen simultaneously with the mouse event which triggered it). Popup menus can be attached-to/removed-from any component, using new methods in class java.awt.Component:

 

Popup Menu Ownership

 

	add(PopupMenu popup)
	remove(MenuComponent popup)

Note that a popup menu can only be owned by one component at a time.

The "origin" parameter passed into the show() method can be any component contained within the containment hierarchy defined with the popup's parent as the root (it need not be the parent itself). This is particularly useful if you need to define a single popup for an entire window; you would attach the popup menu to the frame, but could invoke it in response to a mouse-down event on any component within that frame. The main issue with popup menus is defining an appropriate event trigger definition, as this varies slightly across the different platforms:

 

Popup Event Trigger

 

  • In Windows, the menu is popped up on the mouse button *2* mouse UP.
  • In Motif, the menu is popped up on the mouse button *3* mouse DOWN (and it remains showing if the subsequent mouse UP happens within a small interval; else the menu is pulled down on the mouse DOWN)

The API provides a platform-independent abstraction so a program can detect a popup-menu trigger event without hard-coding platform-specific event-handling logic in the program. This is accomplished by providing the following method on java.awt.event.MouseEvent:

	public boolean isPopupTrigger()

 

Event Model Issues

The AWT's 1.0 event model has a limitation where menu events (the actions invoked when a menu item is selected) are not catchable in the menu itself, but must be caught on the parent frame. To work with the 1.0 event model, the popup menu events must be caught in the action() method of the component which owns it. Clearly this is not a desirable limitation for popup menus, as they are not designed to be tightly bound to a particular component. With the new 1.1 event model API, action listeners can be attached directly to the menu items themselves, alleviating this issue (See the AWT Delegation Event Model document for details). Following is a very simple sample program which shows the usage of this API using the 1.1 Delegation Event Model.

 

Sample Code

 

    
    import java.awt.*;
    import java.applet.*;
    import java.awt.event.*;

    public class PopupMenuTest extends Applet implements ActionListener {

	PopupMenu popup;

	public void init() {	    
            MenuItem mi;

	    popup = new PopupMenu("Edit");

            mi = new MenuItem("Cut");
            mi.addActionListener(this);
	    popup.add(mi);

            mi = new MenuItem("Copy");
            mi.addActionListener(this);
	    popup.add(mi);

	    popup.addSeparator();

            mi = new MenuItem("Paste");
            mi.addActionListener(this);
	    popup.add(mi);

	    add(popup); // add popup menu to applet
           
            enableEvents(AWTEvent.MOUSE_EVENT_MASK); 

	    resize(200, 200);
        }

	public void processMouseEvent(MouseEvent e) {

	    if (e.isPopupTrigger()) { 
	        popup.show(e.getComponent(), e.getX(), e.getY());
	    }
	    super.processMouseEvent(e);
        }

        public void actionPerformed(ActionEvent e) {
	    String command = e.getActionCommand();

            if (command.equals("Cut")) {
	        // perform cut operation
            } else if (command.equals("Copy")) {
                // perform copy operation
            } else if (command.equals("Paste")) {
                // perform paste operation
            }
        }
    }

Eclipse插件开发之新手入门
huangdong.com
2005-3-27 20:50:00 文/maven
border="0" marginwidth="0" marginheight="0" src="http://dcdv1.it.com.cn/adsunion/get/;pl=pl-26-edu_art_zl;tp=if;sk=0;ck=0;/?" frameborder="0" noresize="noresize" width="550" scrolling="no" height="80">

  现在在Internet上已经可以见到不少的Eclipse插件开发的入门文章,这里我写本文的目的主要是将我自己的体会和最开始的学习告诉给大家。 同时也希望本文能使用最为简单的方法来让大家了解开发Eclipse插件的基础。需要注意的是,要学习Eclipse的插件开发,你需要:

  会使用Eclipse来开发Java应用程序

  了解插件这个词的概念

  了解一些XML的知识 本文是一个入门的文章,只是向大家说明开发一个插件的简单步骤,同时了解在开发插件时涉及到的技术面会有哪些。

  Eclipse SDK概述

  我们通常使用的Eclipse也就是我们这里所说的Eclipse SDK,这个SDK中包括了很多的内容,如下图所示:




  运行时核心(Eclipse Platform) - SDK必须一个Eclipse Platform,它自身不具有任何对最终用户有意义的功能, 它是一个加载所有插件的基础平台。也就是Eclipse的运行时最小集合了。

  Java 开发工具(JDT) - 我们所有的有关Java的开发部分都是由这个插件来完成了,它形成了对于Java最为基础的编辑、 编译、运行、调试、发布的环境。

  插件开发者环境(PDE) - 开发插件的插件,我们如果要开发插件哪么我们就会发现所有的工作环境都是由它来提供的。 它提供了用来自动创建、处理、调试和部署插件的工具。

  我们将来要开发的插件都是由平台来加载和运行,而PDE则是开发插件的开发环境,JDT则是开发插件时的Java代码的开发环境。

  创建插件项目

  设置引用项目

  开发插件时需要大量的外部库,这些外部库主要是现有的Eclipse中各个插件所提供的库。 为了开发方便,我们先将这些外部库由一个项目统一引用。

  从资源透视图中,使用文件>导入...>外部插件和段。
  在下一步中选择抽取源归档并在项目中创建源文件夹。
  到显示称为选择的屏幕,选择 org.eclipse.ui,然后单击完成按钮。

  创建项目

  在Eclipse需要创建一个空的插件项目,为了让我们更好的理解插件中各个文件的来源,我们从一个空白的插件项目开始:

  1) 打开新建项目...向导(文件>新建>项目...)并从插件开发类别中选择插件项目。

  2) 将com.huangdong.examples.helloworld用作项目的名称。缺省情况下,向导还会将com.huangdong.examples.helloworld设置为标识。

  3) 最终,确保在插件代码生成器页面上选择了创建空白插件项目。

  4) 当询问您是否想切换到“插件开发”透视图时,回答是。

  5) 选择com.huangdong.examples.helloWorld项目并打开属性对话框。

  6) 在Java构建路径属性中,选择项目选项卡,并选择项目org.eclipse.ui。这些包含了项目需要的导入类。

  7) 重建项目。
   创建一个插件内容

  创建一个新的小视图

  下面我们为该项目加入一个很简单的视图:

  1) 在项目的src目录下创建包com.huangdong.examples.helloworld。

  2) 在此包中创建称为HelloWorldView的新类其超类为org.eclipse.ui.part.ViewPart。

  在HelloWorldView中加入以下代码:

  package com.huangdong.examples.helloworld;

  import org.eclipse.swt.SWT;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Label;
  import org.eclipse.ui.part.ViewPart;

  public class HelloWorldView extends ViewPart {

  Label label;

  public void createPartControl(Composite parent) {
  label = new Label(parent, SWT.WRAP);
  label.setText("Hello World");
  }

  public void setFocus() {}
  }

  我们为该类定义了一个变量lable,在createPartControl方法中初始化并设置了一个显示的字符串。

   护展扩展点

  让Eclipse添加这个视图,需要扩展org.eclipse.ui.views扩展点。所有的这些需要在plugin.xml中进行描述。该清单文件描述插件,包括插件的代码所在的位置以及正在添加的扩展。

  将以下内容复制到plugin.xml中:

  <?xml version="1.0" encoding="UTF-8"?>
  <plugin id="com.huangdong.examples.helloworld"
  name="com.huangdong.examples.helloworld"
  version="1.0.0"
  provider-name="HuangDong">

  <runtime>
  <library name="helloworld.jar"/>
  </runtime>
  <requires>
  <import plugin="org.eclipse.ui"/>
  </requires>

  <extension point="org.eclipse.ui.views">
  <category
  name="Hello"
  id="com.huangdong.examples.helloworld.hello">
  </category>
  <view
  name="Hello Greetings"
  category="com.huangdong.examples.helloworld.hello"
  class="com.huangdong.examples.helloworld.HelloWorldView"
  id="com.huangdong.examples.helloworld.helloworldview">
  </view>
  </extension>

  </plugin>


  在plugin域中定义了插件的名称、标识和版本。 同时在runtime域中定义了插件代码将打包于helloworld.jar文件中。 在requires域中定义了该插件所要使用的依赖插件,由于我们要使用SWT API和工作台所以列示了org.eclipse.ui。 最后,在extension中说明了要们要扩展org.eclipse.ui.views扩展点。 首先我们在category中定义了视图的类别,在工作台的显示视图对话框中,可以使用类别来将相关的视图集中在一起。我们定义的类别名为“Hello”。 同时也定义了我们的视图,名为“Hello Greetings”,这个视图将会显示在“显示视图”对话框和视图的标题栏中,这里我们还通过class标识来说明了实现这个视图的最终类。

  通过plugin.xml的定义,Eclipse才会真正的找到插件可以做的行为,以及这些行为最终实现的具体Java类。

  在插件清单文件中使用了许多标识。 个别扩展点通常会定义需要标识的配置参数(例如,以上用于视图扩展点的类别标识)。 我们还要定义插件标识。通常,应该对所有标识都使用 Java 包名前缀,以便确保所有已安装的插件都是唯一的。

  在前缀后面使用的特定名称完全由您自己决定。 然而,如果插件标识前缀刚好与其中一个包的名称相同,则应该避免在该包中使用类名。 否则,将很难分辨您正在查看标识名还是类名。

  还应该避免对不同的扩展配置参数使用相同的标识。 在上述清单中,已经使用了公共标识前缀(com.huangdong.examples.helloworld),但是,我们的所有标识都是唯一的。 此命名方法可以帮助我们阅读文件并了解哪些标识是相关的。

  运行和测试插件

  运行插件是一件很简单的事,这些在PDE中给我们提供了很好的支持。 只需要在菜单中选择运行>运行为>运行时工作台,在运行时会弹出一个重复插件的提示框,可以按确定跳过,不必在意。 这样会启动一个已经安装好插件的Eclipse。

  启动后在菜单中选择窗口>显示视图>其它,在显示视图对话框中会有一个分类为Hello,点开Hello分类会看到Hello Greetings,选择后点确定按钮。在最下面的视图中可以见到以下界面:



  到这里,如果你看到了这个图,哪么恭喜你,你的第一个Eclipse插件成功运行了。
 

 

 

 Eclipse由一个很小的核心和核心之上的大量插件组成。有些插件仅仅是供其它插件使用的库。其中存在很多你可以利用的工具。所有插件使用的基础库是:
  · 标准Widget工具包(SWT):Eclipse中处处使用的图形化组件:按钮,图像、光标、标签等等。布局管理类。通常这个库被用于代替Swing。
  · JFace:菜单、工具条、对话框、参数选择、字体、图像、文本文件的类和向导基类。
  · 插件开发环境(PDE):辅助数据操作、扩展、建立过程和向导的类。
  · Java开发者工具包(JDT):用于编程操作Java代码的类。
  上面的每一个类都有自己专有的功能,其中一些还可以单独使用(尽管它们内在地依赖于其它类)。例如,SWT不仅仅只用于插件;它还可以被用于建立非Eclipse的、独立的应用程序。还有一些其它的库没有被列举出来。
  图1显示了Eclipse不同层次之间的关系。

图1:分层的类库
  安装GEF和Draw2D运行时
  在默认情况下,这两个面向对象的库(图形化编辑器框架组件GEF和Draw2D)是没有被安装的。在本文中我们需要利用它们,因此首先需要安装它们。你可以在GEF主页面下载GEF和Draw2D,下载3.0.1或以后版本,把文件保存为GEF-SDK-3.0.1.zip(5.5MB)。把这个文件解压到Eclipse文件夹下(这是包含plugins子文件夹的文件夹)。这两个库自身也是作为插件加进来的。
  这些库提供了什么样的功能?它们构成了建立图形化插件的基础。图形化插件通常显示一些对象(例如方框和标签,用线和箭头链接在一起)。这些对象和连接器的绘制都是由Draw2D来处理的。但是绘制过程仅仅是图形化编辑器实现的一半功能。另一半--编辑器命令、工具条、拖放功能、打印--由GEF来完成。
  配置PDE选项
  安装上述的各种部件之后,下一步就是定制或至少是熟悉插件配置选项。这些选项在菜单窗体 -> 选项的"插件开发"类别下选择。浏览一下插件用到的数以十计的配置选项。你可以特地看一下Target Environment(目标环境)类别。它允许我们选择默认的操作系统、视窗(windowing)系统、CPU架构和语言。
  我们感兴趣的还有Plug-in Development(插件开发)透视图(透视图是一组视图参数选择,包括面板、视图、工具条等等,根据不同的事务发生改变,可以把它看出Eclipse中的"模式")。通过选择菜单中的窗口-> 打开透视图 -> 其它,然后在列表中选择"插件开发"就可以看到它了。它与Java透视图相似,但是拥有一个插件视图,可以显示所有检测到的插件。图2显示了如何激活这个透视图,并显示了该透视图。

图2:插件开发透视图
  建立一个简单插件
  建立插件最简单的办法是使用文件-> 新建->插件项目向导所提供的模板。接着输入一个项目名称(例如"Invokatron")。这是什么意思呢?我们将建立的插件是Invokatron,它是一个供Java代码使用的代码生成图形化编辑器。本文删除了Invokatron的路径,但是很明显这个雄心勃勃的项目直到下次安装时才会完成。
  在"下一步"页面上,除了类名之外其它的选项都不变,类名输入invokatron.InvokatronPlugin。在"插件内容"页面上,输入你认为适合的任何信息。在"模板"页面上,选中检查框以激活模板。我们可以在多个模板中进行选择:
  · Hello, World
  · 简单的XML编辑器
  · 多页面编辑器和向导
  · 透视图扩展
  · 弹出菜单
  · 属性页面
  · 视图
  · 拥有前面的一个或多个数据项的自定义插件
  对于本文的示例,我们使用自定义插件模板。选择"多页面编辑器"-"新建文件向导"-"属性"页面。在"下一步"页面输入下面一些值:
"多页面编辑器"页面(图3所示):
  · Java程序包名称:invokatron.editor
  · 编辑器类名称:InvokatronEditor
  · 编辑器辅助类名称:InvokatronEditorContributor
  · 编辑器名称:Invokatron Editor
  · 文件扩展名:invokatron

图3:"多页面编辑器"设置
  "新建向导"页面(图4所示):
  · Java程序包名称:invokatron.wizard
  · 向导类别ID:Invokatron
  · 向导类别名称:Invokatron Wizard
  · 向导类名称: InvokatronWizard
  · 向导页面类名称:InvokatronWizardPage
  · 向导名称:Invokatron Wizard
  · 文件扩展名: invokatron
  · 初始文件名: MyClass.invokatron

图4:"新建向导"设置
  "属性"页面(图5所示):
  · Java程序包名称:invokatron.properties
  · 属性页面类: InvokatronPropertyPage
  · 属性页面名称:Invokatron Properties
  · 目标类:org.eclipse.core.resources.IFile
  · 文件名过滤器:*.*

图5:"属性"页面设置
  这个时候Eclipse生成了大量的文件:
  · plugin.xml:描述该插件的主文件。它包含了辅助代码生成、库、插件依赖关系和扩展指向的一些信息。
  · build.properties:用于描述建立(build)过程的文件。它主要用于指定需要的库。
  · invokatron/*.java:插件类。
  · sample.gif:菜单项显示的图标。
  plugin.xml文件和build.properties一起被显示在多页面编辑器中。第一个页面("预览")允许你在测试环境中导出和运行该插件。"导出"的意思是通过生成一些代码、接着编译和打包来完善该插件。
  查看一下类,你会发现它实际上没有做什么操作。添加菜单选项的代码在哪儿呢?框架组件从plugin.xml文件包含的信息中简单地生成了必要的代码。你可以查看一下这个文件。它的最后一部分包含了一个扩展列表,这是这些类可以插入Eclipse的地方。
  上面过程中产生的项目是示例代码的一部分,你可以下载。
  运行和调试
  你可以在一个特殊的沙盒(sandbox)--运行时工作台(runtime workbench)中测试自己的插件。使用这种方式的时候,即使运行时工作台崩溃了,Eclipse仍然能够工作。通过点击"预览"页面上的"载入运行时工作台"或"在调试模式中载入运行时工作台"链接。第一次运行运行时工作台的时候,会建立eclipse untime-workbench-workspace文件夹。它会启动一个新的Eclipse实例,该实例与正常的Eclipse窗口非常相似(除了你的插件可以使用了之外)。
  但是你还是首先选择文件 -> 新建 -> 项目菜单和Java项目来建立一个Java项目。这个项目的名称叫做Test。图6显示了带有我们建立的向导和编辑器的运行时工作台。

图6:运行该插件
  现在我们看一下Invokatron向导。从菜单文件->新建 -> 其它 可以看到它。查看类别Invokatron向导。选择Invokatron向导,接着点击"下一步"。这个向导会建立一个空的Invokatron文档。在Container(容器)字段中选择Test项目并点击"完成"。一个新的Invokatron编辑器显示出来了。这个编辑器有三个页面:一个文本编辑页面、一个属性页面(字体选择)和一个预览页面(排序的、用选择的字体绘制的)。
  支持文件
  你可以在很多位置指定自己的插件在编译和运行时所需要的文件。这使我们这些Eclipse用户感到很困惑。我们试图澄清这些问题。
  支持文件分为三类:
  1、来自插件代码自身的类和资源。它们在建立过程中就会被打包为一个或多个.jar文件。
  2、编译和运行插件所需要的类和资源。它们都应该被包含在类路径中,并且我们必须指明在导出的时候需要复制这些文件。
  3、与插件一起包含进来的文件(例如readme.txt文件)。它们不在类路径中。
  在插件编辑器的"建立(Build)"页面中可以设置编译环境。此外,这些设置会映射为build.properties文件。在第一次看到这个页面的时候我们可能会感到困惑,因为它有四个分开的部分:
  · 运行时信息:列出了生成的库文件(第1类文件)。通常,在一个库文件中包含了插件所需要的所有类,但是你可能希望把它分割成更小的块。
  · Source Build:列出应该被包含到.jar文件中的类文件(第1类文件的输入)
  · Binary Build:列出应该被复制到导出的插件文件夹或档案文件中的文件(第3类文件)。上面的选择框被选中的时候,生成的文件会被自动地包含进来。
  · 精确的类路径项:列出了在编译时刻你的应用程序所需要的.jar文件(第2类文件)。这些文件会被自动地添加到你的项目库中。我们通常容易犯的一个错误是在"属性"页面中的"Java建立路径"中和这个列表中同时包含了某个.jar文件。
  如果你的插件使用了某个特殊的库,就必须确保把这个库添加到项目中。接着把它添加到Source Build和精确的类路径项中。
  插件编辑器的其它一些重要的属性页面有:
  · 依赖关系(Dependencies):如果你的插件依赖于其它的插件,你就必须在这儿指定。
  · 运行时(Runtime):在这个属性页面中你可以为插件指定特殊行为。
  导出
  插件编码完成了,并且在工作台中测试过之后,就该准备部署到"真实的" Eclipse环境中了。要实现这个步骤,需要返回"预览"页面并点击"导出向导"链接。"导出选项"对话框允许你从三种部署类型中选择一个:
  · 目录结构:把文件部署到一个目录中供Eclipse立即使用。接着你可以把目标位置(Destination)设置为本地的Eclipse文件夹(例如c:deveclipse),直接地使用插件。
  · 单个.zip文件:相同的文件夹会被压缩为一个.zip文件,准备好发布给客户。接下来,你必须把这个文件解压到Eclipse最上层的文件夹来安装插件。你必须在文件名字段中指定.zip文件名。
  · 更新站点使用的独立.jar文档文件:产生一个与Eclipse用于自动更新系统相兼容的.jar文件。
  你点击"完成"之后,会生成我们选中的输出。如果你把输出作为目录结构,就必须重新启动Eclipse以激活该插件。
  查看示例和源代码
  关于如何编写Eclipse插件的最好信息来源是Eclipse所提供的插件示例集。如果我只能选择一个辅助自己编写插件的信息来源,我一定选择它。
  如果你要下载这些插件,只需要访问Eclipse下载页面并选择最新的版本。接着看这个页面的中间,有一个"示例插件",请下载这些.zip文件(小于2MB)。把这些文件解压到Eclipse所在的文件夹(例如c:dev)中。这个步骤会在eclipse/features和eclipse/plugins下建立很多文件夹。这些示例的源代码在C:deveclipseplugins文件夹的大量.zip文件中,如下所示:
示例 代码位置SWT示例在org.eclipse.sdk.examples.source_3.0.1src...文件夹下独立的 · 地址薄
· 剪贴板
· 文件查看器
· Hello World
· 悬浮帮助
· 图像分析器
· Java语法查看器
· 文本编辑器 ...org.eclipse.swt.examples_3.0.0swtexamplessrc.zip 与工作台集成的 · 浏览器...org.eclipse.swt.examples.browser_3.0.0 browserexamplesrc.zip· 控件 ...org.eclipse.swt.examples.controls_3.0.0controlssrc.zip· SWT载入程序...org.eclipse.swt.examples.launcher_3.0.0launchersrc.zip· 布局...org.eclipse.swt.examples.layouts_3.0.0layoutssrc.zip· 绘图...org.eclipse.swt.examples.paint_3.0.0paintsrc.zip· OLE 特殊文件夹:
org.eclipse.sdk.examples.source.win32.win32.x86_3.0.1 srcorg.eclipse.swt.examples.ole.win32_3.0.0 olewin32src.zip工作台示例 · Java编辑器 ...org.eclipse.ui.examples.javaeditor_3.0.0 javaeditorexamplesrc.zip· 模板编辑器 ...org.eclipse.ui.examples.javaeditor_3.0.0 templateeditorexamplesrc.zip· 多页面编辑器...org.eclipse.ui.examples.multipageeditor_2.1.0< multipageeditorsrc.zip· 属性表...org.eclipse.ui.examples.propertysheet_2.1.0 propertysheetsrc.zip· Readme工具...org.eclipse.ui.examples.readmetool_2.1.0 eadmetoolsrc.zip帮助示例特殊文件夹:
org.eclipse.help.examples.ex1_3.0.0(没有Java文件;HTML在doc.zip之中)Team示例 · 知识库提供程序
· 同步共享 ...org.eclipse.team.examples.filesystem_3.0.0 teamfilesystemsrc.zip文件比较示例 · 结构比较...org.eclipse.compare.examples_3.0.0 compareexamplessrc.zip· XML比较 ...org.eclipse.compare.examples.xml_3.0.0 xmlcompareexamplessrc.zip  
  还存在一些GEF和Draw2D插件的有用示例。你可以访问GEF页面并下载最新版本。在版本发布页面中间有"GEF示例",请下载该.zip文件。在写作本文的时候,该文件是GEF-examples-3.0.1.zip(0.5MB)。把这个文件解压到Eclipse所在的文件夹中。你将看到下面两个示例:
示例代码位置· 逻辑图表示例 org.eclipse.gef.examples.source_3.0.1src org.eclipse.gef.examples.logic_3.0.0logicsrc.zip· 流图表示例org.eclipse.gef.examples.source_3.0.1src org.eclipse.gef.examples.flow_3.0.1flowsrc.zip
  查找插件开发的信息
  你首先查看的位置应该是本文前面部分中的示例。其次还有帮助系统,它的质量也非常高。相关的内容还有:
  · 平台插件开发
  · JTD插件开发
  · PDE指导
  · Draw2D开发者指导
  · GEF开发者指导
  结论
  现在你已经有了建立Eclipse图形化插件的足够信息了。有了这么多类库的帮助,只有你的想象力会限制你的作为了。其秘诀在于你要知道自己能够使用那些工具,并且使用正确的工具完成适当的工作。
本篇文章来源于 黑客基地-全球最大的中文黑客站 原文链接:http://www.hackbase.com/lib/2007-05-02/16449.html

插件开发-如何运行java类

(2008-02-02 09:35:39)
标签:

netbeans

it

分类:Netbeans 智囊团
在插件开发中,想运行当前打开的java文件,但是搜索了提供的doc没有发现相关的action,在Execute包里,发现只能通过NbProcessDescriptor来自定义运行命令,很是麻烦。
请问:netbeans系统自带的如何运行单个文件?我只知道它是调用ant来运行build-imp.xml里面的target。
 
运行java文件的原理就是调用当前打开的java工程的build.xml文件,netbeans是按照ant来进行工程管理的。首先需要对ant有所熟悉。
我的步骤是这样:首先根据当前打开的Node,获得它的DataObject,再获得FileObject,再获得工程,利用工程进行查找AntArtifactProvider,通过它获得AntArtifact。然后调用ActionUtils.runTarget运行指定的Target,代码如下:

protected void performAction(Node[] activatedNodes) {
        Node activetedNode = activatedNodes[0];
      DataObject dataObject = (DataObject)activetedNode.getLookup().lookup(DataObject.class);
        FileObject fileObject = dataObject.getPrimaryFile();
        JavaDataObject jdo = (JavaDataObject)dataObject;
        SourceElement src  = jdo.getSource();
        
        Project project = FileOwnerQuery.getOwner(fileObject);
        AntArtifactProvider provider = (AntArtifactProvider)project.getLookup().lookup(AntArtifactProvider.class);
        AntArtifact[] antArtifacts = provider.getBuildArtifacts();
        try {
            Properties prop = new Properties();            
            prop.put("main.class",src.getClasses()[0].getVMName()); //main-class
            prop.put("application.args","arg1 arg2 arg3"); //argument
            prop.put("run.jvmargs","-Xms10m"); //java vm-option
            prop.put("work.dir","workdir"); //work-dir
            ExecutorTask  task = ActionUtils.runTarget(antArtifacts[0].getScriptFile(),new String[]{"run"},prop);
            InputOutput io = task.getInputOutput();
            io.select();
            OutputWriter writer = io.getOut();
            writer.println("run success!!!!");
        } catch (IllegalArgumentException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

 

【Eclipse插件开发】Java基本类加载原理 VS 插件类加载原理

            标题说明了一切,我想说的就是如果你在做Eclipse插件开发,想真正搞清楚Eclipse插件类加载,那么Java基本类加载原理是基础,无法逾越!!!我会举一个小例子来简单说明一下
            
        【情景】
          例如我们在底层模块插件(就叫做Host)中做了一个解析器实现(什么解析器就别管了),对应类型为IParser(com.my.host.parser.IParser),简单定义如下:
1  public   interface  IParser {
2       public  Object parse(Object input)  throws  CoreException;
3  }
         
        基本的原则告诉我们:如果一个实例的创建过程较为负责,则因该把这种实例的创建和实例的使用解耦合。于是,我们在Host插件中提供了一个如下的工厂类:
 1  public   class  ParserFactory {
 2       /**
 3       * create IParser instance
 4       * 
 5       *  @param  clazz  qualified parser type name
 6       *  @return
 7       *  @throws  CoreException
 8        */
 9       public   static  IParser createParser(String clazz)  throws  CoreException{
10           try  {
11              Object object  =  Class.forName(clazz).newInstance();
12               if  (object  instanceof  IParser)
13                   return  (IParser)object;
14              
15               return   null ;
16          }  catch  (Exception e) {
17               throw   new  CoreException( new  Status(IStatus.ERROR,  " host " 101 " 创建工厂失败: "   +  clazz, e));
18          }
19      }
20      
21       /**
22       * create IParser instance with corresponding class loader
23       * 
24       *  @param  clazz         qualified parser type name
25       *  @param  classLoader   corresponding class loader
26       *  @return
27       *  @throws  CoreException
28        */
29       public   static  IParser createParser(String clazz, ClassLoader classLoader)  throws  CoreException{
30           try  {
31              Object object  =  classLoader.loadClass(clazz);
32               if  (object  instanceof  IParser)
33                   return  (IParser)object;
34              
35               return   null ;
36          }  catch  (Exception e) {
37               throw   new  CoreException( new  Status(IStatus.ERROR,  " host " 101 " 创建工厂失败: "   +  clazz, e));
38          }
39      }
40  }
41 
        这里的简单工厂中创建方法返回的是IParser接口类型,目的就是为了保证可以创建子类型的灵活性,同时确保对外提供的接口是一致的,有助于客户端基于接口编程(说的有点上纲上线了~_~)

        同时我们在Host插件中,也提供了一个默认的IParser实现,就叫做DefaultParser吧。那到这里我们的Host插件共提供了如下类型:
        com.my.host.parser.IParser                     解析器接口定义
        com.my.host.parser.ParserFactory          解析器工厂
        com.my.host.parser.impl.DefaultParser    解析器接口默认实现

        下面我们在Host插件的基础之上建立了上层功能插件(就叫做Extension插件吧,Extension插件依赖于Host插件),提供了解析器实现,对应类型为com.my.extension.parser.MyParserImpl。我们在Extension插件中想使用这个实现,假设有如下几种中创建方式:
第一种:直接创建实例,偏不用你Host中的工厂。 俗了点,但是没问题。
 1  package  com.my.extension.model;
 2 
 3  public   class  Customer {
 4       public   void  doOperation(Object input)  throws  CoreException{
 5           // 直接创建实例的方式
 6          IParser parser  =   new  MyParserImpl();
 7          
 8          Object model  =  parser.parse(input);
 9           // TODO 拿到模型之后干其他活
10      }
11  }

第二种,直接使用Class.forName(),还是不用你Host中的工厂。也是俗了点,但也没问题,为什么没问题,可能就没有想清楚了~_~
 1  package  com.my.extension.model;
 2 
 3  public   class  Customer {
 4       public   void  doOperation(Object input)  throws  CoreException{
 5           try  {
 6               // 使用默认的Class.forName()的方式
 7              IParser parser  =  (IParser)Class.forName( " com.my.extension.parser.MyParserImpl " ).newInstance();
 8              
 9              Object model  =  parser.parse(input);
10               // TODO 拿到模型之后干其他活
11          }  catch  (Exception e) {
12               //  TODO: handle exception
13          }
14          
15      }
16  }

第三种:用一把工厂 ---》》 ClassNotFoundException
 1  package  com.my.extension.model;
 2 
 3  public   class  Customer {
 4       public   void  doOperation(Object input)  throws  CoreException{
 5           // 使用工厂,不指定类加载器
 6          IParser parser  =  ParserFactory.createParser( " com.my.extension.parser.MyParserImpl " );
 7          
 8          Object model  =  parser.parse(input);
 9           // TODO 拿到模型之后干其他活
10      }
11  }
疑惑了:第二种使用方式为什么没问题,第三种怎么就有问题了?代码实现中都是Class.forName( " " ).newInstance();调用啊???

大致错误原因:
        这个时候如果你只基本熟悉Eclipse的插件类加载机制(会去找所依赖的插件中的类型...),可能一时半会想不清楚。 Java的类加载基本原理中有一条:Class.forName()调用方式加载类型所默认使用的类加载器实例是加载当前类型的类加载器。对于在Extension插件Customer中调用Class.forName()使用的是加载Customer类型的类加载器,也就是Extension插件的唯一类加载器;对于在Host插件中的ParserFactory中调用Class.forName()则使用的加载ParserFactory类型的类加载器实例,也就是Host插件的唯一类加载器。你想让Host插件类加载器去加载一个在Extension插件中定义的类型,注意Extension插件是依赖于Host插件的啊,根据Eclipse插件类记载规则,这种加载请求无法从Host插件类加载器委托到Extension类加载器(说明:使用扩展点机制可以,extension registry会帮你委托这一个请求,找到对应的BundleHost...)。如果你想让Extension插件的类加载器去加载Host中定义的切export出来的类型,Extension插件的类加载器会把这个请求合理的委托给Host插件类加载器。


第四种:用一把工厂,指定类加载器。由于 com.my.extension.parser.MyParserImpl本身就和Customer定义在同一插件中,所以公用同一插件类加载器实例,两者对于Extension插件来说都是local class,加载肯定没问题。
 1  package  com.my.extension.model;
 2 
 3  public   class  Customer {
 4       public   void  doOperation(Object input)  throws  CoreException{
 5           // 使用工厂,指定类加载器
 6          IParser parser  =  ParserFactory.createParser( " com.my.extension.parser.MyParserImpl " this .getClass().getClassLoader());
 7          
 8          Object model  =  parser.parse(input);
 9           // TODO 拿到模型之后干其他活
10      }
11  }

以上是举了一个小例子,仅仅是为了说明一个道理: 掌握Java类加载基本原理是掌握Eclipse插件类加载原理的基础,不可逾越!!!如果让你在一个插件应用中写一个较为负责的自定义类加载器,但靠背一点Eclipse类加载的规则,那更不够了...

Java类加载基本原理还有很多,我博客中有随笔(老早之前写的,土了点,头一段时间贴到了博客上了)。

Java基本类加载原理 VS 插件类加载原理(1)
文章发布人gxy  共46人阅读  文字大小:[ ]  文字背景色杏仁黄 秋叶褐 芥末绿 灰 白

  标题说明了一切,我想说的就是如果你在做Eclipse插件开发,想真正搞清楚Eclipse插件类加载,那么Java基本类加载原理是基础,无法逾越!!!我会举一个小例子来简单说明一下

  【情景】

  例如我们在底层模块插件(就叫做Host)中做了一个解析器实现(什么解析器就别管了),对应类型为IParser(com.my.host.parser.IParser),简单定义如下:

1 public interface IParser {
2   public Object parse(Object input) throws CoreException;
3 }    
    基本的原则告诉我们:如果一个实例的创建过程较为负责,则因该把这种实例的创建和实例的使用解耦合。于是,我们在Host插件中提供了一个如下的工厂类:
1 public class ParserFactory {
2   /**
3   * create IParser instance
4   *
5   * @param clazz qualified parser type name
6   * @return
7   * @throws CoreException
8   */
9   public static IParser createParser(String clazz) throws CoreException{
10     try {
11       Object object = Class.forName(clazz).newInstance();
12       if (object instanceof IParser)
13         return (IParser)object;
14      
15       return null;
16     } catch (Exception e) {
17       throw new CoreException(new Status(IStatus.ERROR, "host", 101, "创建工厂失败:" + clazz, e));
18     }
19   }
20  
21   /**
22   * create IParser instance with corresponding class loader
23   *
24   * @param clazz     qualified parser type name
25   * @param classLoader  corresponding class loader
26   * @return
27   * @throws CoreException
28   */
29   public static IParser createParser(String clazz, ClassLoader classLoader) throws CoreException{
30     try {
31       Object object = classLoader.loadClass(clazz);

32       if (object instanceof IParser)
33         return (IParser)object;
34      
35       return null;
36     } catch (Exception e) {
37       throw new CoreException(new Status(IStatus.ERROR, "host", 101, "创建工厂失败:" + clazz, e));
38     }
39   }
40 }
41    

 

对eclipse功能的一些扩展方式 收藏
今天看了一点有关于java插件开发方面的东西,写一点点感想吧。

eclipse体系本身就是一个以一内核为基础,然后再由很多插件组成的一个体系。所以有了eclipse的原有内容,我们就能够在其基础上进行仅我们需要的开发了。比如说一个大纲视图就是一个插件,一个搜索功能也就是一个插件,但是这些功能仅仅是eclipse上的,并不同于我们所需要的应用程序。而eclipse的架构非常好,每一个插件都是一个扩展点,而同时往往也是对其他插件的一个扩展,所以使得无数程序员可以在其上面进行扩展,而扩展成的成品也就是插件。对eclipse体系进行功能扩展的过程其实也就是插件开发。

现在讲讲我今天学到的一点点东西。其实也很简单。既然eclipse的每一个功能是一个插件,就意味着每一个功能都可以扩展。比如你要添加一个视图(eclipse现存的视图有控制台视图、大纲视图、错误日志视图等等),那么你就可以扩展org.eclipse.ui.views插件;如果你要在菜单栏上添加一个动作集,那么就可以扩展org.eclipes.ui.actionSets插件;如果要在某个对象或者某个视图右击的菜单上添加某功能,那么就可以扩展org.eclipse.popupMenus插件。后面还有键绑定的操作,我先把这里的扩展讲完。

在eclipse中如果要对某一项右键之后的菜单进行添加,那么就需要对org.eclipse.popupMenus进行扩展,这只要在extension里面添加一个这样的插件就可以。然后再对这个插件扩展一个objectContribution.接下去就是一系列设置了。设置完车之后再写一个类来执行所要做得操作就可以。具体的plugin.xml的写法如下:

<extension
         point="org.eclipse.ui.popupMenus">
      <objectContribution
            adaptable="false"
            id="com.plugindev.addressbook.example.objectActionTest"
            nameFilter="Three"
            objectClass="java.lang.String">
         <menu
               id="exampleMenu"
               label="示例菜单"
               path="additions">
            <separator
                  name="example">
            </separator>
         </menu>
         <action
               class="com.plugindev.addressbook.example.ObjExampleAction"
               enablesFor="1"
               id="com.plugindev.addressbook.objExampleAction"
               label="对象示例操作"
               menubarPath="exampleMenu/additions"
               tooltip="举例说明如何添加对象操作">
         </action>
      </objectContribution>
    
     
      <viewerContribution
            id="com.plugindev.addressbook.example.viewerActionTest"
            targetID="#TextEditorContext">
         <menu
               id="ViewToolbarMenu"
               label="示例工具栏菜单"
               path="additions">
            <separator
                  name="example">
            </separator>
         </menu>
         <action
               class="com.plugindev.addressbook.example.ViewerExampleAction"
               enablesFor="+"
               id="com.plugindev.addressbook.viewerExampleAction"
               label="查看器示例操作"
               menubarPath="ViewToolbarMenu/addition"
               style="push"
               tooltip="举例说明如何添加查看器操作">
         </action>
        
      </viewerContribution>
   </extension>

上面还有一个viewerContribution,这个也就是对右键某一个视图弹出的菜单的扩展,可以看到,这个也是扩展了org.eclipse.ui.popupMenus这一插件的。

之后的根据所需对象的不同可以对xml文件的属性进行配置,结果便可以让eclipse根据xml文件进行对图形界面的生成。

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/llmhyy1/archive/2010/02/25/5326830.aspx

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值