So one of the things that I do in my infinite spare time is wade thru people's bug reports as if I were a tester. The report comes in, and it gets stuck in a list, and I'll review and respond to them before testing gets to them simply because the subject may catch my attention. For example, if I see a report that corresponds to an area of the code base I've recently been in, then I know I'll just end up with that report on my plate sooner or later, and I'd rather make it sooner.
Because I check out the bug reports directly, quite often I get to see code that others have written since everyone know that the best bug reports include a sample project that demonstrates the issue. Sometimes, the reports aren't so simple, and I end up wading thru someone's entire application. These reports I usually just send along to testing since I don't want to deal with poor reports.
So basically, I get to see a whole wide range of user application in a very general sense. Because of this, I notice areas where people do things wrong more often than not. So here's my little list of common UI mistakes that I've seen people make based on a number of years worth of bug reports flying past me.
- Duplicate keyboard mnemonics in menus. Remember, the & denotes which letter will be underlined, which in turn denotes the keyboard mnemonic used. These must be unique in order to be truly useful. So quite often I'll see people double these up in their menus. There'll be a &Save and a &Save As for example. I've even seen this happen in professional-grade software such as WS_FTP.
- Related to #1 are duplicate keyboard mnemonics on a view. The most common mistake -- doubling it up with a menu. If you have &File as a menu name, then you cannot have &Foobar as a mnemonic on your window. Think about it -- when you want to get to the file menu, you hit Alt+F and it brings the focus to &File. So &Foobar is a duplicate because of the menu. It's also common to see people who just underline the first letter of every StaticText label, and this can often lead to duplicates as well. Duplicate keyboard mnemonics are worse than not having any at all (which is pretty bad to begin with!) since it gives the user the false impression that they can use the mnemonic.
- Duplicate keyboard shortcuts is another major issue. If you have Ctrl+S for Save, then you cannot also have Ctrl+S for Sort since the two will conflict with one another. This problem tends to get worse as the menus become more full.
- Forgetting to set a Default and Cancel button when having these buttons in a dialog. If you have a button named Cancel, you should be certain to set it to be the Cancel button, otherwise pressing Escape will not do the proper action. The same thing goes for the default action -- you should always have a default action for your dialogs. For example, if you have a Save/Don't Save/Cancel button group (heh, then you've got the wrong captions for it on Windows -- it should be Yes/No/Cancel there) then Save should be the default and cancel should be the "cancel" button.
- Incorrect tab ordering for controls. I see this one especially hitting Mac developers hard. When you do the majority of your dev work on the Mac and bring your app over to Windows, it's very easy to screw the tab ordering up. That's because most people don't have Universal Keyboard Access turned on (I always do, imagine that :-P) and most Mac controls don't get the keyboard focus by default. You should always make sure that your tab ordering is correct on Windows and Linux -- it goes from the upper left to the lower right. Getting the ordering wrong is a very easy mistake to make, but it's also very easy for people to pick out as a bug in your application.
- Not following the most pervasive UI guidelines for the platform. For example, if you're on Windows, you may be used to making all your OK/Cancel/Apply buttons in that order. However, on the Mac, it's Apply/Cancel/OK. Another easy one is text justification in StaticTexts. Or not using sheet windows on the Mac when you're supposed to. Using the wrong font for the system, or using varying fonts. All these sort of things are quite common and require a bit of thought when designing your UI. And they affect anyone who's cross-compiling their application.
Make no mistake about it (no pun intended) -- these things are very easy to get caught by. But just because they're cosmetic and harmless in nature doesn't mean you're allowed to make these mistakes. If you've got any of these issues in your application, then it's a bug.
If it makes you feel any better, another major source where I pulled this list from was RB 2005 itself. One of my (many) jobs with this release was to ensure that the UI was correct for Windows. Every single item on that list was something I had to correct at one time or another in the product. These mistakes I've pointed out are really easy to make, so I'd suggest you check your own applications to see if you've fallen prey to one (or more) of them.
Re: #6:
On a Mac, you shouldn't even have an Apply button! Rather, changing the value of a controls should take immediate effect rather than requiring the user to "apply" the change(s).
And a Windows question that I've wondered about for years: what is the difference between Apply and OK, other than dismissing the window? And does one need to press Apply before OK?
Good point about not using an Apply button on the Mac.
Apply and OK only differ by closing the window. You don't need to hit Apply before OK -- the apply is implicit when hitting OK. When you hit Apply, the changes should take effect immediately or warn the user otherwise (such as "you must restart blah.exe for the changes to take affect.") and Apply causes Cancel to not do its job. Once you've hit Apply, hitting Cancel just closes the window without undoing the change (unless you make other changes after hitting Apply and before hitting Cancel).
The entire concept is horrible. No one will blast you for having only OK and Cancel on a dialog, but I've heard (never really seen) that there are situations where Apply comes in handy.
If the REALbasic IDE is ever user-scriptable or extendable, it would be nice to have an automated compliance checker for #1, #2, #3 and possibly #4.
It's entirely possible you'll see some of these things built in. For example, I know right now, the menu editor makes a half-hearted attempt at checking mnemonics within the menus for duplicates. You can see this by going to the EditMenu, making a new menu item, and setting its text to &Unusual. You should see (in the StatusBar) something that says this mnemonic is taken by Undo.
But I'd like to make these checks more obvious and something you can do via a contextual menu of some sort. Also, make them much more useful by using them on the window, etc.
@Aaron: THe only use for the Apply button I've found is when adjusting the display properties (which I end up doing often at school), so I can see whether the change I made works without having the dialog go away. But it would be better if changes just took effect when I made them (and this is how I code my apps).
Yeah, that's about the only case where Apply makes sense that I can think of. You can't just change the resolution whenever the list selection changes because some resolutions require a reboot and you need to alert the user of the fact. But you're right, in many (most?) cases I think it's good to make the changes as the selection changes without requiring an Apply button.
Heh.... I read that as "Yeah, that’s about the only case where Apple makes sense that I can think of." Oi! I was about to flame ya, mate! :^)
I agree with Phil. The IDE should care of checking such things. In some widget frameworks (I think it was MFC, but I may be mistaken here), the framework actually checks mnemonics for uniqueness and automatically shifts them to the next character that makes sense. While I prefer whacking the developer over the head with that (especially since these dynamic moves can cause havoc when you start dynamically (un)loading some UI), that's a viable alternative IMHO, especially since it also catches run-time mistakes of this sort.
As to the "Apply" button: IMHO, OK *and* Apply should never be done. They confuse the users exactly because they won't be able to tell the difference between the two without first trying it.
And anyway, IMHO today's OSs should have all-modeless panels, not modal dialogs, for everything but simple yes/no/cancel alerts, and in these you'd ideally live-update the data. Where that doesn't work for security, validity or performance reasons, an "Apply" and "Revert" button pair, plus a "do you want to apply your changes?" question when closing the panel are a much better choice.
Sorry for the long comment :-)
I'm definitely guilty of #5. I'm working on an app right now that I've been developing on the Mac. I decided to give it a run on Windows and sure enough I'd screwed up the tab ordering.
@Uli -- I used OK/Cancel/Apply as an example of a three-button interface, but there are others (Save/Don't Save/Cancel, which would have been a better example by far) -- but you're right, I think the UI sucks. OK and Cancel is plenty for users, adding the Apply button is just too confusing.
@Will -- that's a very easy one to mess up when you're not faced with it on a daily basis. :-)
You stated that the Windows interface should be "Yes/No/Cancel" instead of "Save/Don't Save/Cancel", but I've seen some Windows apps using the latter (but with "Discard" in lieu of "Don't Save". What do the Windows guidelines say?
To be honest, there's no guideline for it -- it's just a general practice. It stems from the fact that the MessageBox Win32 API has a Yes/No/Cancel option, and to do one that uses Save/Don't Save/Cancel you'd have to design your own dialog. And it's almost always better to use the system's dialogs instead of your own since you get more for free (such as accessibility features, free localization of the button captions, a common user experience, etc).
I see--makes sense. But even if we specify Yes/No/Cancel as the button captions in RB for a MessageDialog, we don't get accessibility, free localization, and common user experience entirely, do we? Since RB must create the dialog from scratch.
We could use the optional MsgBox parameters, but you've said that's for debugging only and messes up the event loop.
Correct -- MessageDialogs are always RB-defined, and many times, and MsgBox can be as well.
You can use MsgBox with the optional parameters for some things if you'd like. It's perfectly legit on Windows. What you're *not* supposed to use it for is debugging since it changes the state of your application (instead, use System.DebugLog).