Friday, December 15, 2006

NetBeans Platform: Carefull with Matisse and FocusTraversalPolicy (aka Focus subsystem)

Matisse is a really nice GUI editor. But it doesn't seem to be quite up-to-date with the Java Focus Subsystem.

JComponent.setNextFocusableComponent() is deprecated since 1.4 ! And yet, this is all Matisse has to offer.

The right way to specify focus cycles since 1.4 is via FocusTraversalPolicy. You just set Container.setFocusCycleRoot(true) and then install your FocusTraversalPolicy subclass.

The problem is that setNextFocusableComponent has priority over the focus policy:

Overrides the default FocusTraversalPolicy for this JComponent's focus traversal cycle by unconditionally setting the specified Component as the next Component in the cycle, and this JComponent as the specified Component's previous Component in the cycle. (quote from Javadoc, emphasys mine).

So, if you try to define in Matisse some focus cycle the old fashion way (the only way possible right now) but then you want to use a FocusTraversalPolicy you have to go back and remove all the nextComponents otherwise it will break everything !

My advice: don't use nextFocusable on Matisse ! Do it by hand with FocusTraversalPolicy and wait for the 6.0 release when this should be fixed.

Thursday, December 14, 2006

NetBeans Platform: Watch out for the Platform security !

I always had the impression that the Platform is quite lax security-wise. Since you have in the Lookup the system ClassLoader it's not like they can restrict your module that much.

Well, I was a little mistaken. Apparently they do add some security checks.

And a particularly strange one is a security check on System.exit().

Actually, it makes sense to restrict calls to System.exit() but the way I've discovered it is surprising: I just moved a JFrame (made with Matisse) from the Java app to the platform. And by default, JFrames, have EXIT_ON_CLOSE set.

Well, on the Platform, the JFrame won't even show up ! Why ? Because of the EXIT_ON_CLOSE property. It eventually boils down to something like:

SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkExit(0);
}

which fails inside the platform with an org.netbeans.ExitSecurityException .

So the problem is that initComponents() throws this unchecked exception so the entire new Frame().setVisible(true) call fails. Even more: this doesn't show up in the logs!

Btw, System.exit() works just fine during ModuleInstall. It's LifecycleManager that breaks down at that (early) point.

Monday, December 11, 2006

NetBeans Platform: Node.Property custom editor

The property window is a nice quick way to let the user view and edit some values. It's not recommended as a valid approach (one should make its own windows) but it is quick. Just provide some activated nodes, open the Properties windows and all the declared PropertySets will be visible.

The nice part is that we already have a lot of predefined PropertyEditors for boolean/integer/string/font/color/date values.

But if one of the editors doesn't please us, just use Node.Property.getPropertyEditor() .

For example if we need a different date format, it would boil down to a new class:


class DatePropertyEditor extends PropertyEditorSupport{
private SimpleDateFormat sdf=new SimpleDateFormat("yyyy/mm/dd");

public String getAsText(){
if(getValue()==null){
return "";
}else{
return sdf.format((Date)getValue());
}
}
}


We just return a new instance of this class in getPropertyEditor() and that's it.

This gets a little more complicated if you actually need to edit the value as you have to provide a custom editor component but for simple read-only properties, this is all there is !

Wednesday, December 06, 2006

NetBeans Platform: 1st NetBeans Platform workshop in Timisoara. Make that in Romania

Today was the first NetBeans Platform workshop and presentation in Timisoara, held by your's truly. I'm also about certain it's the first in Romania too.

My ex-employer had this Java-workshop about various subjects (Struts, MVC, Hibernate, Design Patterns, Swing and NetBeans (Platform) ).

The presentation was quite nice. There were few people but with many questions (yeah, I'm looking at you Dan ! ).

I had a small OpenOffice presentation as the starting point and in the end I worked only in the NetBeans IDE, showing off:
I only remembered I had a camera at the end of all the discussions. I was too bussy answering questions ;)


