New File Without Project

The upcoming NetBeans Platform 7.4 @TemplateRegistration attribute requireProject is handy when you want to display a file template in the New File dialog when you have no project that relates to it. However, what if you not only have no related project but no interest in the NetBeans project system at all? Then you have a problem because you need the NetBeans project APIs if you want to have the New File dialog because the New File dialog classes are found in the modules that define the NetBeans project system. Lots of menus and toolbar buttons are added to your application for free, superfluously, and you spend time hiding them while at the same time the user gets a bunch of JARs that are not needed at all. Though the coupledness between projects and files makes complete sense from the perspective of NetBeans IDE, it would be nice if the New File dialog were to be in its own separate module from the perspective of non-project oriented NetBeans Platform applications.

A simple workaround is to forget the New File dialog completely, because of above stated dependencies on the project system, and create your own. Even simpler is to create a bunch of simple actions that create new files for you, which means that the whole project infrastructure isn't needed at all.

Here's an example, with thanks to the NetBeans Ribbon Bar project, provided by Chris Bohme from the awesome Maltego team.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;
import org.netbeans.api.actions.Openable;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
import org.openide.filesystems.FileUtil;
import org.openide.loaders.DataFolder;
import org.openide.loaders.DataObject;
import org.openide.loaders.DataObjectNotFoundException;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;

@ActionID(
        category = "File",
        id = "org.squibbly.file.odp.NewFile")
@ActionRegistration(
        displayName = "#CTL_NewFile")
@ActionReference(
        path = "Menu/File", 
        position = 0)
@Messages("CTL_NewFile=New File")
public final class NewFileAction implements ActionListener {

    private static AtomicInteger _integer = new AtomicInteger(0);

    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            DataObject gdo = getDataObject();
            Openable openable = gdo.getLookup().lookup(Openable.class);
            openable.open();
        } catch (DataObjectNotFoundException ex) {
            Exceptions.printStackTrace(ex);
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
    
    protected DataObject getDataObject() throws DataObjectNotFoundException, IOException {
        String templateName = getTemplate();
        FileObject fo = FileUtil.getConfigRoot().getFileObject(templateName);
        DataObject template = DataObject.find(fo);
        FileSystem memFS = FileUtil.createMemoryFileSystem();
        FileObject root = memFS.getRoot();
        DataFolder dataFolder = DataFolder.findFolder(root);
        DataObject gdo = template.createFromTemplate(
               dataFolder, 
               "New Document" + " (" + getNextCount() + ")");
        return gdo;
    }

    protected String getTemplate() {
        return "Templates/Other/file";
    }

    private static int getNextCount() {
        return _integer.incrementAndGet();
    }
    
}

You'd create one of the above for each type of document you'd like the user to be able to create. Note that "getTemplate" above, which points to the location in the filesystem where you've registered your template, probably thanks to the @TemplateRegistration annotation.

Comments:

Currently this code appears to write the contents of a template to memory, then open them in the associated editor the file type. I'm assuming when the editor is modified and the "Save" button is pressed, it prompts the user for a file location to save to.

How would this be modified if we know where we want to save the file on the file system? I want the template to be written to an actual file location before opening it for the user to edit.

Excellent post, thanks!

Posted by Michael Bishop on July 05, 2013 at 09:32 AM PDT #

How do I realize when the editor is modified and the "Save" button is pressed, it prompts the user for a file location to save to? I tried and it does not work automatically.

Regards
Andreas

Posted by Andreas Hauffe on September 29, 2013 at 12:08 PM PDT #

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today