Thursday Oct 30, 2008

In Praise Of... Russell Brand

One of my favorite columnists from my favorite newspaper, the Guardian, is in "a spot of bother". (He made an "inappropriate" prank call on his BBC 2 radio program.) I have been an admirer of Russell Brand for several years. His weekend sports column, focusing primarily on his love for West Ham, the football club of which he is an ardent fan (and which turned out to be a dank little corner of London when I ended up near there accidentally about a year ago), is simply brilliant. His sentences are colorful, lively, warm, amazing. And completely original. His metaphors are incredible. He makes reading about sport a literary endeavor. Read these articles to get an impression of his style:

I'd never have thought I'd use this word to describe someone's way of speaking, but I saw his language referred to recently as "baroque", which is exactly right.

To see his true & 100% original brilliance, a David Letterman piece should serve well:

Other things I've seen of him on YouTube are a lot less good than the above (though his appearance on the Craig Ferguson show was also pretty brilliant). Anyway, I never knew that he had a show on BBC 2 and, now that I know, I'm very surprised at that. They don't deserve him and never did. Good for him for having resigned. And I'm looking forward to his next column already (one of the highlights of my weekend).

Wednesday Oct 29, 2008

5 Minute Video: How Grails Does AJAX

Brief introduction, which should be fleshed out a bit at some point, but provides an introduction:

<script type="text/javascript" src="http://www.netbeans.tv/js/swfobject.js"></script> <script type="text/javascript"> </script>

Read more about it, with related links, here on NetBeans.tv.

In other news. The sound quality of the screencast above is much better than previously. Why? Because I found the "Remove Noise" button in Camtasia. Seriously, is that something that I should have to explicitly invoke? Why would I want to KEEP the noise?!

Tuesday Oct 28, 2008

Understanding the NetBeans Platform in Two Pictures

The pics below sum up everything you need to know to conceptually understand the NetBeans Platform, an application framework for large distributed Swing applications:

The above is Toni Epple, from Eppleton, an independent Java consulting and project out sourcing company in Munich, Germany, presenting the NetBeans Platform in Gdansk, Poland. Several other pics available here and also here, with probably more coming in the next few days, from the NetBeans Days that took place in Poland over the past weekend.

6 Minute Video: Groovy Makes Code Generation Simple

My screencast skills aren't perfect yet, but getting there. I've now learned how 'call outs' work. Some of the timing is still slightly off and the screencast ends quite abruptly. Aside from that, the basic point of the screencast comes across well enough. Have a look (6:22 mins):

<script type="text/javascript" src="http://www.netbeans.tv/js/swfobject.js"></script> <script type="text/javascript"> </script>

The text right at the end, which disappears as soon as you see it, says: "That's all folks. Have fun with Groovy! Clearly it makes code generation a piece of cake, not just for files, but even for complete source structures!"

Go here to download the screencast for off-line viewing.

The basic principles outlined above have several implications that I don't I go into in the screencast, but will do so next time. However, I'm sure there's more than enough in there to give anyone a couple of interesting ideas.

Sunday Oct 26, 2008

Poznan & Gdansk: NetBeans Day, Poland

I've spent the weekend with Karol Harezlak, Toni Epple, and Adam Bien in Poland—specifically in Poznan and Gdansk, because these two cities constituted the locations of NetBeans Day, Poland. It was a pretty excellent time. Both days had a very strong focus on the NetBeans Platform, which was pretty cool. The trip to these places was pretty long (Karol drove the whole way), with me being the GPS, together with Karol's iPhone. Parts of the time the whole map disappeared (thanks Steve Jobs) and I had to try and keep a green dot on a purple line without knowing anything about where we were (the green dot was the car and the purple line was the route from the office in Prague to the hotel in Poznan and then a day later from Poznan to a hotel in Gdansk). The drive from Poznan to Gdansk with Adam and Toni in the back seat was especially memorable.

