I recently had to track down the cause of a NullPointerException when opening a JFileChooser dialog in Praxis on Windows with Java 7. Turns out there’s a nasty little bug that affects NetBeans platform apps and the NetBeans IDE when using a custom look-and-feel or switching look-and-feel at runtime (it affects the ez-on-da-ice plugin too).
It turns out the NPE was being thrown in the initialization of the WindowsFileChooserUI, which confused me for a while as the Praxis look-and-feel should override this. Praxis installs its look-and-feel from a ModuleInstall (more details of which are here). Well, it turns out the NetBeans platform and IDE includes a module that provides an alternative JFileChooser UI for selecting directories. This module (org.netbeans.swing.dirchooser) works by installing a delegate in place of the standard FileChooserUI. What this doesn’t explain is why the Praxis LAF override wasn’t working …
Please trust us, we may know what we’re doing
When the dirchooser module installs, it looks up the current FileChooserUI and creates its own UI that can delegate to the original. It also attaches a PropertyListener to listen for changes to the FileChooserUI, and if it changes, it changes it back to the delegate! I hate this sort of code – document the procedure and trust me that I know what I’m trying to do, listen in if you must and write something to the log, but don’t just change the value back! (can you tell I’m a little annoyed! :-) ) I’d almost forgive this code if it actually updated the delegate to point to the new UI, but it doesn’t, meaning that the WindowsFileChooserUI is left in place without resources it’s relying on … and goes boom!
TL;DR – what’s the fix, dammit?
There’s a number of workarounds for this bug, although none without some issues. As the Praxis LAF (based on NimROD) uses the same BasicFileChooserUI as Metal, then initializing to Metal first will work. The Windows-only bug-fix release of Praxis LIVE fixes this by using ‘–laf Metal’ in the .conf file. You could probably also set this in the validate() hook of a ModuleInstall. However, this wouldn’t work for a look-and-feel with its own FileChooserUI.
You could also use ‘-J-Dstandard-file-chooser=true’ in the .conf file to switch off the delegate altogether, but this makes the Open Project dialog more awkward to use.
Of course, neither of these options allow for switching the look-and-feel at runtime. The ideal thing would be for this bug to be fixed in NetBeans – I’ve re-opened NetBeans bug #207569 which covers this issue.