Wednesday, June 27, 2007

Maven and NetBeans (Platform)

As most of you know, the build system in the NetBeans IDE is entirely ANT-centric. That is, every project has a generated build.xml behind the scenes and every action (compile, run) is an ant target actually.

But, of course, you can't please everyone. Using ANT as a backend means that, of course, you need some custom ant targets to make the IDE-integration better. Thus, you're not 100% independent of NetBeans, you still need those custom tasks (some JARs basically) and the core ant scripts.

Using ANT also means some overhead for each action.

But the most nasty stuff in my projects are the 3rd party JARs. Most projects use some outside blobs. Normally, you can have the JARs in SVN and NetBeans will take care of this quite nicely (using relative paths).

But what happens if you decide not to include those JARs in the SVN ? Well, you enter a world of tweaking of .properties files and custom ant tasks to re-populate those properties files. It's not pretty and error-prone in a distributed project.

Maven on the other side has this repository concept. That is, a place where some 3rd party JARs sit. Your POM file (project metadata basically) just declares the dependencies and the repository list.

Imagine that: you have a local intranet repository and everyone in the team is using it. No more relative paths, no more custom ant tasks !

I've been migrating my SVN for about 3 weeks over to maven. I have normal Java projects, Enterprise projects (EJB/WAR) and NetBeans Platform modules (NBM). It's a bumpy road (I haven't used maven until now) but it does seem to simplify thigs.

But what you win on the dependency side you lose on the integration part. With MevenIDE you have normal NetBeans IDE projects, but not that kind of IDE-integration you have to module-projects for example. No more easy configuration for public-packages -- back to editing manifest files like in the old NetBeans 3.x times ;-)

Overall, Maven2 seems a better choice for the build backend then Ant. You can't customize it that much but once you have all the plugins properly configured, it works better. Plus that you are totally decoupled from the IDE and IDE tasks, but you depend now on the extra plugins.

Most of the continuous integration servers offer support for Maven2 projects so you can drop the new projects immediately.

Monday, June 18, 2007

Gnome Typing Break

As I've said in an older post, I wasn't that impressed with the latest Ubuntu but I also couldn't install OpenSolaris on a laptop. So I installed Ubuntu 6.06 LTS, which seems to work quite nicely. I even has suspend to RAM working (though it breaks the sound afterwards).

One nice feature Gnome has that I didn't know of it is Typing Break, found in System -> Preferences -> Keyboard.


It basically forces you to take a break after a period of time. Gets useful after you start getting some hand-aches. During the break you see something like this:



It takes a bit of discipline to actually respect the breaks (especially when something is urgent and you have the "Postpone" button -- which should be renamed to Snooze). Then again, even if I disable the postpone button I might be tempted to Ctrl+Alt+Backspace or Ctrl+Alt+F1, login then kill process.

I'm also looking at some exotic and ergo- keyboards lately. Anyone has something to recommend ?

I would really like something like 2 half-keyboards. One for each hand, then going into the USB port. This way I can place them to the right and left side of the laptop and use them quite nicely -- it's almost impossible to use an external keyboard with a laptop without also adding an external display.

OK, no flying cars. But 2007 and no mind-reading input devices ? Someone is slacking off...

Thursday, June 07, 2007

Pro NetBeans IDE 5.5 Enterprise Edition Review

Adam Myatt's "Pro NetBeans IDE 5.5 Enterprise Edition" could be quite well an introductory course to Enterprise programming in general and especially a good book for NetBeans IDE (future) users in particular.

It's quite decent for a novice programmer because it consists of small tutorials and introductions in all the different technologies that the NetBeans IDE supports. It gives you the starting point in your endeavor. It's most needed for an introductory course in any Enterprise since it touches a lot of important points like unit-test, good javadoc, version control, build system (ant-centric, like the IDE) and more.

Since it covers that many topics there isn't actually enough space to go too deep into any of the subjects. The spotlight is after all on the NetBeans IDE and the features it has. This is quite a shame since there were some unique things that could have been discussed more upon: Jackpot refactorings made me really curious...

It's also nice to see some features I've discovered myself in the IDE after a while - like the database support and SQL command window - which turned out to be quite useful. Readers get a chance to find out about them from the start.

All in all, a good book that covers a lot of ground. It doesn't touch at all making NetBeans Platform modules, but that's not expected for a NetBeans IDE user. Although, after a while of living in your own IDE, you can't help it but customize it a little -- enter module development.

Wednesday, June 06, 2007

There is truth

There is truth, my boy. But the doctrine you desire, absolute, perfect dogma that alone provides wisdom, does not exist. Nor should you long for a perfect doctrine, my friend. Rather, you should long for the perfection of yourself. The deity is within you, not in ideas and books. Truth is lived, not taught.
Herman Hesse, The Glass Bead Game