The time spent at the two events was really good. Toni's presentation on 'Porting a Swing Application to the NetBeans Platform' was excellent—a good follow up to my 'Creating an Application on the NetBeans Platform'. Toni's real life experiences in this context are great—much better if someone 'out there' (i.e., unaffiliated to Sun) says nice things about the NetBeans Platform than when I do so. Then there was Adam Kędziora in Poznan who talked about the NetBeans Platform too, in the context of his Innovator Grant project. He even discussed the Lookup API in some detail, which was pretty cool. Adam Bien was excellent with all his EJB-oriented demos and his very interactive presentation style. Jacek Laskowski from the NetBeans Dream Team did a presentation on a more advanced level to Adam's (they'd decided that beforehand and, on some points, during Adam's presentation). It was the 1st time for me to meet Jacek, who was great. (Hope to meet again soon, maybe in Warszawa?) Also, Adam Dudczak did a great presentation on VisualVM, including—an introduction to its APIs, as well as a demo of a plugin he made for VisualVM using those APIs. In addition, there were several other presentations too, all in Polish (apart from Toni, Adam, and me), such as the ones by Karol on Java ME development. As a sidenote, I started remembering more and more of my Polish (from several years ago when I studied it for no reason).

Ubuntu completely failed me both days and fortunately I had my presentation on a USB stick, so was able to deliver it on Karol's Mac. Unfortunately I couldn't do some of my demos though and I wasn't overly familiar with the Mac, which didn't make everything as smooth as it should have been. Honestly, despite everything else, I'm very close to giving up on Ubuntu completely. Aside from the continuing projector cable problems, it also refused to start up at some point, with very odd and scary messages. Then it suddenly started working again. Very erratic behavior. I suspect that there's a script that detects whether a projector cable is plugged in and, if "yes", a massive internal error is intentionally thrown just to give you stress for no reason. That's the only logical explanation I can think of.

There's one very interesting thing (even, dare I say it, revolutionary) I worked on in the breaks in between the sessions, something that I'll be creating a screencast about as soon as we find our way back to Prague (long way from Gdansk to Prague and the road will be purple and the dot will be green). Clue about that screencast—it's about Groovy and it's also about the NetBeans Platform. Watch this space for the details.

Finally, thanks to everyone who we met along the way, especially Adam and Kasia (what a great way to start our time in Poland that was) in Poznan and Kuba in Gdansk, as well as, of course, all the speakers, and Toni and Adam for flying to join us from Munich. I'm looking forward to the many photos and movies that were made and taken the last few days! Watch this space for those too.

Thursday Oct 23, 2008

2 Minute Video: Groovy Makes Java Better

The first of several screencasts I am planning in relation to Groovy:

<script type="text/javascript" src="http://www.netbeans.tv/js/swfobject.js"></script> <script type="text/javascript"> </script>

PS: When I said "on our dialog", I should have said "on our Groovy class".

Wednesday Oct 22, 2008

NetBeans Platform Training Taking Off

A cool blog entry I found today by John, head of the Docs team:

Tuesday Oct 21, 2008

"Developing Rich Client Applications Using Swing"

A new and interesting article at "AjaxWorld Magazine". Click the image below to jump straight to the article:

I'm hoping the article will continue by describing and comparing the various Swing application frameworks available—Spring RCP, JSR 296, NetBeans Platform, Griffon, as well as the docking frameworks, like MyDoggy and others. I would be very interested to see the author's take on all those.

Sunday Oct 19, 2008

NetBeans Platform APIs: Top 10 Runners Up

