Eclipse Action学习 1

以前做插件用到的ActionSet都只是依葫芦画瓢,没有真正理解它,现在开始好好学习学习,主要是看"Building Commercial-Quality Plug-ins"写的 

Action
的组成包括几个部分,一个是在plugin.xml中的声明,一个是在Eclipse UI中会用到的IAction实例化对象, 另一个是封装在IActionDelegate中的action执行代码. action的实例化是基于plugin.xml配置文件和IActionDelegate定义的,Eclipse可以先在界面上将action显示出来,直到用户点击了菜单或者工具条按钮才会去真正的加载插件,这也就是所谓的Eclipse的延迟加载机制 

IActionDelegate
有几个子类需要说明一下: 
IActionDelegate2
如果实现IActionDelegate需要一些其他的信息,而这些信息在IActionDelegate销毁时需要同时被销毁时, 它可以提供相关是生命周期事件方法来处理 
IEditorActionDelegate
是跟editor相关的 
IObjectActionDelegate
是跟上下文菜单相关的 
IViewActionDelegate
是跟view相关的 
IWorkbenchWindowActionDelegate
是跟menubartoolbar相关的 

Actions
Eclipse中的其他东东一样,也是通过扩展点org.eclipse.ui.actionSets来添加到Eclipse IDE的各个地方,actions的外在表现形式主要有menubar, toolbar, context menu这样几种 

actionSets的下级节点是actionSet, 它有几个属性,id,label都不用说了,还有一个visible属性,表示在打开Eclipse时是否显示该action,通常我们可以通过Window > Customize Perspective...来设置action是否可见 

actionSet下可以添加menu节点, 它的id,label属性不用说了,其中的path是用来指定菜单的显示位置的,一般设置为additions 

action
并不是直接添加到menu上的, 而是跟menu内部的group关联的,所以我们必须先在menu下创建group,即新建groupMarker, name必须保证在当前menu下唯一, menu还有一种叫separatorgroup, separator group处添加的menu item会在这个组中的第一个菜单项上面添加一条水平线.groupMarker则不会有线, 当其他action要添加到该menu group下时,使用水平线进行分组就显得非常必要 

group
只是用来标识menu的位置,即指这个位置可以添加菜单项, 而不是实际的menu item, 实际的menu itemaction 

因为menu会有层次关系,所以actionSet中专门用一个menu节点来表现这种层次关系, toolbar则没有这种情况,所以这里没有提供toolbar节点 

actionSet下添加action就是最终我们要toolbar上显示的按钮和menubar上的menu item, 这里有几个属性, idlabel不用说了,menuBarPathmenu要显示的位置, 比如"com.qualityeclipse.favorites.workbenchMenu/content",这个值就是actionSet+"/"+group name, toolbarPath 就是toolbar item的显示位置, 比如"Normal/additions", 还有几个属性不常用到,但是有必要解释一下 

allowLabelUpdate
这个要在retarget属性为true的时候有效,还不是很清楚 

class
menubutton要执行的动作, 如果使用的是pulldown风格的action,还需要实现IWorkbenchWindowPulldownDelegate接口,它的构造函数是无参数的,如果要传递参数,还需要是要实现IExecutableExtension 接口, 这个接口还不是很清楚 

definitionId
这个是用来指定action对应的command唯一标识符的 

enablesFor
是一个表达式,用来表示当前action是否可用 

retarget
不是很理解 

state
主要是针对style属性为radiotoggle,表示当前action是否被选中 

style:
默认是push,还有radio,表示一组menu中只能有一个被选中, toggle当它是checkbox好了, pulldown说明是子菜单项或者是下拉toolbar menu 

对于action所使用的图标,我们可以从Eclipse下的plugins\org.eclipse.ui_3.1.2.jar plugins\org.eclipse.jdt.ui_3.1.2.jar得到一些gif的图片 

Eclipse
actionSet以及下级元素都是有id,而且他们可以通过一种path的方式来进行指定,比如com.qualityeclipse.favorites.workbenchMenu/content,如果上一级节点是workbench menu bar或者是view content menu的话,那么它的上一级节点是不用指定的,只要指定group就好 

为了方便其他的插件的action能添加到该插件的actionSet, 在为插件定义group的时候, 会添加一个为additionsgroup, additionseclipse使用的一个默认标识符,用来表示其他actionmenu显示的位置, class中它的对应常量是IWorkbenchActionConstants.MB_ADDITIONS, 比如我们定义了一个menu,指定其pathadditions, 这表示我们的menu将添加到window的左边,因为这个就是workbench menubaradditons所在的位置, 如果指定的是window/additions, 那么将作为子菜单项添加到window 

