I remained silent on the prefix all your member variables with m_ thing, because it's a matter of taste. I find it ugly and mostly useless, other people think it's important, but because it doesn't affect anything outside the class, it's largely irrelevant.
I must, however, disagree with prefix your Interface names with I (e.g. IWindowListener).
The standard argument against such a practice is, again, that it breaks encapsulation: "I am dealing with a type, I don't care if it's an interface or a concrete type."
Well, you should, because they are not equivalent. For example, you cannot "new" an interface, and it's the kind of information I would like to have right off the bat, not when I do my first attempt at compiling and realize that now, I need to find a way to find a concrete implementation of the said interface.
Firstly, I don't know about you, but I never have to wait until compilation time before I discover I can't instantiate an object. Why not? Because there aren't any classes called WorkspaceWithAConstructorThatTakesAString. If I find a class, any class I don't know how to instantiate, I have to either open its definition in my IDE, or read the Javadoc. The point is already moot, the extra I wouldn't save me any time as I would still have to be browsing its documentation to find the list of implementors.
Secondly, an object is only ever instantiated once, but can be used many times after that. This is especially true of Interfaces, which are generally instantiated in one place that knows all about their interface-ness, and then passed around anonymously to lots of other places that don't have to know (think of Listeners, States/Strategies, Comparators).
If you follow the IFoo convention, and you want to change a class into an Interface, you have to change all the places it is instantiated and all the places it is used (in method arguments and declarations). If you don't follow the IFoo convention, you just have to change the instantiations.
(Update) Cedric points out that if you have a good modern IDE with refactoring support, this isn't really a major issue. Considering my argument revolves around the capabilities of IDEs, I guess I'll have to concede that point. :)
Thirdly, and this is my problem with Hungarian notation in general, it's hard to read. Our eyes don't read words letter by letter, we read by pattern-matching the shapes of words, we only fall back on letter-by-letter in the worst case of not knowing a word at all. IApplication takes longer to read than Application. The extra I at the start changes the shape of the word, and your brain takes longer to parse it.
I prefer to have code that is easy to read in the general case, and tools that will tell me the supporting information if and when I need it. Hungarian notation is an artifact of a time when the tools weren't good enough to give us this information in any way but by throwing it all in our face at once. Now we have colour-coding, tool-tips and one-keypress navigation available to us, Hungarian notation is a horrendously clumsy anachronism. The information should be available, but not obscuring the code. Which is why I don't use Hungarian notation, but I do use a good, modern IDE.