If yesterday's list of NetBeans APIs are to be seen as the NetBeans Platform's "Top 10 Greatest Hits" (the 10th place is still open to suggestions), then those that follow are its "Top 10 Runners Up". In other words, though the following don't belong to the central set of NetBeans APIs, they are important nonetheless and, in each case, are APIs that you need to have in your mental toolbox next time you start thinking about the infrastructure of your Swing application:

  1. Dialogs API. Enables you to provide user notifications, dialogs, and wizards that integrate well with the rest of the NetBeans Platform. In the NetBeans sources, see package "org.openide".

  2. Options Dialog and SPI. Enables you to integrate with the NetBeans Platform's Options window so that you can let the user customize the application. In the NetBeans sources, see package "org.netbeans.api.options/org.netbeans.spi.options".

  3. UI Utilities API. Enables you to provide a range of smaller visual items in your NetBeans Platform application—particular favorites are HTML browser integration, the Undo/Redo Manager, and status bar interaction. (Also have a look at the DropDownButtonFactory and TabbedPaneFactory, both of which I blogged about some time ago.) In the NetBeans sources, see package "org.openide.awt".

  4. MultiView Windows. Enables you create two views over the same file, typically a source view and a visual design view. In the NetBeans sources, see package "org.netbeans.core.api.multiview/org.netbeans.core.spi.multiview".

  5. Auto Update Services. Enables you to programmatically install/uninstall and enable/disable modules. In the NetBeans sources, see package "org.netbeans.api.autoupdate/org.netbeans.spi.autoupdate".

  6. I/O APIs. Enables you to write to the NetBeans Platform's Output window, including writing hyperlinks there, such as error messages which the user can then click on to jump to a relevant place in the source code or, possibly, somewhere on-line. In the NetBeans sources, see package "org.openide.windows".

  7. Progress API. Enables you to integrate with the NetBeans Platform's progress bar, to indicate to the user that they need to wait a bit longer during long running tasks. In the NetBeans sources, see package "org.netbeans.api.progress".

  8. Command Line Parsing API. Enables you to parse the command line from within a NetBeans Platform application. In the NetBeans sources, see package "org.netbeans.api.sendopts/org.netbeans.spi.sendopts".

The final two runners up (below, 9 and 10) are not actually APIs. They are, like the above, of course, provided in the form of a NetBeans module. However, in these cases, you can't program against these modules. I.e., for example, you need to do a bit of Java coding to work with the Command Line Parsing API. These two, however, require no coding. Simply include them in your NetBeans Platform application and you've immediately integrated them:

  1. Favorites. Provides the Favorites window, which functions as a file browser. You can brand it quite easily, replacing the strings with your own.

  2. JavaHelp Integration. Provides the infrastructure for JavaHelp help sets.

That's it. I believe that the above 10, and the previous 10, together make up the top 20 modules that the NetBeans Platform makes available. The remainder are mostly support modules for the above or low-level infrastructural modules that could be addressed in a future blog entry.

You might be wondering: "Where are all the editor-related APIs?" Well, those APIs are not part of the NetBeans Platform. They are made available by NetBeans IDE, which is just one of many applications on top of the NetBeans Platform. Those can also be looked at in a future blog entry, but have nothing to do with the modules that the NetBeans Platform makes available. From these two lists, therefore, you should be able to see that the NetBeans Platform isn't concerned with editor applications, necessarily. It provides the basis for any kind of Swing application (small or large) that needs the above services.

NetBeans Platform APIs: Top 10 Greatest Hits

In the first place, the NetBeans Platform is a runtime container for desktop applications, comparable to an application server for web applications. Both handle common concerns, such as lifecycle management, for their target application type. However, secondly, the NetBeans Platform is a set of libraries.

In my (humble) opinion, these are the top 10 libraries offered by the NetBeans Platform APIs:

  1. Module System API. Enables the modular structure of NetBeans Platform applications. In the NetBeans sources, see package "org.openide.modules". Start reading about it here.

  2. Window System API. Enables you to create an application with advanced logical window functionality, such as drag/drop, dock/undock, maximize/minimize. In the NetBeans sources, package "org.openide.windows". Start reading about it here.

  3. Lookup API. Enables communication between modules similarly to the ServiceLoader class in JDK 6, as well as the context sensitivity of windows, nodes, and data objects in the application. This API can also be used outside the NetBeans Platform. In the NetBeans sources, package "org.openide.util.lookup". Start reading about it here.

  4. File System API. Enables the modules in an application to communicate by means of a virtual file system which is, by default, a hierarchical structure of folders and files defined in XML documents. In the NetBeans sources, package "org.openide.filesystems". Start reading about it here.

  5. Nodes API. Enables you to provide visual representations of underlying objects, i.e., these are NetBeans Platform JavaBeans. This API can also be used outside the NetBeans Platform. In the NetBeans sources, package "org.openide.nodes". Start reading about it here.

  6. Explorer & Property Sheet API. Enables you to render nodes in one of several NetBeans Platform Swing components that are, via the NetBeans ExplorerManager, loosely coupled to the rendered nodes. This API can also be used outside the NetBeans Platform. In the NetBeans sources, package "org.openide.explorer". Start reading about it here.

  7. Datasystems API (also known as "Loaders API"). Enables custom file types to be represented in the application. If the application does not make use of custom file types, this API can be ignored. In the NetBeans sources, package "org.openide.loaders". Start reading about it here.

  8. Actions API. Enables you to include actions that can be hooked up to menu items and toolbar buttons in your application, where you can define them as being always available or context sensitively enabled. In the NetBeans sources, package "org.openide.actions", with the related package "org.openide.util.actions". Start reading about it here.

  9. Visual Library API. Enables you to add widgets to your application, with common functionality, such as 'zoom' and 'move' provided out of the box. This API can also be used outside the NetBeans Platform. In the NetBeans sources, package "org.netbeans.api.visual". Start reading about it here.

  10. What do you think..?