当一个actionSet下定义的action跟另一个actionSet下定义的menu关联的时候将发生Invalid Menu Extension (Path is invalid): some.action.id的异常, 为了避免这种问题,menu需要在两个actionSet都定义 

toolbarPath
的指定也跟menuBarPath有同样的情况, 比如定义为Normal/additions, 这里的Normal指的是workbench toolbar, additions就是action要显示的group位置 

action
class属性是封装了执行动作的类,它实现了IWorkbenchWindowActionDelegate, 在它里面有几个方法需要介绍一下, 一个是selectionChanged, 用来动态修改actionstate状态值, 是否可用,以及actiontext属性等, 比如对于enableFor属性来说, 它根据选中对象的数量来判断action是否可用, 但是通过selectionChanged可以通过当前选定的对象的情况来调用setEnable()方法从而更精确的控制action是否可用, 有时候当插件还没有加载,在调用actionrun方法时会加载插件,这时可能在调用run()方法之前没有调用selectedChange方法, 因此在run()方面里面需要写一些防护性代码,比如空值的判断之类的, 另外run()是在主UI线程中执行的,因此,如果该执行耗时较长,需要将其放到后台线程中执行. 

插件运行之后在menubartoolbar上看到定义的actionSet,可以试试下面的方法: 
Window > Customize Perspective... 下看看是不是actionSet没有选中 
使用Window > Reset Perspective刷新当前视图 
关闭重新打开当前视图 
如果还没有出来,可以在在run或者debug的设置中将"Clear workspace data before launching "选中, 然后再启动运行 

虽然通过扩展点可以非常方便的在Eclipse上添加,但是这个玩意儿多了也不是什么好事, 可能会降低用户体验,因此需要进行控制, actionSet扩展点也有相关的设置来指定是否可见, 而且还可以调用IActionSetDescriptor.setInitiallyVisible() 来控制顶层菜单是否可见, 另一种解决办法就是在首选项中提供一个checkbox让用户决定是否显示顶层菜单,其编程实现就是在代码中调用IActionSetDescriptor.setInitiallyVisible()IWorkbenchPage.hideActionSet()来进行控制

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,感谢您对eclipse插件开发学习的关注!下面是一些学习笔记配套代码的例子。 1. 创建一个最简单的插件: ```java public class HelloWorldPlugin implements IStartup { @Override public void earlyStartup() { System.out.println("Hello, Eclipse Plugin Development!"); } } ``` 2. 在Eclipse菜单中添加一个新的命令: ```java public class MyCommandHandler extends AbstractHandler { @Override public Object execute(ExecutionEvent event) throws ExecutionException { MessageDialog.openInformation(HandlerUtil.getActiveWorkbenchWindow(event).getShell(), "My Command", "Hello, Eclipse Plugin Development!"); return null; } } ``` 3. 在编辑器右键菜单中添加一个新的动作: ```java public class MyEditorAction extends Action { public MyEditorAction() { setText("My Action"); } @Override public void run() { IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); if (editor instanceof ITextEditor) { ITextEditor textEditor = (ITextEditor) editor; IDocumentProvider documentProvider = textEditor.getDocumentProvider(); IDocument document = documentProvider.getDocument(textEditor.getEditorInput()); selectCurrentWord(textEditor, document); } } private void selectCurrentWord(ITextEditor editor, IDocument document) { ISelectionProvider selectionProvider = editor.getSelectionProvider(); ITextSelection selection = (ITextSelection) selectionProvider.getSelection(); int offset = selection.getOffset(); try { int lineStartOffset = document.getLineOffset(selection.getStartLine()); int lineEndOffset = lineStartOffset + document.getLineLength(selection.getStartLine()); String lineText = document.get(lineStartOffset, lineEndOffset - lineStartOffset); int wordStartOffset = lineText.lastIndexOf(' ', offset - lineStartOffset) + 1; int wordEndOffset = lineText.indexOf(' ', offset - lineStartOffset); if (wordEndOffset < wordStartOffset) { // The word is the last or only word on the line wordEndOffset = lineEndOffset - lineStartOffset; } else { wordEndOffset += lineStartOffset; } selectionProvider.setSelection(new TextSelection(wordStartOffset, wordEndOffset - wordStartOffset)); } catch (BadLocationException e) { e.printStackTrace(); } } } ``` 此处仅提供了一些简单的示例代码,以帮助您开始使用eclipse插件开发。有关更详细的学习和开发指导,请参阅Eclipse官方文档和教程。祝您在插件开发的学习过程中取得成功!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值