Your application will be with you momentarily

February 16th, 2010 | 16 Comments »

Programming user interfaces has many challenges. Fetching the data from remote service, populating the UI controls, tracking user input against the predefined set of validation rules, persisting the data back to the server, handling transitions between different application screens, supporting offline mode, handling error cases in the communication layer. All of these are just part of our daily programming tasks. While all of these relate directly to what the end user sees on the screen, there is a small subset that greatly affects the overall user experience.

The main two items in this subset are pixel perfection and application responsiveness. It is important to remember that the end user does not care about all of the wonderful underlying layers that take up a larger part of our day. As bad as analogies usually are, i would compare it to the vast majority of the drivers. I personally do not care how many people have worked on the specific model, how intricate are the internals of the engine and how many technical challenges had to be overcome during the development and testing. All i care about is that when i turn the key, the engine starts, when i turn the wheel / press the brake / turn on the AC, it responds correctly and immediately, and that it feels good to be sitting behind the wheel or in the passenger seat.

It is thus rather unfortunate that a lot of user interfaces are not implemented with these two main goals in mind. It would seem that programmers would rather enjoy letting the implementation complexity leaking into the UI layer – if it was hard to develop, it should at least look like that on the screen. There are multiple factors contributing to this. The farther you are from the target audience, the less you are able to judge the usability of the application, especially when you are immersed in its internals for long periods of time. When you operate at the level of data objects (with perhaps direct mapping to the optimized backend data storage), the users don’t. They see your application as a means to accomplish the specific flow that they have in mind. If you fail to crystallize the flows during the design stage, your users will see your application as unintuitive, time wasting and counter productive.

And even if you get the flows right – at least for your target audience – there is the issue of responsiveness. Imagine the following scenario. You’re in the kitchen, and want to heat that last slice of pizza from yesterday’s party. You put it in the microwave, press the button – and the entire kitchen freezes for one whole minute. You can look at the fridge, but you cannot open it. You remember that you pressed the microwave button, but the tray is not spinning and it does not make any noises. You step in your living room, and are not able to get back into the kitchen.

This is what happens when your code does I/O, database or any network operation on the UI thread. It does not really matter how small the operation is or how fast your machine is. If it locks the UI for even a fraction of a second, people will notice. You can say – well, this operation here that I’m doing is persisting the current screen state to the backend, so i cannot really let the user interact with the UI while i’m doing that. Or maybe it’s just not that important and the user can wait. Or maybe it’s just going to add to the development complexity of the UI layer.

Doing this right is hard. First, you need to understand what is right – and that varies depending on the specific scenario. Do you prevent the user from doing anything with the application? Or maybe let him browse some subparts of the screen while you’re running this long operation? Or maybe even let him change information elsewhere in the application? Do you show the progress of that operation? Do you allow canceling the operation? Do you allow creating dependencies between executing / scheduled operations?

And after you know what you want to do, the next step is actually implementing and testing it. At this point the word “multi-threading” will be your friend and nemesis. I cannot say that we are at a stage where doing multi-threading in UI is easy (although i certainly am not an expert in all the modern UI toolkits and libraries). It is certainly easier than it was a few years ago, but it’s still a mess. The words of Graham Hamilton from five years ago are still true today:

I believe you can program successfully with multi-threaded GUI toolkits if the toolkit is very carefully designed; if the toolkit exposes its locking methodology in gory detail; if you are very smart, very careful, and have a global understanding of the whole structure of the toolkit. If you get one of these things slightly wrong, things will mostly work, but you will get occasional hangs (due to deadlocks) or glitches (due to races). This multithreaded approach works best for people who have been intimately involved in the design of the toolkit.

Unfortunately I don’t think this set of characteristics scale to widespread commercial use. What you tend to end up with is normal smart programmers building apps that don’t quite work reliably for reasons that are not at all obvious. So the authors get very disgruntled and frustrated and use bad words on the poor innocent toolkit. (Like me when I first started using AWT. Sorry!)

I believe that any help we can get in writing correct multi-threaded code that deals with UI is welcome. This is why i continue enforcing the Swing threading rules in Substance. It is by far the biggest source of complaints ever since it was introduced about a year and a half ago in version 5.0. The original blog entry on the subject implied – rather unfortunately – that i wanted to make my job easier and not handle bugs that originate from UI threading violations. Allow me to clarify my position on the subject and repost my reply from one of Substance forum postings:

I do not intend to provide such API (disabling the threading checks) in the core Substance library. Once such an API exists, people will have little to no incentive to make their code more robust and compliant with the toolkit threading rules.

If the code you control violates the threading rules – and you *know* it – you should fix it. Does not matter if you’re using Substance or not.

