I wrote this code a couple of weeks ago. It’s a nice idea on how to use generics in order to reduce the pain of using the Eclipse API.
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IObjectActionDelegate; import org.eclipse.ui.IWorkbenchPart; /** * An eclipse action delegate that performs operations on objects of the * specified type. Automatically handles multiple selections. Extend this class * specifying the type parameter of the object that the action operates on. * Implement the main logic in {@link #runOn(Object, IAction)}. * * @author Jaksa Vuckovic (vuckovja) * * @param */ public abstract class TypedAction<T> implements IObjectActionDelegate { protected List selectedElements = new ArrayList(); protected Shell shell; public void setActivePart(IAction action, IWorkbenchPart targetPart) { this.shell = targetPart.getSite().getShell(); } /** * The default implementation will iterate over all the selected elements and * invoke {@link #runOn(Object, IAction)} on every on of them. * * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) */ public void run(IAction action) { for (T element : selectedElements) { runOn(element, action); } } /** * Implement this to invoke the operation on one of the selected elements. * This method is called by {@link #run(IAction)} on every selected element. * * @param selectedElement one of the selected elements * @param action the action that has been run */ protected abstract void runOn(T selectedElement, IAction action); /** * The default implementation will enable the action if all the selected * elements are of type T. * * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, * org.eclipse.jface.viewers.ISelection) */ public void selectionChanged(IAction action, ISelection selection) { selectedElements.clear(); boolean enabled = false; if (selection instanceof StructuredSelection) { enabled = true; for (Iterator it = ((StructuredSelection) selection).iterator(); it.hasNext();) { try { T selectedElement = (T) it.next(); selectedElements.add(selectedElement); } catch (ClassCastException e) { enabled = false; break; } } } action.setEnabled(enabled); } }
Try to refactor your actions to extend this class and you will find a significant reduction in code size
PS: syntax highlighted by Code2HTML, v. 0.9.1
Thanks a lot.
This could further be enhanced by storing a reference to “selection” in selectionChanged() and then looping over the list in run() – This will reduce the execution overhead.
Just learning Eclipse and have limited use of generics. Doesn’t the class have to provide a definition of T somewhere? If the
code as it is here is cut and paste into the browser Eclipse complains.
If is added as an appended element to the TypedAction name it works — TypedAction
I’m not sure if that’s what is to be understood here.
Ooops, seems I’ve forgotten to put the after the name of the class. Will fix soon…