Showing an Action on a TopComponent Node
Posted
by Geertjan
on Oracle Blogs
See other posts from Oracle Blogs
or by Geertjan
Published on Thu, 21 Jun 2012 09:22:10 +0000
Indexed on
2012/06/21
15:21 UTC
Read the original article
Hit count: 206
/NetBeans IDE
Let's say you want to extend the tools in NetBeans IDE, specifically for TopComponents. When the user right-clicks in the Projects window (or Files window or Favorites window) on a Java class that extends TopComponent, a menu item should be available for branding the TopComponent. What "branding" entails is, at this stage, a secondary question. The primary question, from an implementation point of view, is "how do I create an action that is only shown when the user right-clicks on a TopComponent?"
Here's the solution, in NetBeans IDE 7.2 (the "lazy" attribute, here set to false, is new in 7.2):
import com.sun.source.tree.ClassTree; import com.sun.source.util.TreePathScanner; import java.awt.event.ActionEvent; import java.io.IOException; import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.JOptionPane; import org.netbeans.api.java.source.CompilationController; import org.netbeans.api.java.source.CompilationInfo; import org.netbeans.api.java.source.JavaSource; import org.netbeans.api.java.source.JavaSource.Phase; import org.netbeans.api.java.source.Task; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionReferences; import org.openide.awt.ActionRegistration; import org.openide.awt.DynamicMenuContent; import org.openide.loaders.DataObject; import org.openide.util.ContextAwareAction; import org.openide.util.Exceptions; import org.openide.util.Lookup; import org.openide.util.NbBundle.Messages; import org.openide.util.Utilities; @ActionID( category = "Tools", id = "org.tc.customizer.BrandTopComponentAction") @ActionRegistration( displayName = "#CTL_BrandTopComponentAction", lazy = false) @ActionReferences({ @ActionReference(path = "Loaders/text/x-java/Actions", position = 150) }) @Messages("CTL_BrandTopComponentAction=Brand") public final class BrandTopComponentAction extends AbstractAction implements ContextAwareAction { private final DataObject dobj; public BrandTopComponentAction() { this(Utilities.actionsGlobalContext()); } public BrandTopComponentAction(Lookup context) { super(Bundle.CTL_BrandTopComponentAction()); this.dobj = context.lookup(DataObject.class); //Enable the menu item only if we're dealing with a TopComponent JavaSource javaSource = JavaSource.forFileObject(dobj.getPrimaryFile()); try { javaSource.runUserActionTask(new ScanForTopComponentTask(this), true); } catch (IOException ex) { Exceptions.printStackTrace(ex); } //Hide the menu item if it isn't enabled: putValue(DynamicMenuContent.HIDE_WHEN_DISABLED, true); } @Override public void actionPerformed(ActionEvent ev) { JOptionPane.showMessageDialog(null, "Hurray, I am a TopComponent!"); //Now add your code for showing a dialog, //where the dialog will display UI for branding the TopComponent somehow //and retrieve those branding values //and then change the TopComponent class accordingly. } @Override public Action createContextAwareInstance(Lookup actionContext) { return new BrandTopComponentAction(actionContext); } private static class ScanForTopComponentTask implements Task<CompilationController> { private final BrandTopComponentAction action; private ScanForTopComponentTask(BrandTopComponentAction action) { this.action = action; } @Override public void run(CompilationController compilationController) throws Exception { compilationController.toPhase(Phase.ELEMENTS_RESOLVED); new MemberVisitor(compilationController, action).scan( compilationController.getCompilationUnit(), null); } } private static class MemberVisitor extends TreePathScanner<Void, Void> { private CompilationInfo info; private final AbstractAction action; public MemberVisitor(CompilationInfo info, AbstractAction action) { this.info = info; this.action = action; } @Override public Void visitClass(ClassTree t, Void v) { Element el = info.getTrees().getElement(getCurrentPath()); if (el != null) { TypeElement te = (TypeElement) el; if (te.getSuperclass().toString().equals("org.openide.windows.TopComponent")){ action.setEnabled(true); } else { action.setEnabled(false); } } return null; } } }
The code above is the result of combining various tutorials found on the NetBeans Platform Learning Trail.
© Oracle Blogs or respective owner