I doubt that there'll be much argument about the top 9 listed above (apart from, possibly, the Datasystems API, which those who don't use custom file types are probably not using; and potentially someone will argue that the whole 'runtime container' should be included in the first item, rather than just the Module System API). But... what should no. 10 be? Options? I/O? Common Palette? Something else? Suggestions (with justifications!) welcome.

Saturday Oct 18, 2008

"But... Don't All NetBeans Platform Applications End Up Looking Like NetBeans IDE?"

I had an interesting discussion recently which started when someone's central reservation to using the NetBeans Platform turned on their assumption that the end product would "look a lot like NetBeans IDE".

That is not a very surprising assumption. It is logical to assume that you should consider building your Swing application on the NetBeans Platform if you're thinking about creating "some kind of editor". But it shows a misunderstanding of what the NetBeans Platform is. The NetBeans Platform is not bits and pieces removed from NetBeans IDE. Quite the opposite, in fact: NetBeans IDE is bits and pieces placed on top of the NetBeans Platform! I.e., the relationship is the other way round: the NetBeans Platform is the dominant partner, while the NetBeans IDE is just one way (of many) in which the NetBeans Platform can be used.

However, of course, when it comes to talking about how something "looks", one shouldn't be using words. One should be using pictures. So here are three applications on top of the NetBeans Platform:

None of them look like any kind of IDE. Say about them whatever you like, but you can't say: "Wow, those look a lot like NetBeans IDE". The only thing the above have in common with NetBeans IDE is their infrastructure, not "the way they look". Many more screenshots (and more are being added all the time) can be found here.

Friday Oct 17, 2008

NetBeans Platform Certified Training Mentioned on java.net

Thursday Oct 16, 2008

How Users Can Let Children Move Up & Move Down (Part 2)

In How Users Can Let Children Move Up & Move Down (Part 1), the children class extended Index.ArrayChildren. That was extremely convenient, because (in order for the 'Move Up' and 'Move Down' menu items to be enabled), an implementation of the Index class MUST be included in the root node's Lookup. Since an implementation of Index.ArrayChildren meets this requirement, things look good so long as you're using that class. However, what if you're extending Children.Keys instead? That's the vexing question posed in this blog entry.

In the case where you're not extending Index.ArrayChildren, you have a problem. In this case, you need to create a new class that extends Index.Support, with content like this:

import javax.swing.JOptionPane;
import org.openide.nodes.Index;
import org.openide.nodes.Node;

public class IndexSupportImpl extends Index.Support {

    private PropChildren prop;

    public IndexSupportImpl(PropChildren prop) {
        this.prop = prop;
    }

    @Override
    public Node[] getNodes() {
        return prop.getNodes();
    }

    @Override
    public int getNodesCount() {
        return prop.getNodesCount();
    }

    @Override
    public void reorder(final int[] perm) {
        JOptionPane.showMessageDialog(null, "reorder here!");
    }
    
}

The "only" problem is that I haven't been able to figure out how to implement the 'reorder' method above. I've seen all the related sources but haven't been able to figure it out. Anyway, now you need to add the above implementation of Index to the root node's Lookup:

PropChildren prop = new PropChildren();
explorerManager.setRootContext(new AbstractNode(prop, Lookups.singleton(new IndexSupportImpl(prop))));