Tuesday, June 05, 2007

OpenOffice and Java take 2

Hm, I just got this morning the weekly NetBeans newsletter and it had this part:

Netbeans Plugin for OpenOffice.org Development

Sun's OpenOffice.org engineering team has developed a plug-in for building OpenOffice.org extensions. It is an easy to use set of wizards to create OpenOffice.org extensions that can be used to integrate new functionality, adopt existing functionality, and create Java applications that can remotely control OpenOffice.org. Everything is ready for you to start implementing OpenOffice.org extensions, including a Java code skeleton.

So, SUN is still supporting this. Maybe I'll take a look at this new plugin and see how it feels.

Monday, June 04, 2007

Is OpenOffice too late with the Java-bindings ?

I remember my first "important" job at my previous employer was to maintain some in-house Office-based application. Nothing like Excel and VBA to ruin your day ! Well, I was a rookie so I couldn't refuse but it was a depressing experience.

For some time now (I remember I was running some samples last year), OpenOffice has some nice Java bindings (or API). Now, this is all great, but the actual code looks quite arcane.

What troubles me is this: why was OpenOffice so late with this move ? I mean, most programmers don't want to live inside Excel and Visual Basic so if you have a choice, you move a simple dedicated "application" from Excel + VBA to OpenOffice + Java.

I guess it's obvious Java is a better choice (than VB) for most programmers (it would have been for me) and the final product would have been better in so many ways:
  • More happy programmers that they don't have to use VB or (oh, the horror), maintain VBA.
  • A decent codebase for your initial small application in Java, that could, potentially be migrated to a full Swing application (if we just treat OpenOffice Calc or Write as the GUI toolkit). I mean, most code will get thrown away anyhow, but it's quite a waste of time reimplementing the same business logic (with the VB code as a reference). This would be a perfect change to actually use the IDE's refactoring.
  • Possible introduction of OpenOffice in the corporate ! Sure, people would still copy-paste from your "application" into Microsoft Excel but that should be quite pain-less. But the developer won't have to worry about a new Office version or some other Microsoft-specific (DLL) nightmares.
But, today, making desktop applications with OpenOffice (in the same style like Excel + VBA + VB DLLs) seems less of an option:
  • it's really hard (look at the API) and the practice isn't actually encouraged. The 100% Java purity had probably done more wrong than right here and most people will just suggest using some Swing Application or framework like NetBeans Platform. But why shouldn't people do this kind of applications ? Most internal apps have some sort of tabular data and lists and then fancy reports. Why should we struggle with JasperReports and such when you have the nice OpenOffice Writer codebase ? Export to PDF: check, export to tons of other formats : sure!
  • OpenOffice doesn't provide a nice "platform". Something to put in a folder with all the jars and DLLs and work flawlessly. I don't need to "install" OpenOffice: I just want to distribute my application as a simple ZIP file. No DLL hell, no nothing. Make that with (Consumer) JRE included and a simpler API ! (this is linked to the previous point).
  • We have reached the point where tiny web-apps seem good enough and are developed fast enough to give existing Excel-based tools a short lifespan. This is a good way because we get rid of Excel but people still need to reinvent the same things over and over: charts and nice (PDF) reports that OO Calc should have facilitated (do I hear OpenOffice-based rich-client ?).
I think OpenOffice missed the boat by a lot for standalone (tabular) applications and it would have been a really nice thing for everyone ! Maybe even for Microsoft since it would have put to death the abomination known as VB 6.

Sure, this would have destroyed the purity of your application, mixing it with the OpenOffice native code and maybe even with some other COMs but I think it would have been better overall.

Wednesday, May 23, 2007

Euro ripoff (aka The gold you have to pay for pretty glass in Romania / Timisoara)

Ever since the dollar took a nose dive against the Euro I always drooled at the nice prices the US seems to have. Why ? Because most sellers in the EU (and Romania) make a really 1:1 conversion. This means that if something is about 1000 USD in the US it will be about 1000 EUR in EU (although this means about 1300 USD - 30% increase! ).

Now, on the other side of the spectrum sits Romania. Since we basically have no market-culture and we are still in some sort of Wild-wild-west kind of economy, the prices here are even higher than in the EU. So, there you are: probably in the poorest country among the EU ones, and you have the biggest prices for computers.

That would be one thing but there's more: you basically can't find decent brand workstations (powerfull desktops) and if you do, your best chance is if you live in Bucharest, the capital. And Bucharest is way in the east compared to Timisoara, and quite-ugly as a city might I add ;-)

So, outside Bucharest you only have the major retailers (which means that you get no service on-site and all your hardware is sent to Bucharest for service; scary thought for a laptop) or some medium-sized companies. As in Economy 101, when you sell something that's in short supply, what do you do ? Well, of course, you increase prices.

