Making the simple complicated is commonplace; making the complicated simple, awesomely simple, that's creativity. -- Charles Mingus

Sunday, April 19, 2015

More news on Java, Mac, Screen Menu Bar

It turns out that the situation described in my previous posting does not tell the whole story.

After making the screen menu bar work for one of our applications, I attempted to do the same thing for the others.  One successful trick in the first application was to override JMenuBar.addNotify() to add the accellerators.  The theory was that this is the moment that the screen menu bar is created.  And the technique worked for one application.  But...the same trick, indeed the same code, did not work for other applications in our suite.

The best I can tell is that there is some kind of race condition which gives a time window when the peer is ready, and if you miss it, you're sunk.   But this is just a conjecture.  Still working...

Sunday, April 12, 2015

Java Desktop Applications: Menus on the Mac

Our desktop applications are written in Java, and we work hard to make this fact completely transparent to our users.  They shouldn't have to care what language their applications are written in.  One challenge with this is to make the applications conform to the expectations of the host platform.

We recently puzzled over a problem with Swing menus and accelerator keys -- you know:  Cmd-C as an abbreviation for Copy.  Attaching accelerator keys to Swing menu items is trivial, it works everywhere except on Mac OS X when the application uses the screen menu bar.  Then the accelerator keys are not (always) installed.

The problem is that on Mac OS X, the screen menu bar is a peered object, like all of the controls in AWT (and supposedly none in Swing).  There's a bug in the JVM code for managing the screen menu bar, which means that if you attach the accelerator key before the peer is created, the accelerator is not passed to the peer when it eventually is created.  If you attach the accelerator later, after the peer has been created, then the accelerators do appear.

The only way we found this out was that in one of our not-yet-released applications we play with the accelerators once the program is running.  The same accelerator is moved between menu items, and we noticed that this accelerator key was being correctly set, because it was done later.

So moral of the story, make sure that the screen menu bar is visible prior to setting accelerator keys on the Mac.  Of course AFAICT (please let me know if I missed something), there is no way to find out whether the screen menu bar has been made visible, so good luck being 100% certain that things are always going to work.