If the code you do not control violates the threading rules – either put pressure on the respective developers to change it or stop using it.

It may be painful in the short term. I may lose potential users because of this. It may cause internal forks of the code base. I am aware of these issues. In my personal view, all of them are dwarfed by what is right in the long term interests of both Substance itself and Swing applications in general.

The followup posting by Adam Armistead provides a deeper look into why this matters – and i thank Adam for allowing me to repost it here:

I would just like to say I strongly support Kirill in this and I am very glad to see he is sticking to his guns on this. I feel that it is too easy to violate threading rules in UI code and that I run across entirely too much code that does. I feel that if someone doesn’t strictly enforce these threading rules then there is not enough pressure on developers to fix the problem. If there was enough pressure I wouldn’t see so damn much of this.

As for it causing problems due to 3rd party dependencies having bad UI code, there are tons of solutions for this. I have personally put pressure on developers to fix problems, submitted patches to open source projects to fix code myself, extended classes, forked codebases, used bytecode manipulation, proxy classes, and Spring and AspectJ method injection, method replacement, as well as adding before/after/around advice to methods. I have yet to encounter a situation where a little work or ingenuity on my part has not been able to overcome someone else’s crappy code. In the worst cases I have written my own libraries that don’t suck, but in most cases I didn’t have to go to this extreme.

I sincerely believe that having substance crash my applications has made MY applications as well as those I interact with better. I have seen people in comment sections in blog posts and on forums advise using Substance in order to assist developers in finding UI threading violations. I have fixed open source code and seen others do the same because Substance throws this exception. I can also say, I know may coders that if they had the choice to just log it, they would do so and just say, “aww, I’m busy, I’ll fix it later.” and likely never get around to it…

They’re always busy, so when one thing gets done there’s always half a dozen more that pop up. If it’s not crashing their code its not critical to fix. Besides, its too easy to violate these rules. I’m a Swing developer and I know the rules, and sometimes when I’m hammering out features I slip up and do things incorrectly. Personally, I am glad Substance catches it so I can fix it now.

What are the chances that Swing will start enforcing threading rules in the core? Zero. Between focusing all the client-side resources on JavaFX and sticking to binary compatibility (even when any reasonably sized Swing application needs code changes when it is ported between different JDKs), there is no chance. However, as SWT and Android show, a toolkit / library that aggressively enforces its own threading rules from the very beginning is not such a bad thing. And who knows, your users may even thank you for it.


