Thursday, October 12, 2006

.NET lacks action; can't keep up with Swing

Microsoft has really not understood the concept behind the GUI design pattern Model View Control (MVC). As I understand .NET can not connect GUI controls to functionality (logic) objects (that would be linking View to Control). I've asked this question on common .NET sites, usenet groups and it seems that they missed out on this part totally. To me, it shows that the .NET Forms project was really rushed and misses major parts that Swing has had for 8 years.

What I am talking about, is that Java Swing has Action classes that can be linked to GUI controls, which means that the GUI control uses the Action object when it has been activated (clicked for buttons, menu items, combo boxes, lists and even tree controls) . This Action class contains only the logic (Control) and nothing else; when activated from a GUI control it will perform it's functionality. The drawback with this approach that every major action needs their own class, which generate many more classes. But the benefit is that you can have several buttons/menu items, that uses ONE class to do a certain functionality. It helps during maintenance, where I am right now. This is nice, when a certain Action is disabled (for instance Save is disabled when the user doesn't have an active document); because it will notify ALL controls that is connected to the Action object. So the developer does not have to care which dialogs/forms/menu that are visible and must be disabled, etc. It is just one simple method call, and that is the beauty of it.

Another nice thing with it, is that the Action class contains most of the important properties for a control:
* A name (for buttons) (can be localised)
* A short description (read tool tip) (can be localised)
* A key accelerator, for short cut keys
* An icon (next to the text in buttons and menu items)
* An mnemonic key

So when I need to create a button and menu item, all I do is:
anAction = new FileSaveAction();
JButton button = new JButton(anAction);

mainFramePanel.add(button);
JMenuItem menu = new JMenuItem(anAction);
mainFrame.getJMenuBar().getMenu(0).add(anAction);
anAction.setEnabled(false);
//.. user opens a new document
anAction.setEnabled(true);

The above code will create a button in the main frame panel, and a menu item. They will have the same text, the same icon, the same tool tip AND both are disabled at the same time. When the user opens a new document it is just one method call to enable both controls. Magic, isn't it? Or is it just properly designed?

At my current project, which is a huge .NET project, they have many menu items and buttons that each of them needs to be enabled/disabled when some functionality is disabled. That generates alot of excess code that isn't needed and is hell to maintain. Since the application is localised in 5 different languages, the developer needs to code enable/disable functionality for least 2 GUI controls. And this means that each control needs 5 different localisations which needs to be set. Talk about unnecessary and unwanted work.