Thus the local companies that do have service on-site have even higher prices than the retailers.

In summary: Price(Timisoara) > Price(Bucharest) > Price(EU) >>>>> Price(US).

To everyone that complains in the US about high Apple/HP prices or some other nonsense like this I have an advice: come to Romania for a while and live the experience :-)

End of trolling / muble-grumble session.

Saturday, May 19, 2007

Migrating to Derby (JavaDB) with schema

I went to a lot of trouble lately trying to migrate a database from MS SQL Server to Derby (aka JavaDB) [1]. I've used the DDLUtils ant tasks to export-import the database.

The major issue was that in my previous database we used a given schema and that schema wasn't recreated now by DDLUtils. I've tried tweaking the ant task parameters but still nothing. I even done some quick sed scripts [2] to add the schema myself (rename tables from "oldname" to "schema.oldname" basically). But all this meant nothing. Plus that the database was 100MB+ and import time was well over an hour so I couldn't actually try a lot of times.

The solution resided in the Derby FAQ but it wasn't until someone from the mailing list pointed it to me that it struck me:
The current schema for any connection defaults to a schema corresponding to the user name.
You see, I was creating the database beforehand with some random user like "admin". I didn't notice this was the default schema. Also, while reading the same FAQ, I just skipped to the part with SQL.

So: if you migrate to Derby, always create an username with the same name as your schema (the one you import).


--
1. I wouldn't actually put Derby on a production server but I feel better during development having the data in a more cross-platform DBMS . Plus, I'm spared of all the security issues MS SQL has (or at least my fear of having those ports open).

2. Yep, sed. I know some XSLT might have been smarter but I'm quite rusty at that and there is no easy xslt shell/script I could use.

Friday, May 11, 2007

Building is fun with Hudson

I've used last year Cruise Control and really liked the feeling a continuous integration and build system gives you. There you have a central place to see the health of the project (unit tests), linked to the VCS and a build server.

This year, I've re-evaluated Continuum and Cruise Control and found out that I still had to work with some XML files to make it work. Plus, notification is exceptionally hard to get right.

So, everything was paused until I found Hudson. It's a web-application (like the other two), quite new and active (unlike the other two).

It has the best out-of-the-box experience. Just deploy the WAR and configure your project. Continuum comes close here with Cruise Control third.

Since NetBeans already generates proper ant targets for everything including tests, I just need to configure what ant task to run, which are the build artifacts and where to get the junit results from.

Of course, I did stumble on some problems:
- Running multiple ant targets it's impossible (ie. multiple build files) so you have to make another script that calls the others.
- make sure junit.jar is in ant's classpath.

But Hudson is impressive. Help messages at each step, SVN integration (with authentication), nice charts.

It could still use some more reports and plugins but I think it has a bright future. I might even write some plugins myself if it gets selected for the build-server.

Monday, May 07, 2007

Still in OS land: OpenSolaris

After Ubuntu, I said I could give a chance to (Open)Solaris. I do remember Solaris from the Sparc stations we had at the University and I keep on reading about ZFS and dtrace, but I never actually used it much.

So I just went and downloaded the DVD, burned it then installed Solaris with no fuss on top of the previous Ubuntu partition. Rebooted the system and it all worked! Even had an option to switch between Gnome and CDE -- well that brings back memories...

First, OpenSolaris (Developer version) really seems a Java programmer's kit: I get NetBeans 5.5 with Sun Java Application Server. Even the installer seems Java. Plus, I have Firefox, Thunderbird and a Terminal: that about covers most of the stuff you actually need while working. Sadly, no movie player like Xine or VLC.

Of course, there was some strangeness:
  • it also installs Sun One Studio which seems redundant with NetBeans but I didn't actually try it.
  • even if we do have SJAS installed, it doesn't show up in NetBeans. Using the Server Manager is quite easy to add it and it took me about 3 minutes but it was strange. I guess it has something to do with the multi-user settings.
So, wish me luck. I kept wanting to try out SJAS clustering and doing this under Solaris seems the best solution.

Friday, April 20, 2007

Ubuntu 7.04 over-hyped

I've used Linux under some form or another for some time (I think 7 years or so). Started with some SUSE then found out RedHat and switched to Ubuntu when Fedora turned out to be a mess.

Since I'm a little stuck on Windows for the programming part I use nowadays mostly Windows (2000/XP) and OSX.

Ok, so I saw all the hype about Ubuntu 7.04 and downloaded the torrent. Let's say I wasn't impressed.

I used a lot at my previous job Ubuntu on a T60 Thinkpad so I knew how it should feel. This new release was about the same plus a fancy-er splash screen.

Even more, the Live-CD detected my NVidia Quadro NVS graphics card and installed the driver for it. Thus I could enable "Desktop Effects" and look at the wobbly window (then disable it immediately).