I'll try and post another picture with the NetBeans powerpoint in the background later on today or tomorrow. Of you could just download the presentation together with the small application written on the spot.

UPDATE(11.dec.2006): New photos on Flickr.

Tuesday, December 05, 2006

NetBeans Platform: TopComponentGroup strangeness

Ok, I never used window groups as I wasn't that used to have that many interdependent windows.

It seems easier to add a "Palette" inside your JPanel and it surely is easier to handle than to make a separate window tha listens on the Lookup/activated nodes and reacts.

TopComponentGroup seems like the next logical step: if you already started using a whole bunch of windows that are interconnected somehow put them in the same group.

The teoretical advantage would be that
1. You get to easily open and close the whole group. You don't even have to know *who* is in the group. (Note the nice decoupling you get there).

2. The Group implementation remembers the closed/open state of contained TopComponents and restores them in the same way. This makes it consistent with the user.

Well, it's number 2 that annoys the hell out of me. For example: what if I *don't* want to remember the state ? What if I have 3 TopComponents that work together but they should *always* be in an open() state together ?

What do you do then ? Of course: do it manually. You lose the decoupling and have to keep hard references to your "buddy"-windows and .open() or .close() them by hand when needed.

Which means that by this point TopComponentGroup is useless and you might as well remove all the code/xmls. Grr.

Wednesday, November 22, 2006

NetBeans Platform: Lookup.Result garbage collection trick and active TopComponent lookup

In the old days, one could listen on changes in the "activated nodes" of the active TopComponent with a listener on TopComponent.Registry paying attention to the PROP_ACTIVATED_NODES property.

Now Lookup is a much nicer way to show activate "objects". The way to listen globally to
changes in the Lookup of the active TopComponent is via Utilities.actionsGlobalContext() (which is a Lookup itself).

The trick is simple, you add a LookupListener on the Lookup.Result you get from Utilities.actionsGlobalContext().lookup(yourLookupTemplete) .

What is the garbage collection trick ?

Well, it's quite odd for me the existence of the Lookup.Result class. Because you don't do something like Lookup.addLookupListener(yourLookupTemplate, yourLookupListener). If you were to do something like this, you would expect that your listener lives as much as the Lookup. Meaning in the case of a "global" listener -- forever.

But what you do do is actually add a listener on Lookup.Result, which could be garbage collected and thus your listener also.

Generally, keep a hard reference on the Lookup.Result (or make a closure on it with some final keyword and a reference from the anonymous listener). Because if you don't -- the garbage collector might kick in quite soon and your listener won't be called.

Monday, November 20, 2006

NetBeans Platform: Branded resources

OK, you've probably been here too: how does one load a Branded resource ? Let's say... the splash screen.

Well, let me tell you the stages you might try after you've found out that it's "org/netbeans/core/startup/splash.gif" :
  • Use the ClassLoader from Lookup to load the resource. What does this do ? It returns the default, non-branded splash.
  • getClass().getResource(). Same as above.
  • new URL(). Wrong !
  • Utilities.loadImage(string). Still wrong.
Of course, the nbres:// protocol might also help (after all it's a NetBeans resource we're talking about) but you know what ? It also fails (with NPE) except for the new URL method.

So ? What is the solution ? Well, it's Utilities.loadImage(string, true) . This is the only one that does the localized/branded woodoo. I'm still not certain why the nbres:// stuff didn't work...

Sunday, September 24, 2006

Busy blogless month

It has been a really busy month since the last time I've blogged about the NetBeans Platform (or anything else).

Mainly it consisted of:

