Wednesday, August 23, 2006

NetBeans Platform: StatusLineElementProvider order and Progress bar

Using the nice META-INF/service, one can declare it's own little status-bar piece by implementing StatusLineElementProvider . You basically just return your Component that will be placed on that IDE/Platform status bar.

What the javadoc for StatusLineElementProvider doesn't say is how does one define the order for the components in the status bar.

Well, since we are using the services, then Lookup has something to do with this. Indeed, the documentation states this and also mentiones two other Lookup features (aka extensions): you can remove service implementations and you can define the order they are returned. Of course, this order is used for StatusLineElementProvider too !

So, just edit the org.openide.awt.StatusLineElementProvider file and add after the implementation class name something like #position=10 to define a position for your implementation.

At Platform startup these will be instantiated starting with the smallest position and going up.

Another thing: the Progress API line element has position number -13. So, if you use -14, -15 for 2 fake items, you get something like this:

If you use bigger numbers you get something like this:

And, I could also get rid of the progress bar altogether with



If this was helpful for you then maybe you'll like reading the other NetBeans Platform-related posts.

Emilian Bold
Java-loving consulting services from Timisoara, Romania.

NetBeans Platform: Showing Progress to the user

The Progress API is a new (I've noticed it in the 5.0 release) and usefull little API. It has a rather simple task: display to the user the Progress of long tasks.

Usually it makes sense to use it if you have a task that may run in the background. If you need to block the whole IDE I guess you need to do it in a modal dialog-way.

But most of the long tasks may safely run in the background. With Progress API you just declare your new task and then in the lower-right part of the main window you'll see a progress bar.

Usually you have two kinds of tasks: tasks execute a predetermined number of steps and you could estimate something like a percentage realised so far and tasks that could go on for ever.

The fun part about the Progress API is not only that it allows you to have *determinate* and *indeterminate* kind of progress handles (this is how your little presenter is called) but it also allows you to switch between determinate and indeterminate tasks.

Imagine this: you take a locally-saved HTML file and need to re-save it with links up to a depth. For all local links you pretty much know it's going to take little time to copy the file so you have a determined progress (with a percentage shown) but once you start downloading something from the net you have no ideea how much it will take. So you switch to indeterminate and the user sees just an indefinite progress bar.

Even better, you could have more than one task running at one point. So if you click on the progress bar for the current task, a popup will appear with all the tasks.

Did I mention tasks could be canceled ? Yeap, you could declare that too and a small "close" button will appear next to the progress bar. Really handly.

Now, if you need this for standalone non-Platform based apps, you might find usefull. There is one app where I used it and it works great !

On holiday during the 24 august - 31 september period.

Emilian Bold

Java and NetBeans Platform-loving consulting services from Timisoara, Romania.

Tuesday, August 22, 2006

NetBeans Platform: Options Dialog isValid() or implement thy TODOs

The Options Dialog API allows an invalid state for the panels.This is normal, it could happen that user changes lead to an invalid state and you don't want to set some magic default. So, you force the user to make all the changes until the panel is in a valid state.

For example: I have an user that may be a minor. If he's a minor, the parent's name must be set. I have 3 situations:

  • he's an adult. Panel state is valid. Ok and cancel button are active, no warning. All is good.
  • he's an minor with an empty parent name. You get the red text warning (which is just Swing from my JPanel, no Platform stuff here) and the OK button is disabled. Noticed that ? This is where the isValid() does its work.
  • he is a minor with a non-empty parent name. The OK button is enabled (isValid contribution) and no more red warnings (pure Swing code): Fun stuff no ?

The way this is doable is: just look at the TODOs.

  1. Implement the load() and store() methods in the generated Panel to have persistence.
  2. Implement the valid() method in the Panel. In my case is something as simple as
     return adult || (!adult && parentName.getText().trim().length()>0);

  3. Then implement the final TODO from the constructor: listen to changes in form fields and call controller.changed() In my case I just call controller.changed() when the radio buttons are pressed and also in a DocumentListener for the text (to detect if the parent name changes and provide instant feedback).

And that was all it was needed. Now I have a simple, interractive with possible invalid states option panel.

If this was helpful for you then maybe you'll like reading the other NetBeans Platform-related posts.

Emilian Bold
Java-loving consulting services from Timisoara, Romania.

Monday, August 21, 2006

NetBeans Platform: Branding the help with layer kung-fu

Since I said that I have to make a proper application and I was too lazy to actually write any complicated code in the weekend I said: ok, let's add the Help. If you're new to NetBeans Platform, this means basically that there is a Wizard to generate a whole bunch of files and configuration: the Java Help-related files and the files to have the integration with the Help system of the Platform.

Since NetBeans 5.5 this Help Wizard has been a real life saver. The was too much wodoo going on there to actually get it done by hand. It was doable just no something you do when you want to feel relaxed.

The deal about the Help System it's that, of course, is designed to take into account the situation where you have multiple modules with their own helpset. But when you develop a standalone platform application you only have one helpset and you get this ugly picture first:
As you see there is an annoying first page.

The nice thing about the NetBeans Platform and IDE is that the sources are available so you can always grep the hell out of them and find what you need. For example, it seems that this page is in core/javahelp (unsurprisingly) and that it's named masterHelpPage, referenced from the masterHelpMap.jhm with MASTER_ID . MASTER_ID pops up in master-help.xml (based on helpcontext-1_0.dtd) which has an option showmaster = true / false. So this must be the guilty thing.

Ok, there it is, but how does one change it ?

Indeed, found the (possible) culprit. So I have to change the showmaster somehow. Since I've always felt that Java Help is unnecessary complex, I first assume I have to patch the build system and modify the damn file. Nasty but doable.

But this looks like some sort of per-application customization, known as branding on the NetBeans Platform. Branding is the same process that lets you change the application splash screen, icon, title, Bundles for localization and more.

And branding usually involves work with the Bundles, the layer.xml file and new resources (icons, etc).

Since I can't possibly imagine how one could brand, I find on the net Geertjan's blog topic on the subject. The solution is unbelivebly short:

<folder name="Menu">
<folder name="Help">
<file name="master-help.xml_hidden"/>
<file name="your-master.xml" url="master.xml">

Read Geertjan's post for more details.

Layer kung-fu

The ideea is simple: all layers on the Platform are placed on a stack with your module's layer on top. So basically you can't only add or hide (with _hidden) new files, but you can also replace them.

Of course ! This is how branding gets done.

So in the XML above you see the existing master-help.xml file is hidden and then replaced by our own (where we set our own MASTER_ID). It's so simple I can't believe it.

I always though the layer ideea was a little over-engineered but now I'm a believer.

Layers: I know kung-fu!
Developer: Show me !

If this was helpful for you then maybe you'll like reading the other NetBeans Platform-related posts.

Emilian Bold
Java-loving consulting services from Timisoara, Romania.

Saturday, August 19, 2006

NetBeans Platform: Who needs the Web Browser ?

During my lobby period for the NetBeans Platform at my workplace I did
with a coleague a quick port to the NetBeans Platform of a Swing application.
Of course, nothing too Platform-dependent, just module with
TopComponents instead of JFrames, library wrappers, etc.

Now, one of the complaints was: "hell, in another tab I had a *web browser* !"

Tonight I was looking at the new NetBeans 6.0 M2 Platform and it hit
me: the View->Web Browser is there ! It's there in 5.5 too.

Now, why would my standalone application need it ? It's not like
people use some other "internal" broser that each application has, so
why is it there? Or at least -- why the menu item ?

There was a comment in a blog at some point with something like "we
like Eclipse RPC because there we have to put things in, on the
NetBeans Platform we have to take things out first" which kinda made
sense (although I haven't used the Eclipse RCP, only the IDE).

I've dugg into the sources and it seems the Web Browser is used by the
*autoupdate* module. But even if I don't use the autoupdate module,
it's still there. Ok you'll say: "there is a trick! You never actually
remove autoupdate entirely", which is true. Autoupdate also has the
little update piece generated from libsrc/ that has low-level module
update/install code.

But the Web Browser usage in autoupdate isn't in the *libsrc/* part,
it's in the module, that you can disable.

Also, in Tools->Options->Advanced Options->System there is a Web
Browser option (with Swing Browser as the default). And that is needed
... why ?

Of course, one can always set a _hidden in tha layer for the folder or file and thus hide the Web Browser menu item or the whole View menu but this seems indeed a little odd. In the end -- what is the purpouse of the Web Browser that makes it so hard to remove altogether ?

If this was helpful for you then maybe you'll like reading the other NetBeans Platform-related posts.

Emilian Bold
Java-loving consulting services from Timisoara, Romania.

Friday, August 18, 2006

NetBeans Platform: Options Dialog and SPI

A nice thing in NetBeans Platform and IDE 5.0 is the nice Options dialog from the Tools menu. I've developed platform modules on NetBeans Platform 3.6 and skipped the whole 4 release so I'm not sure if it was introduced in release 4 or 5.

Anyhow, it's a nicer way to present options to the user than the usual tree display (now in Advanced Options). Also note that the Properties Window is also getting somehow deprecated and not recommended (unless in 3.6 where everyone was drooling to use it).

The NetBeans IDE Wizard for a new Options Panel is great. It generates the Bundle, the OptionsCategory , the OptionsPanelController , the swing JPanel, copies the icon and modifies your layer.xml .

An Option panel may reside in it's own "tab" or in the Misc area. This means that your class (subclassing AdvancedOption or OptionsCategory ) is registerd in the layer in

<folder name='OptionsDialog'>
<!-- here for OptionsCategory file/class -->
<folder name='Advanced'>
<!-- here for the AdvancedOption file/class-->

Basically the AdvancedOption and the OptionsCategory represent the name and icon of your Option panel and also the factory for your Controller.

The controller takes care of stuff such as saving your options and loading them, offer listeners and provide data outside such as "does this panel need to be saved ?" Easy short methods that are generated for free by the Wizard.

The controller is the one that provides the Swing JComponent for your panel. Of course that people usually have a JPanel (as the wizard generates).

Now, a nice thing about this API is that it even takes into account the situation when the settings are invalid. For example the user changed the Country but forgot to update the phone number or something. Because usually it's easy to provide a GUI warning (like a little red icon) but the API must also help.

Basically only the load() and store() methods from the JPanel must be filled after you generate the GUI interface with the form editor. I think the SystemOption -s are going to be deprecated or rewritten soon so I use the standard java Preferences.

Of course, if your panel may also be in an invalid state, the valid() method must also be implemented. Take a look at a simple valid/invalid Panel:

Hiding the Misc Options tab

And if you have a standalone application and you want to have only our option in the dialog (withou the Misc option), it's easy. Just edit the layer.xml and

<folder name="OptionsDialog">
<file name="Advanced.instance_hidden"/>

If this was helpful for you then maybe you'll like reading the other NetBeans Platform-related posts.

Emilian Bold
Java-loving consulting services from Timisoara, Romania.

Thursday, August 17, 2006

NetBeans Platform: DataLoader, DataObject and DataNode

The Loaders API is one of those things in the NetBeans Platform you know it exists, kinda know what it does but never dare to use it since it seems either too complex or not necessary.
For my current project I said I'm going to use everything the Platform has to offer and try not to re-invent anything so I had to use the dreaded Loaders.

The ideea behind the Loaders is quite simple: the IDE/Platform has to work with lots of file types (as in extension or MIME) and each DataLoader must take care of recognising it's file or files and represent it with a DataObject .

I say file or files because there is no one-on-one (1:1) relationship. The simplest example is the form editor that generates a single DataObject from the .java and .form files.

The wizard NetBeans 5.5 offers is more than enough to get anyone stared with the Loaders. Just ask for a File Type wizard, choose the file extension or MIME and quite fast you get everything autogenerated.

Basically each DataLoader is registered in the DataLoaderPool so each new file (as in FileObject) is queried against all the DataLoader-s to see if it is recognized or not. There also seems to be a mechanism to avoid creating a DataObject more than once - probably since it's considered expensive to parse / load the file.

Now, DataObject-s seem to be a lot more complex than meets the eye and I hope to post another message about these. There are ways to add listeners, cookies, move/delete methods, etc. Surely these methods are put to good use inside the IDE but I still haven't found a way to match and use there features yet.

The last thing related to the Loaders API is the DataNode . This is just a Node representation of the DataObject. The "view" part that I imagine as the GUI parse-tree.

What I fail to understand about the Loaders is the fact that some global actions like SaveAll seem to need a DataNode in the activatedNodes of a TopComponent which means that, although you could live and develop Platform applications without using DataLoader-s at all, it kind of forces you if you need SaveAll. This also means for me that basically you can't get a SaveAll action without first saving something to a FileObject. I was under the impression that SaveAll means "save all unsaved documents" not "save all unsaved documents already with an attached path".

If you've spotted any mistakes are you are able to clear some things in my Loaders mist, feel free to leave a message or contact me.

If this was helpful for you then maybe you'll like reading the other NetBeans Platform-related posts.

Emilian Bold
Java-loving consulting services from Timisoara, Romania.

Wednesday, August 16, 2006

MindMapping with the NetBeans Platform

I've started work on a free mind-mapping module for the NetBeans Platform (with Not planning anything fancy, just a well done NetBeans Platform-based application with help, autoupdate, etc.
I expect the feature list to be close to the features of FreeMind or other open-source tools.
What I do want is import from these other free formats in order to have a simple migration guide for the existing users.
I also planned some tutorials / podcasts as I come along but I think I'm overly optimist so I'll be happy if I just manage to finish the first version untill me self-declared deadline of 4th September 2006.

The Trouble with Harry time loop

I saw The Trouble with Harry (1955) a while back and it didn't have a big impression on me. But recently I rewatched it and was amazed a...