And, finally, your children object needs to implement Index and then delegate to the above Index.Support class. At least, then the menu items will be enabled, even though the 'reorder' will need to be figured out per implementation.

Wednesday Oct 15, 2008

NetBeans Podcast Episode 47 (Part 2)

Lloyd and I very conscientiously send prizes to those who win the 'NetBeans Puzzler of the Podcast'. We tend to ask, sometime afterwards, for a pic of the happy winner together with their prize.

Below you see one of our recent winners, Lukáš Vlček, with his prize and his daughter:

Below is the text he sent with the picture:

You can see that the book is now the natural course of events in our family. My daughter cannot wait to get her hands dirty with the code while I read the book and naturally she cannot fall asleep without me reading her at least one chapter covering an advanced NetBeans API topic. If I were to describe this book then I would borrow words from Albert Einstein: "If you want your children to be intelligent, read them fairy tales. If you want them to be more intelligent, read them more fairy tales." Yes, this book is unbelievable!

Finally, if you ever won the NetBeans Puzzler of the Podcast and did not receive your prize (Robert Appleby in Australia is potentially someone falling in this category), please DO write and let us know! We really don't want disgruntled winners spread around the world as a result of our forgetfulness, incompetence, or otherwise. So write to nbpodcast@netbeans.org if you won a prize without actually receiving it.

Tuesday Oct 14, 2008

NetBeans Podcast Episode 47 (Part 1)

Another podcast filled with info, insights, and innuendo!

Here's the agenda (34.17 mins):

  • 1.00: News. Tinu Awopetu, Managing Editor of NetBeans.org, talks about the NetBeans Calendar (next stop of NetBeans Day is Seoul, South Korea, October 17th, i.e., this Friday!), the 10th birthday of the NetBeans project, and... the NetBeans Decathlon!
  • 3.40: Interview. David Strupl, technical lead of JavaFX support in NetBeans IDE, is interviewed by Lloyd. Find out all about David, his technical background, and what's going on with JavaFX tooling in the IDE. Also find out about JavaFX itself, as well as JavaFX script. How does JavaFX script compare to other scripting languages? And what will the NetBeans tools for JavaFX actually consist of? What makes working on this project interesting? David tells all and asks for user feedback!
  • 15.30: API Design Tip. Are APIs like stars or are they like diamonds? Jaroslav Tulach hooks into a discussion connected to Josh Bloch (here in the comments) about whether APIs are 'stars' or 'diamonds'. What's the difference between these two metaphors and what does the difference say about APIs? (In the process of the discussion, Geertjan shows he's not very smart.)
  • 22:40: NetBeans Innovator Grant Contest. Jirka Kovalsky talks about the NetBeans Innovator Grant Contest. He talks about how shocked he was at the amount of submissions and, then, how impressed he was with their quality. He thanks the NetBeans Dream team for selecting the best 20 proposals and for defining the process/rules as well.
  • 28.30: Project of the Podcast. For the first time, we talk to a NetBeans user on the NetBeans Podcast. Brian Segale, who manages the Solutions Team at DeviceAnywhere, talks about the NetBeans modules they developed for their mobile solutions.
  • 33.00: Puzzler. We announce the previous winner and introduce the next puzzler! Deadline: Friday, October 31, all submissions to nbpodcast@netbeans.org. And, if you write with ideas for future podcasts, and your idea ends up being used, we'll send you a NetBeans t-shirt in gratitude!

Click here to hear it all:

<script type="text/javascript" src="http://www.netbeans.tv/js/swfobject.js"></script> <script type="text/javascript"> </script>

Alternative source: http://feeds.feedburner.com/NetBeansPodcast

Many thanks to Lloyd for stringing everything together!

Monday Oct 13, 2008

World's Simplest NetBeans Node Implementation

While looking into some small corners of the Nodes API, I realized that this is probably the simplest Nodes implementation. It is perfect for demos and presentations and trainings, etc. Anyone can code this and it is easy to explain what's going on:
class SystemPropertyNode extends Children.Keys {

    @Override
    protected void addNotify() {
        Properties props = System.getProperties();
        setKeys(props.stringPropertyNames());
    }

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

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

}

