Friday Nov 28, 2008

Conociendo a NetBeans Platform: Introducción

Wednesday Nov 26, 2008

Two New Chinese Tutorials for NetBeans Platform 6.5

Two of the newest tutorials that relate to NetBeans Platform 6.5 are now translated into Chinese:

The first is the Code Generator tutorial, the second is the Quick Search tutorial.

Thanks, Will Zhang, for translating them!

Monday Nov 24, 2008

Sharing ExplorerManagers Between TopComponents

The NetBeans ExplorerManager class is great—it lets you display the same set of nodes in multiple explorer views while synchronizing the selection. In other words, if you select a node in one explorer view, it will automatically also be selected in another explorer view.

An explorer view is placed on a TopComponent that implements ExplorerManager.Provider, with the ExplorerManager's root context being set to the root node. Then everything happens magically from there thanks to the ExplorerManager: each explorer view in the TopComponent will have synchronized selection management for the node hierarchy. But... what if the explorer views are in DIFFERENT TopComponents? Below is a perfect example. The explorer view on the left (BeanTreeView) displays nodes, while the explorer view on the right (PropertySheetView) presents a different view on the same nodes, which should therefore be synchronized with each other:

In other words, the explorer views are in different TopComponents. If, as normal, you instantiate the ExplorerManager in each of the TopComponents, you have TWO ExplorerManagers... which means you will have no selection management between the nodes in the different explorer views.

Here's the solution to this problem.

  1. Create a new Java class that defines an explorer manager:
    package org.my.demo;
    
    import org.openide.explorer.ExplorerManager;
    
    public class MyExplorerManager implements ExplorerManager.Provider {
    
        private ExplorerManager em;
    
        public ExplorerManager getExplorerManager() {
            if (em == null) {
                em = new ExplorerManager();
            }
            return em;
        }
        
    }

  2. Create a new folder (with any name you like) in the layer.xml file and then register the above class there:
    <folder name="ExplorerManagers">
        <file name="org-my-demo-MyExplorerManager.instance"/>
    </folder>

    At runtime, the ExplorerManager is available in the filesystem and any module in the application can make use of it.

  3. In each of your TopComponents, implement ExplorerManager.Provider, exactly as you would always do. However, instead of creating a new ExplorerManager, get the one above from the filesystem via the Lookup. For example, this is the PropertiesTopComponent you see above:
    private ExplorerManager em;
    
    private PropertiesTopComponent() {
    
        initComponents();
    
        setName(NbBundle.getMessage(PropertiesTopComponent.class, "CTL_PropertiesTopComponent"));
        setToolTipText(NbBundle.getMessage(PropertiesTopComponent.class, "HINT_PropertiesTopComponent"));
    
        em = Lookups.forPath("/ExplorerManagers").lookup(Provider.class).getExplorerManager();
        em.setRootContext(new AbstractNode(new WordChildren()));
    
    }

    Note the line in bold, of course, which looks in the specified filesystem folder for a class of the required type.

  4. Do the same for all the other TopComponents that need to have the same ExplorerManager handling the selection for their explorer views.

What's nice about this solution is that it leverages some of the central tenets of the NetBeans Platform: selection management, explorer views, nodes, lookup, filesystem... It's a perfectly NetBeans-centric approach to this problem. The most interesting part is the registration of the ExplorerManager in the layer.xml, because it is yet another example of the cool things you can do if your application has a filesystem. And all NetBeans Platform applications automatically have one of those for the whole system.

Warsaw on the NetBeans Platform!

Karol Harezlak, Toni Epple, and I spent the last two days with Jacek Sroka and his group of students from the Faculty of Mathematics, Informatics, and Mechanics at the University of Warsaw, delivering the NetBeans Platform Certified Training. Here's the whole group at the end of the training:

