Reading this article on Swing menus reminded me of how much I love programming in Apple's Cocoa framework
Cocoa is one of those frameworks that makes the simple things simple, and the difficult things possible. The standard way for handling menu item enabling and disabling echoes this approach. There are more complex techniques for more complex requirements, but the 80% solution is very simple indeed.
First: draw the menu. You do this graphically in Interface Builder, Apple's GUI interface layout tool. Except unlike other GUI layout tools, it doesn't suck. You arrange the objects, set up their properties, and tell it how they would talk to your controller objects if there were controller objects around. Then you write the objects themselves in XCode

You then connect the menu item to one of the "actions" in the FirstResponder object. For example, I would connect the "Print" menu item to the FirstResponder action called "print:"
The FirstResponder is a placeholder object. Whichever interface widget currently has the focus is the FirstResponder. Behind it is the "responder chain" of enclosing objects, all the way up to the main application object itself. (Interface elements can also be assigned "delegates" so you don't have to subclass the widgets themselves. These are also part of the chain by proxy).
Actions assigned in IB correspond to method selectors. Since the "Print" menu item is bound to the "print:" action, the menu will will search up the responder chain for an object that implements a print method. If it finds one, that method becomes the target of the menu item, and the menu item is enabled. If there are no objects in the responder chain with a print method, the menu item disables itself.
Like I said, there are other ways of achieving more complex menu requirements. This simple way just makes it so much easier to do all the simple things, and gives you an enormous amount of standard menu functionality for free. Aside from Print (OS X uses Display PDF, so pretty much everything knows how to print itself), there's stuff like this:

This is the standard bottom section of the Edit menu in OS X. The standard Cocoa text area (NSTextView) knows how to hook into the spell-check service, or how to speak its contents, or how to pop up a search window. And because of the way the menus work, the menu items just hook up to whatever text view is in focus automatically.
The practical result is that OS X applications are naturally rich. Every app with even the most trivial text-editing function has a spell-checker and a text-search feature, because you essentially get them for free, fully hooked up to the standard menu UI and keyboard shortcuts the moment you drag the NSTextView onto your window in IB.
Thanks for linking to me in your article. I would just like to point out that while Cocoa makes things easier, it's because of the development environment. Not the language. VS.NET makes these kinds of things really easy also. But doing it by hand in C# or VB is still mundane and problem prone. However, I have never programmed on OSX/MAC before. I wish I had the $$ to go out and by a desent one to work on.
I use to program NeXTSTEP/OpenStep/Objective-C for a living and I can tell you that
it's mostly the language Objective-C that allows people to do what is possible in OSX.
VS.NET uses code generation where as IB will archive the object graph when it says
the NIB file.
Gregg: What Robert said.
Most of the power, even the power of the development environment, comes from the Cocoa (or NeXTSTEP) framework itself. The FirstResponder/NSEvent menu handling I described above is purely a Cocoa thing: you could take advantage of it even if you were building your UI by hand-coding them.
But nobody hand-codes UIs in Cocoa unless they need to modify the UI layout on the fly. Which is really pretty rare: the most complex thing you usually have to do is replace one pre-drawn panel with another pre-drawn panel and resize the containing window.
This isn't just because the tool is available, but because the framework and the tool are designed for each other. Cocoa has a standard serialized object format for storing pre-drawn UIs. It has a standard set of APIs for unpacking these "nib files" and connecting them up with the rest of the application. Thus, you need none of the code-generation hackery that other frameworks have to do, and it ends up being a simple, elegant solution.
Java tried something similar a while back with the whole Javabeans/Beanbox thing, but it didn't work out because there wasn't a standard framework for hooking everything back into the application, and because Java is so much stricter about type-safety and serialized object versioning. As such, you had to share concrete classes between the beanbox and the dev environment, and you had lots of messy code-generation to hook up actions and events, where in Cocoa you just assign attribute and method names in IB, and worry about coding them later.