Once you've got that, you need this in your view component (which could be a TopComponent or a JFrame):

ExplorerManager.setRootContext(new AbstractNode(new SystemPropertyNode()));

In addition, you'd need to implement ExplorerManager.Provider and add an explorer view. But most of that part can be done via the ui in the IDE. Short, simple, nice demo of Nodes API, ending with you swapping different explorer views around to show that the model is disconnected from the view.

How Users Can Let Children Move Up & Move Down (Part 1)

"Move up" and "Move down" support for nodes is provided by the NetBeans Platform, as described in this "NetBeans Definitive Guide" page on-line. I tried to get it to work for some of my child nodes today and managed to get it working, with Jarda's help. The menu items are enabled, if I select one child node at a time, and they work as one would expect them to:

Let's say I define my children like this:

public class PropChildren extends Index.ArrayChildren {

    @Override
    protected java.util.List initCollection() {
        ArrayList childrenNodes = new ArrayList();
        Properties p = System.getProperties();
        Enumeration e = p.keys();
        while (e.hasMoreElements()) {
            childrenNodes.add(new PropNode(e.nextElement().toString()));
        }
        return childrenNodes;
    }

    public class PropNode extends AbstractNode {

        public PropNode(String key) {
            super(Children.LEAF, Lookups.fixed());
            setDisplayName(key);
        }

        //You need to add the 'MoveUpAction' and 'MoveDownAction',
        //which are part of the Actions API:
        @Override
        public Action[] getActions(boolean popup) {
            return new Action[]{
                        SystemAction.get(MoveUpAction.class),
                        SystemAction.get(MoveDownAction.class)
                    };
        }
    }
    
}

For the above, you need the following in the TopComponent's constructor (of course, the TopComponent implements ExplorerManager.Provider and has an explorer view added to it):

//Create an instance of the children class:
PropChildren prop = new PropChildren();

//Add the map of actions to the TopComponent's Lookup:
associateLookup(ExplorerUtils.createLookup(explorerManager, getActionMap()));

//Create the children and
//include an implementation of the Index class in the Lookup of the root node.
//Since our children class above is such an implementation, we'll include that:
explorerManager.setRootContext(new AbstractNode(prop, Lookups.singleton(prop)));

//Set the display name of the root node:
explorerManager.getRootContext().setDisplayName("Properties");

The key to the above is that I have extended Index.ArrayChildren, which provides me with reorderable children out of the box (but only if I include the class in the Lookup of the root node, as shown above). If you're using Children.Keys or ChildFactory, the children class could implement Index. Or you could create a new class that extends Index.Support, which should then be added to the Lookup as shown above. But then you would have to handle the reordering yourself, unlike with Index.ArrayChildren which, as can be seen above, gives you that functionality for free.

Friday Oct 10, 2008

Flickr Photos of Recent NetBeans Platform Training

Toni's photos, taken last week at the NetBeans Platform Certified Training in Wuerzburg. The training was delivered by Pavel Kotlov, David Strupl, Toni Epple, and myself.

This course is offered for free to universities (and colleges and similar institutions), but only if the course is embedded within the existing curriculum of the class. (I.e, it should be taken seriously by everyone involved.) The course fits very well within an advanced Swing curriculum or within a curriculum that focuses on architectural concerns for large and distributed Java applications. It is probably less appropriate for a class of complete newbies to Java. We have a number of trainers available around the world, in particular in the US, Europe, and Australia. A good report on the whole experience is here in Toni's blog, where he writes about his 1st experience being a trainer on this course.

Using the Layer to Set Customer-Specific Properties

Let's say you have one base application for all your customers. However, each customer has some user-specific settings that need to be distributed and installed in some way. Previously, i.e., in your pre NetBeans Platform days, you might have distributed an INI file (or some other config file) which was somehow read into the application to include the customizations.

But now you're working with the NetBeans Platform. Is there specific support for this scenario or should you go on using your INI approach? Here's where the System FileSystem comes in handy. Let's say we have two clients, called 'Red Station' and 'Blue Station'. For each of these, create a new NetBeans module. Don't add any code at all. Simply populate the layer.xml file of the 'Red Station' module with this content (or whatever content your original INI file used to have):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" 
"http://www.netbeans.org/dtds/filesystem-1_1.dtd">

