aloleary
|
Posted: March 11, 2010 15:30 by aloleary
|
|
Hello, When I specify Block for a Task - the default blocking dialog is appearing over the button on which the action is performed. I would like it to center in the middle of my window/applciation - any way to do this ? Thanks -A- |
InputBlocker
Replies: 2 - Last Post: March 11, 2010 23:26
by: aloleary
by: aloleary
showing 1 - 3 of 3
Eric Heumann
|
Posted: March 11, 2010 18:06 by Eric Heumann
|
|
As far as I can tell, no. Not easily anyway. The Task input blocking part of SAF (and thus BSAF) needs a lot of work. It seems like it was part of an idea that was never fully completed. Many people argue that the original SAF (i.e. SAF 1.03 from the JSR-296 Java.net project) was released prematurely, and the Task input blocking mechanism surely supports that argument. The folks here at BSAF have done a good job of gutting many bugs, but the Task input blocking issue is more than a bug... it's an incomplete design. Here are some issues to consider: 1) The Task.InputBlocker architecture in general. Task.InputBlocker is a public static abstract nested class in the Task class. Something about that doesn't sit right with me. DefaultInputBlocker (which is the only implementation of InputBlocker) on the other hand, is a top level class. It's also final, so you can't create your own subclasses of it. 2) Your issue with DefaultInputBlocker. When the JDialog component is created, it's done so via final JDialog dialog = optionPane.createDialog(dialogOwner, dialogTitle); which looks fine at first, but if you look a few lines up, dialogOwner is actually the button that fired the event. This is why the dialog is placed over the button... because a dialog is centered over its parent by default, which is the button. One would think this line could be fixed by changing it to final JDialog dialog = optionPane.createDialog(SwingUtilities.getWindowAncestor(dialogOwner), dialogTitle); which will center the dialog over the button's window ancestor, but there's also a problem with this code as well, which I will explain in my next point... 3) Bug 77 documents how the DefaultInputBlocker doesn't acutally block input until the dialog appears. By adding a line to your Task or Action's resource file, you can tell the dialog to delay appearing by some number of milliseconds after the Task has started. If this value is significant, it gives the user ample time to click buttons, etc, on the window before the blocking dialog appears. The original designer intended to resolve this issue by disabling the window's menu bar and placing a glass pane over the rest of it which would consume, and thus block, all input. If your button is in the window, this works. However, if your button is a JMenuItem in a menu, this doesn't work, because recursively calling getParent on a JMenuItem will never lead you to the window. In BASF-77 I explain that this modification is required to the Window finding loop:
Component root = (Component) getTarget();
while (root != null) {
if (root instanceof RootPaneContainer) {
rpc = (RootPaneContainer) root;
break;
} else if (root instanceof JPopupMenu && root.getParent() == null) {
root = ((JPopupMenu) root).getInvoker();
} else {
root = root.getParent();
}
}
This same fix is needed in the code that creates the dialog in my previous point, otherwise the the dialog will have null as a parent and will appear centered on the first display (which is very bad if the user has two displays or more and the window is on one of the other displays). 4) The dialog is packed and sized with the default message (which I think is something like "Please wait..."). After this, your custom messages are applied. If your message is anything longer than "Please wait...", you'll only see part of it, because the dialog is never resized when larger messages are applied. The dialog should either be configured to resize when a larger message comes along, or there should somehow be an option to specify a size for the dialog. These are the big issues I've found thus far. I'm sure there are more. 2 and 3 seem like simple fixes. 4 may take some more thinking. 1 is an issue that will need some discussion, and should probably be addressed for a future version, since it will require switching up a good deal of code. I hope this sheds some light on any funny business you've been noticing with the input blocking dialog. Cheers, Eric |
aloleary
|
Posted: March 11, 2010 23:26 by aloleary
|
|
Thanks for that - I spent a bit time digging through the code and saw the mess you've described around this area... For now what I have done is taken the SwingWorkerCompletionWaiter approach as described here: http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html#get%28%29 And simply added this to my task using: myTask.addPropertyChangeListener(new SwingWorkerCompletionWaiter(..... I need to see if this approach has some of the same edge case issues that the InputBlocker has but it seems to work pretty well.. |
Replies: 2 - Last Post: March 11, 2010 23:26
by: aloleary
by: aloleary