(I'm not in the picture because I was holding the camera that took it.) For the first time, despite being limited to our two day parameter, we extended the program to include 3 hours of workshops on both days. So, instead of the standard 5 hours, we did 8 hours both days, starting at 9.00 and ending at 17.00. This was certainly a better solution than previously, where hands on work was left until the end of the two days. However one looks at it, two days isn't much, but on the other hand, we're not fulltime trainers and are unable to make much more than that available (i.e., Karol is one of the engineers in the Mobility team and I am a technical writer in the Docs team). But, this solution, of inserting 3 hours of workshops (i.e., after/during three of the presentations, the students were able to do some exercises to begin working with some of the concepts that were introduced), is a pretty nice compromise.

Here you see part of the group intently listening to one of the presentations:

But it wasn't all hard work for Karol, Toni, and me. On the evening of the first training day, Jacek Laskowski invited us to a party for the Eclipse Demo Camp that was being held at the same time. We had a really good time, thanks Jacek and others from the Eclipse Demo Camp. Here you see someone we met (from Gdansk, who was also at the NetBeans Day there some weeks ago), Toni, and me at the party:

And here you see some more of the scene at the party:

Next day it was back to school for everyone. By the way, it was really great to have Toni participate: he did the presentation on the System FileSystem and also on the Visual Library (for the first time, this was included in the course). He's really excellent: he doesn't work for Sun and is therefore a more credible NetBeans advocate than I or Karol can be. He has his own Java Consulting and Project Outsourcing company and knows the NetBeans APIs from having worked with them at a company where he led the design and implementation of a NetBeans Platform application. He's also very enthusiastic about the NetBeans Platform and its APIs and can explain how they work very well. Here's one of his slides, during the Visual Library workshop:

Finally, the students received their certificates. Here's one of them, Tomasz Frydrychewicz:

I'm looking forward to going back to that university some day soon. Some of the students are going to be doing their university thesis about the NetBeans Platform. Jacek said that in a future course there, there could be completely new people to the course, so we could start again from scratch. We could also go further into the NetBeans Editor APIs, because the students seemed particularly interested in that.

Students who were on the course and who want to get the next level of certification will be working on NetBeans modules (either for NetBeans IDE or some other application on the NetBeans Platform). They'll need to go through a quick registration process to get a NetBeans.org account, after which they'll be able to register at this mailing list (where all the NetBeans Platform experts are found): dev@openide.netbeans.org

Then, before beginning the work on their idea, they'll write to the mailing list to see if others aren't working on it already. If others are working on their idea, they'll potentially be able to join someone else's project, which would be very cool too. Looking forward to hearing their ideas!

By the way, the student from a previous course (in Germany) who is working on 'batch refactoring' for NetBeans IDE is making some great progress, read all about it in the issue below:

http://www.netbeans.org/issues/show_bug.cgi?id=25377

Friday Nov 21, 2008

Children.Keys for Presenting Layer Folders & Files

Here's what's in my layer.xml:
<folder name="Words">
    <file name="ajva">
        <attr name="unscrambled" stringvalue="java"/>
    </file>
    <file name="ynamicd">
        <attr name="unscrambled" stringvalue="dynamic"/>
    </file>
</folder>

And here's a Children.Keys class for creating a presentation layer on top of the folders and files above:

public class WordChildren extends Children.Keys<String> {

    @Override
    protected void addNotify() {
        FileObject words = Repository.getDefault().getDefaultFileSystem().findResource("Words");
        FileObject[] fos = words.getChildren();
        String[] s = new String[fos.length];
        for (int i = 0; i < s.length; i++) {
            s[i] = fos[i].getName() + " (" + fos[i].getAttribute("unscrambled") + ")";
        }
        setKeys(s);
    }

    @Override
    protected Node[] createNodes(String name) {
        AbstractNode WordChildrenNode = new AbstractNode(Children.LEAF) {
            @Override
            public String getHtmlDisplayName() {
                String normal = getDisplayName().substring(0, getDisplayName().indexOf("("));
                String greyed = getDisplayName().substring(getDisplayName().indexOf("("));
                return "<b>" + normal + "</b><i><font color=\\"#808080\\">" + greyed + "</font></i>";
            }
        };
        WordChildrenNode.setDisplayName(name);
        return new Node[]{WordChildrenNode};
    }

}

Here's the result, when you instantiate the above via an Explorer Manager, while an explorer view is available to it:

One of the cool things about putting your data in the layer.xml is that then other modules can add their own data to those same folders and they can even be ordered relative to each other. Then the code above will load that data, which is why there are FOUR word combinations in the screenshot above, because the NetBeans runtime container merges all the layer.xml files into one single hierarchical filesystem. Hurray for the NetBeans runtime container!

Wednesday Nov 19, 2008

Getting Started with the Print API

The next newly official API in 6.5 is the Print API. It works in the same way as the new 'feature' that lets you specify the size of the popped-out TopComponent: via a client property (which implies that there should be the same ui for it, i.e., a checkbox in the Window Component wizard):

 

putClientProperty("print.printable", Boolean.TRUE); // NOI18N

Just put the above in your TopComponent constructor and you're good to go. Let's say, for example, that this is what your TopComponent looks like...

Now, to provide Print functionality, all you need to do is add the above single line of code to the constructor of the above TopComponent. Then the File | Print menu item will automatically be enabled. Alternatively, instead of clicking that menu item, press Ctrl-Alt-Shift-P. (According to Tom Wheeler in an e-mail to me, in order to do this "you'd need amazing dexterity, several years of emacs experience or assistance from a passerby to press all those keys simultaneously".)

You'll then find yourself with this dialog, which you can use for printing purposes:

That's pretty cool. One step in the direction of providing business functionality out of the box. I'm looking forward to similar enablement-functionality for login, persistence, and other business/CRUD functionality, as described here in Issuezilla (which should get you here at some point). After all, as someone said at the NetBeans Demo Camp in Munich: "Why does JSR-296 have a cool business application generator in NetBeans IDE, while the NetBeans Platform doesn't?" Good question! The concept of a NetBeans Business Platform (something that Ralph Lance, at the same demo camp in Munich, asked me about... 3 years ago or so... and I was reminded of the moment I saw him again) would be great to introduce. It would be an absolutely killer approach to all the low level NetBeans Platform details.

Tuesday Nov 18, 2008

Getting Started with the Database Explorer API

Now that the Database Explorer API is official, I need to write a tutorial covering some typical things that you might want to do with it. David Van Couvering, who leads this area of NetBeans, provided me with the following notes. Thanks a lot David. The use case is that of a developer wanting to inspect metadata for a connection in the Database Explorer.
  1. Get a connection. Normally the first step for this is to find out what connection the user wants to use. We provide a helper utility that provides you with a combo box containing all current connections in the Database Explorer, as well as the ability to create a new connection. Here's how you might use this API:

    • In your UI, create a combo box.

    • Associate the combo box with the utility:
      DatabaseExplorerUIs.connect(dbconnComboBox, ConnectionManager.getDefault());
    • In your action listener for your combo box:
      Object selected = dbconnComboBox.getSelectedItem();
              if (selected instanceof DatabaseConnection) {
                  dbconn = (DatabaseConnection) selected;
      }
  2. Make sure you're connected. It's possible your database connection is not connected. Here's what you do:
           Connection conn = dbconn.getJDBCConnection(true);
            if (conn == null) {
                ConnectionManager.getDefault().showConnectionDialog(dbconn);
            }
            conn = dbconn.getJDBCConnection(true);
            if (conn == null) {
                // user chose not to connect, handle this
            }
Get metadata. Let's say you want to get all the tables for the connection. We are going to be adding a new Metadata API, but for now you just use the native JDBC DatabaseMetadata. So, for example:
       Connection conn = dbconn.getJDBCConnection(true);
        try {
            ResultSet rs = conn.getMetaData().getTables(null, null, "\*", new String[]{"TABLE"});
            while (rs.next()) {
                System.out.println("Table name is " + rs.getString("TABLE_SCHEMA") + "." + rs.getString("TABLE"));
            }
        } catch (SQLException sqle) {
            // handle me
        }

For example, here's a TopComponent showing the result of the code above:

Finally, here's some code, also from David, for dragging and dropping in a snippet. It comes from J2EEComponentDropProvider.java in org.netbeans.modules.form.j2ee:

    /\*\*
     \* Processes given transferable and returns the corresponding
     \* NewComponentDrop.
     \*
     \* @param formModel corresponding form model.
     \* @param transferable description of transferred data.
     \* @return NewComponentDrop that corresponds to given
     \* transferable or null if this provider
     \* don't understand to or don't want to process this data transfer.
     \*/
    public NewComponentDrop processTransferable(FormModel formModel, Transferable transferable) {
        try {
            if (transferable.isDataFlavorSupported(DatabaseMetaDataTransfer.CONNECTION_FLAVOR)) {
                DatabaseMetaDataTransfer.Connection connection = (DatabaseMetaDataTransfer.Connection)transferable.getTransferData(DatabaseMetaDataTransfer.CONNECTION_FLAVOR);
                return new DBConnectionDrop(formModel, connection);
            } else if (transferable.isDataFlavorSupported(DatabaseMetaDataTransfer.COLUMN_FLAVOR)) {
                DatabaseMetaDataTransfer.Column column = (DatabaseMetaDataTransfer.Column)transferable.getTransferData(DatabaseMetaDataTransfer.COLUMN_FLAVOR);
                return new DBColumnDrop(formModel, column);
            } else if (transferable.isDataFlavorSupported(DatabaseMetaDataTransfer.TABLE_FLAVOR)) {
                DatabaseMetaDataTransfer.Table table = (DatabaseMetaDataTransfer.Table)transferable.getTransferData(DatabaseMetaDataTransfer.TABLE_FLAVOR);
                return new DBTableDrop(formModel, table);
            }
        } catch (Exception ex) {
            // should not happen

            Logger.getLogger(getClass().getName()).log(Level.INFO, ex.getMessage(), ex);
        }
        return null;
    }

All the above code will be part of a new tutorial soon.

Friday Nov 14, 2008

Zembly, Sang Shin, and Swing

I took the first half of Sang Shin's Zembly Basics course today. It was the first time that I'd ever used Zembly. I didn't even really know what it was, before taking Sang's course.

It seems pretty cool. Zembly is an on-line platform for creating 'things', which are 'services', 'widgets', and 'applications'. First you create services (such as a weather service) and then you create widgets that provide a presentation layer on top of the services (such as a widget where the user needs to type in a zip code for the area of interest for the weather service). Then you make the widgets available to others, by embedding them in your website, or something similar. (You can also create applications, but that's the second part of the course, which I haven't done yet.) You can very easily reuse other people's services and widgets too. Hard to visualize all this without doing it yourself, though.

So then I created a service following Sang's instructions and then thought: "Why would I create an on-line widget when I could just as easily create a widget in Swing?" So I created a small NetBeans module that calls my service from a menu item:

public final class GreetMeAction implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        int ageValue = 34;
        String nameValue = "Tom";
        try {
            URL zemblyServiceURL = new URL("http://zembly.com/things/099efc10ebed4e4899decd62d7aad4ba;exec?name=" + nameValue + "&age=" + ageValue);
            URLDisplayer.getDefault().showURL(zemblyServiceURL);
        } catch (IOException ex) {
            Exceptions.printStackTrace(ex);
        }
    }
    
}