<filesystem>

    <folder name="station">
        <attr name="name" stringvalue="Red Station"/>
        <attr name="welcomeText" stringvalue="Welcome to the Red Station!"/>
        <attr name="isHelpMenuIncluded" boolvalue="false"/>
        <attr name="isToolbarsIncluded" boolvalue="true"/>
    </folder>
   
</filesystem>

Then, in the 'Blue Station' module, populate the layer.xml file with this content:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" 
"http://www.netbeans.org/dtds/filesystem-1_1.dtd">

<filesystem>
    
    <folder name="station">
        <attr name="name" stringvalue="Blue Station"/>
        <attr name="welcomeText" stringvalue="Welcome to the Blue Station!"/>
        <attr name="isHelpMenuIncluded" boolvalue="true"/>
        <attr name="isToolbarsIncluded" boolvalue="false"/>
    </folder>
    
</filesystem>

As you can see, we have set various properties—the name of the station, some welcome text, whether the Help menu should be displayed, and whether the toolbars should be displayed. You can set any attribute you like, i.e., those attributes could be anything at all, whatever you need, such as 'isSantaClausReal' or whatever. By the way, notice those attribute types, i.e., 'stringvalue' and 'boolvalue'. Those are fixed, i.e., there is a specific subset of types that can be used. How did I know what was available? First, I used code completion:

Secondly, look at the DTD, which is available on-line.

OK. So, now we've set our properties. They could be a whole range of different things. Then we distribute them to our users. Users at the 'Red Station' would get that particular module, while users at the 'Blue Station' would get the other one. Even though neither module contains any code at all, once the respective users install them, they'd get very different results (look at the title bar, tab text, text area, toolbars, and Help menu in the screenshots below):

How is that possible? In the base application (i.e., the application that all the users have), I have a TopComponent with all of this content in the constructor (though the code could be anywhere else too, but since it mostly relates to the TopComponent, I put all the code there):

private BaseTopComponent() {

    try {

        initComponents();

        //Get the root of the user directory:
        FileObject root = Repository.getDefault().getDefaultFileSystem().getRoot();

        //Get the station element:
        FileObject station = root.getFileObject("station");

        //Get the 'name' string attribute for the station:
        final String name = station.getAttribute("name").toString();

        //Get the 'welcome text' string attribute for the station:
        String welcomeText = station.getAttribute("welcomeText").toString();

        //Get the 'isHelpIncluded' boolean attribute for the station:
        final Boolean isHelpMenuIncluded = (Boolean) station.getAttribute("isHelpMenuIncluded");

        //Get the 'isToolbarsIncluded' boolean attribute for the station:
        final Boolean isToolbarsIncluded = (Boolean) station.getAttribute("isToolbarsIncluded");

        //Dynamically set the main window's title based on the 'name' above:
        WindowManager.getDefault().invokeWhenUIReady(new Runnable() {
            public void run() {
                WindowManager.getDefault().getMainWindow().setTitle(name);
            }
        });

        //Also set the tab of the TopComponent to the 'name' value:
        setName(name);

        //Set the text area's content, using the 'welcome text' above:
        welcomeTextArea.setText(welcomeText.toString());

        //Hide the Help menu, using the boolean above:
        if (!isHelpMenuIncluded) {
            FileObject helpMenu = root.getFileObject("Menu/Help");
            if (helpMenu != null) {
                helpMenu.delete();
            }
        }

        //Hide the toolbars, using the boolean above:
        if (!isToolbarsIncluded) {
            FileObject toolbars = root.getFileObject("Toolbars");
            if (toolbars != null) {
                toolbars.delete();
            }
        }

    } catch (IOException ex) {
        Exceptions.printStackTrace(ex);
    }

}

This solution means that you need to be using the File System API, which provides the very powerful org.openide.filesystems.FileObject class that you see in action above. In effect, this API lets you very easily parse the layer.xml file, finding its elements and attributes and then converting them to strings, booleans, and so on. Another approach would be to use the NbPreferences class. However, in that case you'd be using properties files. That's less powerful than an XML file, because you simply have key/value pairs, instead of the hierarchical folder/file and element/attribute structure that the layer.xml file implies. I will blog about this second approach soon, at which point the disadvantages will become very clear, especially when compared to the above.