* one week holiday
* another super-busy week at work trying to do a quick catch-up for an urgent (aren't they all ?) project
* another week working and being part-time sick
* another week still recovering and starting to remember the Platform.

Basically my MindMapping application isn't near as ready as I would have liked (and there is at least another person working on the same thing: MindMapping with Visual library + NetBeans Platform). Bug it will be ready when it's ready. No deadline here. I was thinking maybe also use the new-ish StarOffice integration with NB that I kept reading about.

The good news is that I'll be working more on NetBeans Platform-related tasks so watch out for new hints.

I've also received a new Mac Mini (well, PPC actually not the new Core Duo) so I've got myself some new display/keyboard too ! A whole bunch of new stuff to make me want develop.

BTW: forgot to mention I've also got an article on the netbeans.org website. That was quite an interesting experience ! (you should see the blog traffic spike :) ).

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

#-org.netbeans.progress.module.ProgressVisualizerProvider

Enjoy.

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 https://progress-api.dev.java.net/ usefull. There is one app where I used it and it works great !

On holiday during the 24 august - 31 september period.

--
Emilian Bold
http://emilian-bold.blogspot.com/

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">
</folder>
</folder>


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-->
</folder>
</folder>


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"/>
</folder>


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 graph.netbeans.org). 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.

Monday, July 10, 2006

Units API (javax.units) live again !

It was a real shame that javax.units (aka JSR-108) died because of lack of interest. Some nice libraries already use it (geotools for example) and the Java world doesn't have a standard way of talking about units.

Unit measuring seems a very handy way to prototype some nasty formulas. Remember the old: forgot it was metric unit error ?

Well, now javax.units is reborn under JSR-275, with a RI based on JScience. There also seems to be a new package now: javax.quantities. I'm going to read the spec to see what's this about.

Friday, June 30, 2006

Using Netbeans Lookup.getDefault() outside the platform.

A nice thing about the org.openide.util package is that it is standalone and my be used in any project. So you can use Lookup everywhere!

Using lookup outside NetBeans Platform means that the getDefault() lookup contains only the meta-inf services and the classloader. Which isn't bad if you do your jars with services. But in my case I don't.

So I needed somehow a way to add some objects in the global lookup. Nothing easyer: just define the System.property: org.opeinde.util with your classname (which must be a Lookup.Provider) and them make your own public methods to add objects to the lookup.

So I had com.example.MyLookup registered, with my own static method addToGlobal() and that was I. I could register with the lookup things like the main frame, etc. and use it with the normal Lookup.getDefault.lookup(MyObject.class). Fun stuff !

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, June 26, 2006

Free as in beer and as in speech

An interesting thing this time on TV: a commercial of a mobile company where they say that after the freedom of speaking won from Ceausescu we will now get the right of free
speaking on the mobile (as in no money). I think this is something everybody could understand as a description of open-source with the free as in beer (the commercial) and free as in speech (won after the revolution).

Although the commercial is quite bad-taste especially after so many years after the revolution, it's an amazingly good description of the core free software movement ideea.

Weak References

The nice stuff about Java is that is has GC. The bad part is that the GC only takes care of memory. Why is that ?

Programmers like to be messy so we sometimes forget about little things like dispose() that memory. GC is great in this department. But we're also messy in the sense that we forget to close files, network connections, etc.

There are all kinds of resources, besides memory that the GC could, in theory, take care of.

On such thing are the listeners. I somehow have an inner fear about listeners since they seem messy, in the same way as memory managenent. God forbid you forget to remove a listener or your object will be kept forever.

So - why cant' the GC keep track of listeners also ? A quick solution seems to be the usage of weak references for the listeners. Supposedly a weak referenced-object is no longer needed so our listener can finally die.

And this is a simple way to involve the GC in managing the listeners.

The disadvantage is that there must be a strong reference to the listener at all times (when we need it) otherwise it could get GCed together with the Weak Reference.

We don't actually care about this when we have an ueber-object which implements XListener or we create an anonymous inner class (which creates a closure to the ueber). But if we do it the fluffy way with our own Listener implementation classes, it's back to ground 0 again. We still have to take care of the strong references, etc. Darn.

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...