Then the browser opens, displaying this result:

Hi Tom! Your age is 34

So, the menu item is the widget for my Zembly service. It would be even better to be able to receive the results within Swing, rather than needing to open the browser to see them. Not sure how that would be done, though. But, imagine creating a weather service in Zembly. Then you'd (under the hood of your module) call that service and then do something with the results, within the module itself. But how could one get access to the results?

Thursday Nov 13, 2008

Overview of Brno NetBeans Platform Training Demos

Some of the students from the recent NetBeans Platform Training in Brno asked for a list of the demos (the related slides are all here) done during the training.

Here it is:

  • Presentation: Introduction to the NetBeans Platform. At the end of this presentation, a demo was done of the Anagram Game being ported to the NetBeans Platform. For details, see the NetBeans Platform Porting Tutorial.

  • Presentation: Dependency Injection & Modular Systems. During this presentation, a first module was created, and the students were shown how dependency management and versioning is handled for a module. At the end, an application with three modules was created—one module contained a service exposed via an interface, the next module was the service provider via the META-INF/services folder, and the third module was an Installer class that printed out the Strings provided by the service providers. For details, see this tutorial: NetBeans Selection Management Tutorial I—Using a TopComponent's Lookup.

  • Presentation: System Filesystem. During this presentation, demos were done that showed how to create a layer.xml file and how to populate it—via the module project wizard and the file-level wizards. Also, the explorer view on top of the layer.xml file was shown, i.e., the "this layer" and "this layer in context" nodes were explored and discussed. See all the NetBeans Platform tutorials for details.

  • Presentation: Nodes & Explorer Views. At the start of this presentation, a standalone Java application was created, with about 5 NetBeans Platform JARs on its classpath, which enabled a Node to be created, and displayed in multiple different views. See here for the code. Then the application was ported to the NetBeans Platform. Also, the students were shown how to create a System Filesystem browser (as described on page 204 of 'Rich Client Programming: Plugging into the NetBeans Platform'). Finally, the System Filesystem browser was uploaded to the Plugin Portal (here), at which point the topic of 'autoupdate descriptors' was also discussed, together with different techniques for distributing modules.

  • Presentation: Data Objects & Editors. Here it was shown how to create and register basic editor support for a new file type, via the File Type wizard. A new action was added to the node in the explorer view. The 'Schliemann' declarative editor support was also introduced, starting with the Language Support template.

  • Presentation: Window System. A new TopComponent was created and added to a new application's window system, via the layer.xml file. The persistence of the TopComponent was extended, so that not only the size and position of the window was stored across restarts, but also the content of one of its text fields, exactly as described in Playing with Persistence Across Sessions. In addition, the creation of a new mode was also discussed, and demoed, to some extent.

  • Presentation: Productivity Tools. During this presentation, on different ways in which the NetBeans Java editor can be extended, small demos were done of the following features (click the links that follow to get to the source code)—code completion, code generator, mark occurrences, quick search, project template, file template, and editor hints.

