Custom project file structure in NetBeans - new menu item in projects
In a previous post, I’ve told that I want to use NetBeans and share projects with developers that still use Eclipse. In another post, I added a custom folder to the project view.
Now, I will add a custom menu item to run an ant task outside NB’s build scripts:
- Assuming you have a NB module project ready, you just need to add a new entry in your layer.xml:
<folder name="Projects"> <folder name="Actions"> <file name="org-mycompany-MyMenuAction.instance"/> </folder> </folder> - Create a new class with the same name (org.mycompany.MyMenuAction):
public final class TransitMenuAction extends AbstractAction implements Presenter.Popup, ContextAwareAction { public final static String DISPLAY_NAME = NbBundle.getMessage(TransitMenuAction.class, "CTL_TransitMenuAction"); private Lookup context; public TransitMenuAction() { this(null); } public TransitMenuAction(Lookup context) { super(DISPLAY_NAME); this.context = context; } public void actionPerformed(ActionEvent e) { // I'm a menu container... I do nothing } public Action createContextAwareInstance( Lookup context) { return new MyMenuAction(context); } public JMenuItem getPopupPresenter() { return new PopupPresenter(); } /** Dynamic menu factory */ class PopupPresenter extends JMenuItem implements DynamicMenuContent { public JComponent[] getMenuPresenters() { Project proj = context.lookup(Project.class); // MyUtils comes from last post if (!MyUtils.isMyProject(proj)) { // hides this menu return new JComponent[0]; } JMenu mnu = new JMenu(DISPLAY_NAME); mnu.add(new PackageAction(context)); return new JComponent[] { mnu }; } public JComponent[] synchMenuPresenters( JComponent[] items) { return items; } } } - And, the PackageAction is:
public class PackageAction extends AbstractAction { private Lookup context; public PackageAction(Lookup context) { super(NbBundle.getMessage(PackageAction.class, "CTL_PackageAction")); this.context = context; } /* This action will copy a file and run an Ant task */ public void actionPerformed(ActionEvent e) { try { /* Both the file and the build scripts are under * the "ant" folder in project directory */ Project proj = context.lookup(Project.class); FileObject antFolder = proj.getProjectDirectory(). getFileObject("ant"); // Read the original file FileObject def = antFolder. getFileObject("compile-default.properties"); Properties prop = new Properties(); prop.load(def.getInputStream()); // Change a little bit // TODO: Add this to a property window prop.setProperty("compile.lib.ext", "C:\\etc\\apache-tomcat-6.0.14\\lib"); // Write to the copy file FileObject cpy = antFolder .getFileObject("compile.properties"); if (cpy == null) { cpy = antFolder.createData("compile.properties"); } FileLock lock = cpy.lock(); try { prop.store(cpy.getOutputStream(lock), "any cool comment"); } finally { lock.releaseLock(); } // Now, we will run Ant - grab the script... FileObject buildXML = antFolder .getFileObject("build.xml"); // ... and run the "package" target ActionUtils.runTarget(buildXML, new String[]{ "package" }, null); } catch (IOException ex) { Exceptions.printStackTrace(ex); } catch (IllegalArgumentException ex) { Exceptions.printStackTrace(ex); } } } - Last, but not least, the project dependencies:
- Ant (ActionUtils)
- Filesystem API (FileObject and FileLock);
- Project API (Project);
- UI Utilities API (DynamicMenuContent); and
- Utilities API (Lookup)
And, your new project menu item (that calls an Ant task) is ready.
Tags: action, ant, build, eclipse, migration, NetBeans, project, script