Thursday Oct 09, 2008

Two NetBeans Platform Trainings and a JUG Event

I spent the last week traveling around Germany. First there was a customer training (a customized version of the NetBeans Platform Certified Training) in Immenstadt, which is pretty much on the border with Austria and Switzerland. I spent two days there with Petr Suchomel, a NetBeans engineering manager, giving a two day NetBeans Platform course to 5 engineers. It was an interesting time (and most of my recent blog entries are based on remaining questions that were unanswered, more of those coming in the coming weeks). I also met with Sven Reimers, who works at the same company, and has many years of experience with the NetBeans Platform. He demoed the extremely advanced NetBeans Platform application that they're using there (and I'm hoping to be able to show screenshots of it here soon!). By the way, Sven is also a Dream Team member and he runs the Software Quality Environment (SQE) project.

Here's Sven and me together with a sign I found lying on his desk:

The sign says: "Will code generator for food. Even debug apisupport."

After that I had a few days to relax. Then, this week Monday and Tuesday, I was in Wuerzburg with David Strupl (technical lead of NetBeans JavaFX support, listen to a very recent interview with him here) and Toni Epple (who is also from the Dream Team) to give a training to an IT class at Julius-Maximilians-Universität Würzburg. Those two days were extremely busy but fun. We ran out of time in a few sessions, we just had too many things to talk about. Aside from the time management issues we need to solve, the course went well. Would be great to go back some time, especially to talk in greater detail about Lookup and to spend a lot of time on the Visual Library, for which there ended up not being time. But the main concepts of the NetBeans Platform (Window System, Nodes, Explorer Views, Lookup, File System, Data Objects, Editors) were basically covered. Discussions with the students afterwards showed that they had really got the point very well. Their assignment for the course involves creating modules and the proposals I've seen so far look very cool, even useful directly for NetBeans IDE. Our entire training was videod and Pavel Kotlov, a great NetBeans Platform user who is the course instructor, is thinking about making the result (once it is edited and so on) available on parleys.com. Toni took a few pictures at the end of the course, also a group pic, which I'm hoping to be able to publish here soon too.

Then, finally, last night, I was at the Saxony Java User Group (JUG) in Dresden (on the way back from Wuerzburg and about 2 hours by train from Prague, where I live), where I talked about the NetBeans Platform. I was prefaced by a presentation on the Eclipse RCP and JSR-296, as can be seen here. (Click here for my presentation slides, in PDF format, called "Hello NetBeans Platform!")

It was a very good event, even though my NVidia card completely died (resulting in horrible screen resolutions accompanied by an unlikely array of wavy lines and flashy blocks, comparable to those flatlining heartbeat charts in a hospital) as soon as I plugged in the projector cable. Only once I got back to work (this afternoon) was I able to fix everything. The speaker on JSR-296 also had problems with Ubuntu and the projector; David Strupl did too, on our training in Wuerzburg. Sometimes (as in Immenstadt) there were no problems in this regard at all, other times it's a nightmare. The one moment where you want no mess ups is when you're setting up for a presentation (with a slowly growing crowd of observers gradually gathering as the time for the presentation start approaches). Fortunately Saxony JUG leader (and Dream Team member) Kristian Rink's laptop (also Ubuntu) was ok and so the two of us did our presentations on his laptop. The Eclipse presenter, on the other hand, walked in with his Mac, plugged it in and, while we were still sweating over our Ubuntus, sat back and relaxed without a problem.

But, all in all, it was a really cool week. I learned a lot of new things about NetBeans IDE and the NetBeans Platform and enriched my understanding of the ways in which users in the field interact with these tools and technologies. Here's hoping I'll get the chance to get involved in more things like this! Thanks to everyone we met in Germany—especially the informal times spent with Toni, Pavel, Sven, and Kristian were very cool.

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
« October 2008 »
SunMonTueWedThuFriSat
   
2
7
8
11
12
20
24
25
27
31
 
       
Today