Is the above description detailed enough? If there was someone on the course who'd like more details, feel free to leave a comment here.

Wednesday Nov 12, 2008

@org.netbeans.spi.project.LookupProvider.Registration

It's been possible since 6.1 to extend an existing project type's Lookup, by means of the layer.xml file. The NetBeans Project Type Extension Module Tutorial provides all the details. From today onwards (as recorded in the NetBeans API Changes document), however, in line with the annotation-based approach for registration of NetBeans artifacts, as introduced here in a recent blog entry, it is also possible to register Lookups via an annotation (instead of via the layer.xml).

So, the example in the tutorial can now (from 7.0 onwards, anyway, since it's in the development build from today, which is therefore not part of 6.5) be rewritten as follows:

@org.netbeans.spi.project.LookupProvider.Registration(projectType="org-netbeans-modules-web-project")
public class LookupProviderImpl implements LookupProvider {

    @Override
    public Lookup createAdditionalLookup(Lookup lookup) {

    ...
    ...
    ...

Therefore, note the new annotation above for project type Lookup extensions. By the way, I've actually tried the above in a build from a few hours ago, and it works exactly as advertized. Read here for the rewritten Lookup extension for Java project types, in order to support, for example, Groovy, as well as the issue itself, which is issue 152392.

Tuesday Nov 11, 2008

Setting a Node's Tooltip on the Fly

I expanded my API today. It now looks like this:
package org.netbeans.demo;

public interface User {

    public String getName();

    public String getDescription();
    
}

As a result, the other module, i.e., the one that provides the service, now needs to update its service provider class:

package org.netbeans.demo;

import org.netbeans.demo.User;

public class User1 implements User {

    private String name;
    private String description;

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getDescription() {
        return description;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setDescription(String description) {
        this.description = description;
    }

}

So, now, in the editor component, I add the user name and user description to the InstanceContent when the Enter key is pressed in the editor, which updates the node hierarchy even though the node hierarchy is in a different module to where the editor component is found:

Finally, in order to handle both the name and the description, the Children.Keys subclass now works with a string array, instead of a string, to get the name and description which are used in the creation of the node hierarchy:

public class UserChildren extends Children.Keys<String[]> implements LookupListener {

    private Lookup.Result result = null;
    private ArrayList<String[]> userDetails = new ArrayList();

    public UserChildren() {
        result = Utilities.actionsGlobalContext().lookupResult(User.class);
        result.addLookupListener(this);
    }

    @Override
    public void resultChanged(LookupEvent lookupEvent) {
        Collection c = result.allInstances();
        for (User user : c) {
            userDetails.add(new String[]{user.getName(), user.getDescription()});
        }
        setKeys(userDetails);
    }

    @Override
    protected void addNotify() {
        resultChanged(null);
    }

    @Override
    protected Node[] createNodes(String[] userDetails) {
        return new Node[]{new PropNode(userDetails)};
    }

    private class PropNode extends AbstractNode {

        private PropNode(String[] userDetails) {
            super(Children.LEAF);
            setDisplayName(userDetails[0]);
            setShortDescription(userDetails[1]);
        }
        
    }

}

Notice that AbstractNode.setShortDescription sets the tooltip. I also tried working with AbstractNode.setIconBaseWithExtension, but that unfortunately assumes that the image is within the module, so it is not possible to have the user select an external image (i.e., on disk) for setting a node's icon on the fly.

Monday Nov 10, 2008

LookupListener & Children.Keys

My first LookupListener on Children.Keys enables the two window components you see below to be decoupled from each other:

Whenever the Enter key is pressed in the editor component, a new instance of the API object is added to my InstanceContent, exactly as described in the first part of Tim's 'Selection Management' series. This component, the provider of the API object, is exposed via the META-INF/services folder.

Whenever the Children.Keys class (which is in a separate module) detects that a new API object is available in the global lookup, a new item is added to the list that is used to create the nodes in the hierarchy. Here's the Children.Keys with LookupListener:

public class UserChildren extends Children.Keys implements LookupListener {

    private Lookup.Result result = null;
    private ArrayList list = new ArrayList();

    public UserChildren() {
        Lookup.Template tpl = new Lookup.Template(User.class);
        result = Utilities.actionsGlobalContext().lookup(tpl);
        result.addLookupListener(this);
    }

    @Override
    public void resultChanged(LookupEvent lookupEvent) {
        Lookup.Result r = (Lookup.Result) lookupEvent.getSource();
        Collection c = r.allInstances();
        for (int i = 0; i < c.size(); i++) {
            User user = (User) c.iterator().next();
            list.add(new String(user.getName()));
        }
        //Call this to let the nodes be recreated
        //when the result changes:
        addNotify();
    }

    @Override
    protected void addNotify() {
        setKeys(list);
    }

    @Override
    protected Node[] createNodes(String key) {
        return new Node[]{new UserNode(key)};
    }

    private class UserNode extends AbstractNode {
        private UserNode(String key) {
            super(Children.LEAF, Lookups.fixed());
            setDisplayName(key);
        }
    }

}

In other words, the viewer component is populated on the fly, based on the name typed into the editor component. And if the editor component is replaced by a different editor component, the viewer component will be unaffected: so long as it receives implementations of the API object, it will function correctly regardless of the editor's implementation.

 

PS: After some code cleaning (see the comments below) the code above is now as follows:

public class UserChildren extends Children.Keys<String> implements LookupListener {

    private Lookup.Result result = null;

    public UserChildren() {
        result = Utilities.actionsGlobalContext().lookupResult(User.class);
        result.addLookupListener(this);
    }

    @Override
    public void resultChanged(LookupEvent lookupEvent) {
        ArrayList list = new ArrayList();
        Collection<User> c = result.allInstances();
        for (User user : c) {
            list.add(new String(user.getName()));
        }
        setKeys(list);
    }

    @Override
    protected void addNotify() {
        resultChanged(null);
    }

    @Override
    protected Node[] createNodes(String key) {
        return new Node[]{new UserNode(key)};
    }

    private class UserNode extends AbstractNode {

        private UserNode(String key) {
            super(Children.LEAF);
            setDisplayName(key);
        }

    }

}

In other news. DZone has a new Refcard... a cheat sheet for MySQL! Take a look. It's free.

 

Sunday Nov 09, 2008

Brno on the NetBeans Platform!

I spent the weekend in Brno (second city in Czech Republic, after Prague), with students from the Masaryk University, delivering the NetBeans Platform Certified Training, together with Petr Adamek, their instructor (in the purple shirt below):

Petr and I split the sessions between us and it worked really well. He did some sessions in Czech and some In English. He's got good experience with the NetBeans Platform and is a really great teacher, bringing across the conceptual understanding of the NetBeans Platform very clearly. And he definitely isn't a default implementation of the "Trainer" interface—he has his own vineyard, which enabled him to present a workshop on wine tasting, starting at the end of the first day of training (and ending late that same night):

That was really a cool experience. We must have tasted about 10 different wines, including one that he made himself.

Another very interesting thing is that most (almost all) of the students in the class are doing their university thesis (some of them bachelor and some of them master) on the NetBeans Platform! For example, one will create TestNG support, another will provide Stripes support, and another will provide DBUnit support, while someone else will work on Wiki editing support. Some kind of support already exists for some of these, but not on the full blown scale that the students are planning to provide. If any of the students are reading this, they should click here and read about another Masters degree on the NetBeans Platform, done recently in Linz, Austria.

And, finally, just in case anyone reading this wonders whether we did anything other than taste wine, here's a pic of part of the class during one of the presentations:

Thanks to everyone for spending their weekend with the NetBeans Platform! I will be answering several of the remaining technical questions in this blog over the coming days, together with some new tutorials that I will create as a result of some of the questions, and I will also provide pointers to the demos that I did, soon.

Saturday Nov 08, 2008

NetBeans Platform for Kids

Here's a pic of Robert Appleby, one of the recent NetBeans Podcast Puzzler winners, who is the Webmaster for the Australian Hydrographic Service in Australia. He looks after website infrastructure, website design & development, and coding of in-house software. His main focus at the moment is building online web mapping systems for Hydrographic data.

On the left is Robert and on the right his 3 year old son Liam who wanted to take the book to pre-school! "So," writes Robert, "the book is being introduced for show-and-tell to a bunch of 2-5 year-olds."

Just like Allan Davis recently, Robert has received two books instead of one, because of the first having been delayed in the mail. Robert's planning to give the second book away as a prize at the Illawarra Java Users Group, which Robert has just joined, at the next meeting in late November. So if you're from Australia, that's another reason to go there!

Thursday Nov 06, 2008

18 November: NetBeans Demo Camp, Munich

If you're in Germany (anywhere in Germany, come on, it's not so big, Munich is more or less accessible from everywhere), here's a program (in draft form, but this is the basic idea) that you can't afford to miss, for the first NetBeans Demo Camp in Munich:
  • "New Features in NetBeans Platform 6.5"
    Geertjan Wielenga, NetBeans Guru, Sun Microsystems Inc., Prag.

  • "Demosession: ChipInspector - NetBeans APIs im Einsatz"
    Tanja Drüke, Genomatix Software GmbH, Munich, Germany.

  • "RCP Entwicklung in der Praxis: Third-party libraries und ClassLoader"
    Anton Epple, NetBeans Dream Team Member, Eppleton, Munich, Germany.

  • "Portierung von Swing Applikationen auf die NetBeans Platform"
    Aljoscha Rittner, CEO, Sepix GmbH, Hann. Münden, Germany.

  • "Grosseinsatz - NetBeans RCP im Grossprojekt"
    Sven Reimers, NetBeans Dream Team Member, ND SatCom Defence GmbH, Immenstadt, Germany.

That's about the best set of NetBeans Platform presentations one can imagine. Apart from myself, everyone on the program is loosely coupled from Sun, talking about their own practical experiences with the NetBeans Platform in corporate Swing application development environments. Tuesday, 18 November, from 16.00 to 20.00. All the details for this event, also for registration purposes and how to get there, can be found here:

http://netbeansdemocamp.eventbrite.com/

The usage of the plural "pubs" in the following statement is especially promising: "The event will officially end at 8 p.m. After the event we will celebrate NetBeans 10th birthday and the release of NB 6.5 in nearby pubs."

How to Create a Menu Item to Invoke a PDF Document

In situations where you want a menu item to produce a PDF document (e.g., as in the case with the shortcuts.pdf card in NetBeans IDE), do the following:

  1. Switch to the Files window, create a top-level folder called 'release' in your module source structure, and put your PDF document there.

  2. Create an XML file with this content:
    <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD PDF Document Menu Link 1.0//EN" 
    "http://www.netbeans.org/dtds/pdf_link-1_0.dtd">
    <pdfLink>
        <idefile base="shortcuts"/>
    </pdfLink>

    The above implies that the document will be named 'shortcuts.pdf' and that it will be found within the main folder of the module. If you put 'docs/shortcuts', for example, then the 'docs' folder of the module will be used instead. But then you would have to put the PDF in 'release/docs' instead.

  3. In your layer.xml file, register the above XML file, which in this case is called 'shortcuts.xml', as follows:
    <file name="shortcuts.xml" url="nbresloc:/com/me/bla/shortcuts.xml">
         <attr name="SystemFileSystem.localizingBundle" stringvalue="com.me.bla.Bundle"/>
         <attr name="position" intvalue="480"/>
    </file>

  4. In the Bundle referenced above, put the following:
    Menu/Help/shortcuts.xml=Keyboard Shortcuts

Thanks to this mail thread, I put the above steps together. Similarly, you can open a URL instead of a PDF from a menu item, following these instructions.

Wednesday Nov 05, 2008

Student Project: Other Actions for Multiple Files?

Recently I reported on the 'batch refactoring' project by one of the NetBeans Platform students at the Julius-Maximilians-Universität, in Würzburg, Germany. Here is that article, called "NetBeans Platform Student Projects: Batch Refactoring". There is progress in this project, as you can see here:

It works perfectly. You right-click a package and then the actions above can be used to format all the Java files in the package or to fix the imports of all the Java files in the package. I like it a lot and it's a standard part of my installation now. I'm hoping Lorenz Weber, i.e., the student working on this project, will put the plugin in the Plugin Portal soon. Until then, all the code is here, in the issue, though it takes a little bit of work to figure it all out:

http://www.netbeans.org/issues/show_bug.cgi?id=25377

The next question is: are there other multi-file actions that should be included in this project? Lorenz would like to know—leave a comment here with your suggestions and he'll consider incorporating them.

Monday Nov 03, 2008

@org.openide.util.lookup.ServiceProvider

Read issue 150447 and then look at the code below:
public interface DemoInterface {
    
    public String getName();

}
@org.openide.util.lookup.ServiceProvider(service=DemoInterface.class)
public class DemoServiceProvider1 implements DemoInterface {

    public String getName() {
        return "John";
    }

}
public class Installer extends ModuleInstall {

    @Override
    public void restored() {
        for (DemoInterface di : Lookup.getDefault().lookupAll(DemoInterface.class)) {
            System.out.println("Hello " + di.getName());
        }
    }

}

The above works using a build I picked up today. No more META-INF/services (unless you want to continue using that approach). I especially like Jarda's comment in that issue: "This is how our future should look like". Would be nice to work with Actions and so on via annotations and to increasingly forget the layer.xml file. Seems extremely likely that will be increasingly possible. That would be the biggest revolution for the NetBeans Platform since its creation.

Sunday Nov 02, 2008

Camtasia & Top 10 NetBeans APIs

I'm beginning to figure out some of the basic things needed for making Camtasia work the way one would expect it to. I've just posted part 3 of "Top 10 NetBeans APIs" on NetBeans Zone (here). This is how it all looks inside Camtasia. For the first time I have multiple small parts that I'm stringing together via Camtasia's handy story boarding tools:

I'm hoping that my next screencast will have a more steady volume between the individual parts. (But then again, what's wrong with variation.) Apart from that, I've got everything working the way I want it.

The whole series is being published here: Video: Top 10 NetBeans APIS

Saturday Nov 01, 2008

Two RCP Books Found At Last

Below is a pic of Allan Davis, the chair of the New Orleans Java users group (CajunJUG). CajunJUG meets every third Thursday of the month (so if you're from that part of the world and you're not going to these meetings, maybe you should start going this month) and are doing a series on JPA with the NetBeans Platform, which sounds pretty interesting. (Looking forward to seeing blogs about it!) Here you see Allan giving out two copies of "Rich Client Programming: Plugging into the NetBeans Platform" at the end of the meeting, to Sophie Hung and Paul Williams. (They won by the luck of the random number generator.)

And guess how Allan ended up with those books? He won the NetBeans Podcast Puzzler some months ago. We first thought the prize we sent him (one of the two books above) had got lost in the mail and so we sent him another one. So... he ended up with two prizes—and it seems like they found good homes!

By the way, Allan is one of the people working on nbPython and you can read an interview with him about that here on NetBeans Zone from some time ago.

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
« November 2008 »
SunMonTueWedThuFriSat
      
4
7
15
16
17
20
22
23
25
27
29
30
      
Today