In my design I have a class that can "freeze" the EDT by calling a blocking method inside it. This is a desired behavior: I want the class to freeze the EDT with some timeout and then display a progress monitor. This part is no problem.
The class features a "release" method which can be called from any thread, and while the EDT is freezing, it may be called, which indicates that the EDT should stop freezing. The proper way to do this, of course, would be to interrupt the EDT. Again, not a problem.
The problem is: What if some other class is also dependent on interrupting the EDT and some behavior? Is there a mechanism with which I can check "how many times" a thread has been interrupted, and interrupt it again if needed? Or should I reconsider my design?
An answer I would love to hear would be "If the EDT is running a custom piece of code, no class ignorant of that code should try to interrupt the EDT as it cannot know what will happen." Is this the case?
freezing the EDT would seem like a very bad design. it will most likely make the ui look terrible on some platforms as repaint events will probably not be processed (so if a window covers the ui and then uncovers, it will be left blank). i would strongly advise rethinking your design. if you provide some more context, maybe someone could give you some pointers on better design.
as to your "specific" question, if you want a targeted hang/restart, it's best to use some shared state and wait/notify, not just hang until interrupted. as you've already realized, being interrupted doesn't necessarily mean that the desired state has been achieved.
I will close with a flip-flop of your last statement: no class ignorant of the internal details of the EDT and how it is managed should be intentionally hanging that thread.
The context is the following: in my application(s) tasks will often be run in a thread pool. Those tasks often need to ensure that nothing else happens in the GUI while they are working, however. For instance, you can't cut/paste while saving a document, for instance.
I have seen a couple of applications do it this way: Freeze the GUI for a second or so, or less if the task completes faster, and then display a progress monitor. This way, particularly short tasks that are run in a separate thread still don't pop up a dialog that only stays for a fraction of a second. I've heard it worries users if a dialog pops up for a fraction of a second, which they couldn't see in detail, and then just disappeared.
The progress monitor does that same thing as the freezing: it's modal so it prevents the users from interacting with the GUI while it is open.
An alternative would be to do a mass-disable-all-gui-components each time I want to disable the GUI like this. There are some disadvantages to this approach though. For one, very short tasks would cause the GUI to "flash" to gray and might also cause the same kind of confusion. Second, it might be difficult to implement a thorough design where all components are actually disabled. Third, if the GUI is very large, it might also take a lot of time in itself.
Any ideas on alternative designs, or improvements on these designs, or other thoughts are very welcome. :)
Here's the code for my current design, note that it doesn't compile as I have changed the design lots, but it might give an idea: http://pastebin.com/cBPx0yRN
It seems that glass panes can do what I want, but for my application I would also have to block all dialogs.
Is there another way to do this, or are glass panes the way to go? If so, what would be a good way to, given a JFrame, determine all dialogs/top-level containers belonging to it? And what about key events - mnemonics, accelerators, will those be problematic?
If there's another way to consume all Swing input events for a while, that would be great.
You would only have to worry about non-modal dialogs since modal dialogs by definition prevent interaction with parents. I don't know of a way to get information about child dialogs from a parent but it can't be too difficult to keep a collection of active dialogs in your main application.
P.S. I try to avoid dialogs since it is too easy for them to get lost on the desktop.