Ok, so I've installed 7.04. The first surprise: it didn't boot-up ! I mean, it did, but in text mode.

You know why ? The XOrg configuration still had the reference to the nvidia driver but the installer didn't actually install the driver on the hard-drive. Since this is something common (to me), I just went to xorg.conf, and replaced the driver with the default nv. I only assume a normal user would have given up at this point with no GUI.

Ok, with nv I'm able to startx and install the nvidia driver (plus some update manager ... update). I need to restart the system (why ?) because of the new driver.

Again, it doesn't boot ! Why ? I have some wacom input devices in my xorg.conf and it fails while looking for the device (/dev/wacom or something).

Again, I edit xorg.conf, comment those things and -- finally ! -- I'm able to boot normally.

The nice thing is that I'm able to install Sun's JDK immediately. When I get to Netbeans in Synaptic I notice a warning that that package doesn't actually contain Netbeans, I have to manually download the tar. The package Netbeans from Synaptic just provides "integration" with Gnome. Huh ?

So, this is the first Ubuntu that crashes on me at install time and basically forces me to go inside config files. If anything, I would say it's a regression and not an evolution.

One could say that it's my graphics's card fault, but since Ubuntu does provide the users nice point-n-click ways to install those drivers, anyone would expect for those things to work.

Thus, I'm still waiting on my Windows/OSX setup with the intention of buying another Mac as soon as Leopard comes out.

Friday, January 12, 2007

NetBeans Platform: CallbackSystemAction sync madness

An annoying problem I had this week involved the CallbackSystemAction class.

Basically the general ideea of this type of action is this: you have the Action implementation, but the "#actionPerformed code" is deferred.

What was my problem: depending on the user selection in an explorer, my action was supposed to become enabled or not (plus some othe conditions).

So, the javadoc says that way to do it is by setting an action in the ActionMap of the TopComponent.

TopComponent tc = ...;
javax.swing.Action yourCopyAction = ...; // the action to invoke instead of Copy

CopyAction globalCopyAction = SystemAction.get (CopyAction.class);
Object key = globalCopyAction.getActionMapKey(); // key is a special value defined by all CallbackSystemActions

// and finally:
tc.getActionMap ().put (key, yourCopyAction);


The problem is that there is no listener on the action map. So if I want later to disable my action and I do a tc.getActionMap().remove(key) -- it won't work ! I mean, it will work if you change the current TopComponent and come back to the original (I guess there are some event thrown there that CallbackSystemAction catches and does a refresh).

So, using the ActionMap.put and #remove doesn't work !

Ok, I said to myself, I'll just use the deprecated #setActionPerformer , which seems to work better. Only it is deprecated, which is not good.

I went and complained on the dev@openide mailing list and I got a tip that I should change my TopComponent's lookup in order to fire the events that CallbackSystemAction might catch to refresh itself.

But you can't call #associateLookup twice ! Arr.

So I just started reading carefully the CallbackSystemAction source code and I've noticed that it does put a listener on the enabled/disable state of the TopComponent's action (ie. yourCopyAction in the example above).

So -- what's the solution ? Dead simple: call getActionMap().put(...) once and then just do a #setEnabled on your Action. Simple -- but very non-intuitive.

Actually in this situation I would say that the Javadoc was more confusing than useful because it says

The action will be automatically disabled when it has no performer.

and removing your action from the ActionMap means exactly that: no performer...

Saturday, January 06, 2007

NetBeans Platform: Combobox in property editor

Happy new year everyone !

I'm going to talk today about something simple GUI-wise but quite a lot asked on the mailing lists: how does one display a combobox in the property editor ? Actually, how does one use an editor that displays a combobox.

What should get you started with this task (and other editor customizing) is a little file from the Platform javadoc.

This is what we plan to get:


In order to do this note the Custom parameters in core editors paragraph from the above link and the fact that for java.lang.Integer properties there are some custom keys we can use:
  • stringKeys - an array of strings to be present in the combobox
  • intValues - an array of integers representing the values of the selection in the combobox.
So something like this:

Node.Property p=new YourProperty(Integer.class);
p.setValue("intValues",new int[]{1,2,3,4});
p.setValue("stringKeys",new String[]{"One","Two","Three","Four"});

is all you need.



Note: Please take care that for the current property
  • #getValue is the index in the intValues array. So if you want to see "Three" in the combobox, you return the number 2 in #getValue.
  • #setValue is called with the actual number from intValues (not the index). So if the user selects "Four" from the combobox, #setValue(4) will be called.

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

Findus and the Christmas Tomte

Sven Nordqvist's Pettson and Findus series is beloved for its cozy portrayal of rural Swedish life. An eccentric old farmer, his talking...