Sometimes you only need a little.
The book is done and I'm up to my ears in Windows bugs so I thought I'd take a break and work on some Mac stuff. There are a few features I've always wanted from Java and needed anyway for another side project (I've got about 3 dozen, of course). The result is a few teeny, tiny classes I've added to the new JDIC Misc project. This project is meant as a catchall for small APIs, things that require only one class or perhaps even one method. The implementation may be complicated as all get-out, but to use it you need only call a function or two.
I'm an equal opportunity platform user, having years of experience with Windows, Mac, and Linux, but I currently work from home on an iBook so that's what I've been working with lately. JDIC has always been lacking on the Mac side, so I thought it would be nice to have some features show up there first. The result is three new APIs in the JIDC Misc incubator project: Volume, Alert, and DockMenu.
Volume is simple. Just get an instance of
Volume from the factory method and call
final Volume vol = Volume.newInstance();
// get the volume
float current_volume = vol.getVolume();
vol.getVolume(current_volume + 0.1);
It returns the volume as a float from 0 to 1. You can also add a property change listener to look for the "
volume" property. When the system volume changes (by the user pressing the volume keys on their keyboard, for example) your application will be notified. Incidentally the OSX implemenation doesn't actually use native code. Apple has provide Java wrappers to the Core Audio APIs (although they are woefully under-documented). I haven't found any announcements about it, but according to the docs in the latest developer tools they have open sourced the Java CoreAudio wrappers. I couldn't find any more information, not even a license, but the implementation should be there on any Mac, so I don't know if the license matters. I should also mention that this does run on Panther. Tiger not required.
Over a year ago I wrote a series of articles about making your Java desktop application feel more native. I mentioned an alert API to make the dock icon bounce when you need the user's attention. Unfortunately that API uses a now deprecatead form of JNI, meaning you could only use it with Java 1.3 applications. Through many hours of beating my head on the cocoa-java documentation I have figured out how send a user alert and bounce the dock icon using only the builtin java wrappers. I'd like to say that Cocoa is a great API and well structured. It's just very very different from Java, making the (under-documented) bridge wrappers difficult to understand. Anyway, now it's encapsulated in a neat API that you can use with two method calls. It's currently Mac OS X only, but I'm working on Windows support.
So, want to alert the user (only when your app is in the background)? Do this:
Alerter alerter = Alerter.newInstance();
Some Mac apps have a special menu that pops up when you right click, control click, or press-hold on the dock icon. This menu provides quick access to the important features of your application (like pausing iTunes) without making the application go to the foreground. It's certainly an extra, but makes your application feel more like it belongs on the mac.
Since only Mac OS X has a Dock, this is a Mac only API. However the non-platform specific API includes a dummy implemenation for other platforms, meaning you don't conditionals to turn it off when running in other environments. The menu will simply be inactive. If another platform ever supports something like dock menus then we can always add a new implementation, without having to change your code.
Here it is:
JMenu dock_menu = new JMenu("Dock");
dock_menu.add(new JMenuItem("item 1"));
dock_menu.add(new JMenuItem("item 2"));
DockMenu dm = DockMenu.newInstance();
The dock needs it's own JMenu, so don't reuse one from your normal menus. The advantage, however, is that you can set the JMenu once, modify it later, and the changes will be automatically reflected in the dock menu. Other caveats include, no sub-menu support (coming soon) and your action listeners won't be called on the Swing thread. You'll need to do SwingUtilities.inovkeLater() if you plan to manipulate Swing components or else your app could completely lock.
So that's it. Three tiny but useful APIs, and Mac first. We need implemenations for other platforms (especially on the volume and alert APIs) so please jump in with contributions if you have them. https://jdic.dev.java.net/ Oh, and these have just been added, so you will need to check the code out from CVS if you want to use it. We should have a new full build of the Misc project in binary form soon, though.
Obligitory book plug: These APIs are not in the book. We simply didn't have room. The book is that packed with good stuff! (well, Chris, Romain, and Jonathan's stuff is great. Don't know about mine). However, once the book comes out that some of that code will find it's way into JDIC and other open source projects here as well, so stay tuned.