16 Comments on “Your application will be with you momentarily”

  1. 1 tbee said at 10:40 pm on February 16th, 2010:

    Enforcing Swing threading rules is an absolute must for the base quality of the code. As soon as you start letting that foundation slip, any application will tumble over some time in the future.

  2. 2 Kali said at 11:24 pm on February 16th, 2010:

    Oh my, how I love this post.

    K.

  3. 3 fbeullens said at 1:42 am on February 17th, 2010:

    Couldn’t agree more!
    I Absolutely HATE UI’s that freeze up when you’ve done something, so this is something one should always try to avoid.
    If it realy can’t be avoided (you never know) at least show the user your appliction is doing something!
    As always, Kirill, a great article.

  4. 4 Aloys Oberthuer said at 1:45 am on February 17th, 2010:

    I am absolutely with you in that. I was glad you introduced that feature into Substance and the only thing that bothers me is that you did what should have been done by the ones who created the toolkit.

  5. 5 Adam said at 10:00 am on February 17th, 2010:

    This is why Substance is not just another look and feel to me, but an integral part of my applications and development toolkit. Great article Kirill.

  6. 6 brian_fr said at 10:08 am on February 17th, 2010:

    I create a lot of swing component in a non UI thread.

    Then only after the construction and initialization is done, the graphics are displayed. According to the swing team it is ok to do this a long as components are not displayable.

    The result is that loading several very huge frames do not freeze the application… It displays a loading panel instead and replace it when the thread has finish to construct the UI part.

    But because of this i could not use substance as it check the EDT violation even if the component is not displayed.

    My apologies if i misunderstood how substance work but it seems than I can’t do that in substance.

  7. 7 Kirill Grouchnikov said at 11:16 am on February 17th, 2010:

    Brian,

    If you are referring to the 2000 article on the Swing threading, it is wrong – as explained in this article from 2007.

    Thanks
    Kirill

  8. 8 João E. Rocha said at 2:26 pm on February 17th, 2010:

    I always tried to follow the threading rules of Swing in my applications, but the first time I tried Substance 5+ with it, i got a LOT of EDT violations that I never expected.
    The fact is that it is too hard to build up UIs with threading issues in mind all the time, and ocasionally you WILL end up doing something you should not do, and I’m glad that Substance does warn me about these violations that the core Swing/AWT should ban from the beginning.

    And there is nothing better than SwingWorkers + JXLayer’s LockableUI to perform lenghty tasks providing an elegant feedback to endusers without violating EDT threading rules! =)

  9. 9 brian_fr said at 2:35 am on February 18th, 2010:

    Thanks, I think the problem is more on the UI part that should not decide to run in EDT or not. It should always run in the calling thread.

    “…the initialization of the Swing UI could trigger something to run on the event-dispatch thread afterward, because the component/UI expects to run everything on the event-dispatch thread…”

    However, I use this trick for a while (multithreading UI construction) and it allows smooth loading of the UI. Create a frame with a load of components can be really slow during JVM startup (up to 10 seconds). So imagine a dozen of window that loads simultaneously… If you are concerned by user experience (and i know this is the case !) you can not accept to freeze the UI, even for one second.

  10. 10 Aleix said at 3:10 am on February 19th, 2010:

    Hi kirill, thanks a lot for your hard work, however I got a problem with EDT and the 2007 rule that afects non showing components:
    I got a Waiting message that is showing when I click a menu option and before displaying an internalFrame, this situation compains about EDT rule, BUT if I obey EDT everybody nows that repaintManager of internalFrames are UGLY and application gets unresponsive. I don’t know any way to solve this situation..
    Anybody knows ? (loading models asyncronoulsy is not an option for me as asynchronous code is messy to read and mantain). I’m using Foxtrot synchronous threeading solution.

    Thanks again kirill and all Client java guys !

  11. 11 Gili said at 6:07 am on February 19th, 2010:

    Something’s got to change.

    Either Sun needs to open-source Swing (not going to happen) or someone needs to build a Swing-replacement that *is* open-sourced and sync it into the JDK on a regular basis.

    Desktop Java will not happen until we build our applications on top of a live API that is being continuously improved and refactored. I would love to keep on developing on top of Swing but it’s essentially dead. Not “stable”. Dead. This needs to change.

  12. 12 Tony said at 8:25 am on February 19th, 2010:

    Hi Kirill,
    What you say is true but only happens over time. Engineering Leads and others get pressed for time then what you say gets thrown out of the window.
    Engineering a fast usable app has to be a passion of all involved otherwise it never happens at least not the first time or even the second. Your company and engineers have to be behind it all the way.

    I have used all sorts of skins over the years and other inovations and no one gets it right the first time. It takes determination and heart.

    Best Regards,
    Tony Anecito
    Founder,
    MyUniPortal
    http://www.myuniportal.com

  13. 13 Aleix said at 11:07 am on February 20th, 2010:

    @Gili:

    You are right, I’m sad coz I love swing programming you can do everything you need with it compared to .net, QT and GTK ! Dou you know about apache pivot http://pivot.apache.org it looks promising, I’ve been playing a bit with it and the only complain I have is not having a GUI designer like Netbeans matisse ! (I’m not a web guy so I don’t feel confortable with this html,javascript,xml messy world :-) )

  14. 14 paulo said at 5:02 pm on February 22nd, 2010:

    A question. I’ve been using http://code.google.com/p/gtkjfilechooser/ in linux for some time. as it is much nicer than the normal swing jfilechooser (if a little slow). I would like to try it on other lookandfeels than gtk (that is slow also, just a btw).

    However it looks like substance specifically enforces not replacing the UI layer. Any way for me to get this without suffering?

    I’m that weird guy that is replacing the look and feel at runtime (never did find that list error too. It was only in the windows laf i think, since i’ve not seen it since changing to linux)

  15. 15 Kirill Grouchnikov said at 5:08 pm on February 22nd, 2010:

    Paulo, this question should be directed to the project forums and mailing lists, since it has not much to do with this specific entry.

    Thanks, Kirill

  16. 16 paulo said at 5:10 pm on February 22nd, 2010:

    Also it’s not hard at all to make a ui without threading violations.
    The strategy i use, is to start the application on the EDT, and only go out of it for long running tasks. Those tasks follow the model of rendevous.

    For example i have a custom list (at http://code.google.com/p/bookjar-utils/)
    I simplified (limited) the interface, and disallowed a list rendering (for my custom ImageList), but exported a cellrenderer like interface. Only instead of returning a image for the component, i “requested” it and had a function to “return” a image (to the EDT). Basically a not hidden mediatracker for a little scability.

    Been using it to display up to 2000 images (only 20 at one time ofcourse).
    The api suffers a little, but i think that concurrency can’t be transparent. People selling you that except a the very most simple level (unrolling for loops) are full of BS.