Monday, July 23, 2007

Menus as Non-Modal Dialogs

I was thinking the other day about how best to keep the details of application logic hidden from Swing widgets (in the spirit of Martin Fowler's Presentation Model), the main intuition being that a user app can/should (arguably) be modeled as a set of nonvisual capabilities to which utterly dumb GUI widgets can later be mapped. Achieving this in a clean way is incredibly difficult. (Or at least for me it is.)

I had an epiphany of sorts. When you design a standalone user app (a menu-driven desktop app), what's the first piece of UI you design? The menu system. And what is a menu? In Swing (Java), it's a series of nested buttons. (JMenu and JMenuItem inherit from javax.swing.AbstractButton.)

The menubar never goes away. Some apps let you hide it, in which case it's merely made invisible (it doesn't actually get released from memory). There's a name, of course, for collections of buttons that never go away: a non-modal dialog. My epiphany was/is that a menu system is a collection of non-modal dialogs. (And I hate non-modal dialogs, both as a user and as a programmer.)

In the typical menu-driven app, menus are non-modal dialogs in which each button "knows too much" about deep application internals. The ever-changing state of the entire app is controlled through this collage of interdependent buttons, and managing the underlying ill-formed dependency graph is difficult, and this is why menu apps are a pain the ass to write.


  1. This would, I'd guess, be why in the MFC classes (my one reference point for a similar construct), there's a ridiculously complicated flow of messages (events) through the app with any changes.

    There's an event something like "Update UI" that's sent to all UI components with any recognizable change in state so that each UI component (menus, individual items on menus, etc.) can update themselves based only on getting a notice to be updated (though of course, as you say, the logic they might then implement needs some kind of omniscient insight into the data in the app to make its own determination on whether it needs to change its state).

  2. Right. I liken this to an ad-hoc messaging system that only knows "fire and forget" notifications. Some people have suggested implementing a singleton State object that serves as a kind of event bus or message bus for the whole app. UI elements can then "subscribe" (and/or "publish) to the State queue (think MQSeries). You can restrict intimacy by having filters at the queue (think MQ "Topics"), etc. It can get out of hand fast, but these are the sorts of things you start to think about doing when you want to manage state in an orderly way.

  3. Anonymous1:57 AM

    You give the good detail about the non-model dialog and yeah you saying right about this matter and I like this because you discuss one of the major issues. I have no word to describe it more because you give almost complete detail on this issue.


Add a comment. Registration required because trolls.