The default wizard provided by eclipse will let you add to the top-level toolbar or menu system using the concept of Actions and ActionSets. Option 1: ActionYou can use action directly - this is an acceptable approach if you are going to use the action within your plugin. newAction = new Action("New...") { public void run() { registerDatasource(); } }; newAction.setImageDescriptor(getImageDescriptor("new.gif")); Example use with a toolbar: IToolBarManager mgr = getViewSite().getActionBars().getToolBarManager(); mgr.add( newAction ); Contributing actions via action setsAn action set is a mechanism that allows a plug-in to contribute menus, menu items, and toolbar items to the main menu bar and toolbar of the Workbench window. It is important to understand what action sets are meant to be used for. An action set should contribute common actions which are not specific to any particular view or editor. Workbench and ActionsUses IWorkbenchWindowActionDelegate ... public class EditStyleAction implements IWorkbenchWindowActionDelegate { public final static String ID = "net.refractions.udig.style.openStyleEditorAction"; //$NON-NLS-1$ private Layer selectedLayer; public void dispose() { } public void init( IWorkbenchWindow window ) { } public void run( IAction action ) { Display.getDefault().asyncExec(new Runnable(){ public void run() { StyleView styleView = null; try { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); page.showView( StyleView.VIEW_ID ); styleView = (StyleView) if (selectedLayer != null); styleView.setSelectedLayer(selectedLayer); } catch (PartInitException e2) { e2.printStackTrace(); } } }); } public void selectionChanged( IAction action, ISelection selection ) { if (selection.isEmpty() || !(selection instanceof IStructuredSelection)) return; StructuredSelection sselection = (StructuredSelection)selection; if (sselection.getFirstElement() instanceof Layer) { selectedLayer = (Layer)sselection.getFirstElement(); } } } View and ActionsUses IViewActionDelegate ... View Context MenuThe class defined for the action must implement org.eclipse.ui.IViewActionDelegate interface if contributing to a view's context menu. EnablesFor attribute control the enabled/disabled state of the action based on the current selection. Its value is the selection count condition which must be met to enable the action. If not the action is disabled. If attribute is skipped default is enable for any number of items selected.
Here is an example used in udig with the zoom to layer action in the Layers View. <objectContribution adaptable="false" objectClass="net.refractions.udig.project.ILayer" id="net.refractions.udig.project.ui.LayerContribution"> <action label="%zoomToLayer.label" icon="icons/elcl16/zoom_layer_co.gif" tooltip="%zoomToLayer.tooltip" class="net.refractions.udig.project.ui.internal.actions.ZoomToLayer" style="push" id="net.refractions.udig.project.ui.zoomTo"/> </objectContribution> Then create the ZoomToLayer class that implements IViewActionDelegate public class ZoomToLayer extends ActionDelegate implements IViewActionDelegate { IStructuredSelection selection; public void selectionChanged( IAction action, ISelection selection ) { try{ this.selection=(IStructuredSelection) selection; }catch (Exception e) { //do nothing } } public void runWithEvent( IAction action, Event event ) { try { PlatformUI.getWorkbench().getActiveWorkbenchWindow().run(false, true, new IRunnableWithProgress(){ public void run(IProgressMonitor monitor){ Envelope bounds = new Envelope(); bounds.setToNull(); Map map=((Layer)selection.getFirstElement()).getContextModel().getMap(); for( Iterator iter = (selection).iterator(); iter.hasNext(); ) { Layer layer = (Layer) iter.next(); if( layer.getContextModel().getMap()!=map ) return; Envelope bbox=null; try { bbox = layer.getBounds(monitor, map.getViewportModel().getCRS()); } catch (IOException e) { } if( bbox==null) continue; if( bounds.isNull() ) bounds.init(bbox); else bounds.expandToInclude( bbox ); if( !bounds.isNull() ){ map.sendCommandASync(NavigationCommandFactory.getInstance().createSetViewportBBoxCommand(bounds)); } } } }); } catch (Exception e) { CorePlugin.log(ProjectUIPlugin.getDefault(), e); } } Editor and ActionsUses IEditorActionDelegate ... public class CommitAction implements IEditorActionDelegate { private MapEditor editor; public void setActiveEditor( IAction action, IEditorPart targetEditor ) { editor=(MapEditor) targetEditor; } public void run( IAction action ) { try { editor.getMap().getEditManagerInternal().commitTransaction(); } catch (IOException e) { // Shouldn't happen but... ProjectUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR, "net.refractions.udig.project",0,"Error commiting transaction",e)); //$NON-NLS-1$ //$NON-NLS-2$ } } public void selectionChanged( IAction action, ISelection selection ) { } } Object and ActionsUses IObjectActionDelegate ... Where are the Actions? Proxy Pattern and Actions In the quest for lazy loading of plug-ins the RCP makes use of the proxy pattern to delay the loading of Actions. For most instances a particular extention point will create a proxy based on configuration information; and it will be this proxy that turns around and creates/calls your class. This practice explains why we are always implementing IActionDelegate. |
(c) Copyright (c) 2004,2005 Refractions Research Inc. and others. |