|
What do you think about this API enhancement and implementation? I would like to add this method to class ActionManager: ActionManager.java /** * Executes the specified action in the thread of the caller (must be the Swing Event Dispatch thread, EDT). * If the action is backed by an org.jdesktop.application.Task, then it will be executed asynchronously * on the EDT, this method will return immediately. If there's a org.jdesktop.application.Task.BlockingScope * specified for the Task, then the UI will be blocked appropriately. * * @param action the Action to be executed * @param source the UI component which acts as the source for the execution */ public void executeAction(javax.swing.Action action, java.awt.Component source) { action.actionPerformed(new ActionEvent (source, ActionEvent.ACTION_PERFORMED, action.toString())); } The implementation is the workaround I'm using right now, but it works fine. Maybe someone has a better idea... Usage example for loading the application data (asynchronous Taks), the UI will be blocked meanwhile: Foo.java appContext.getActionManager().executeAction(
actionMap.get(LOAD_ACTION), frame);
I really don't think this variant does make much sense. You still need a lot of code to retrieve/create action, to get ActionManager, etc. It will work only for a few cases. The main reason that it's not static is simple: so it's easily mockable in unit tests, also without complex bytecode-manipulation frameworks. The ApplicationContext instance is available everywhere, at least in the Controller class of the application which will probably use this method (the same for the ActionMap to get the action to be started). Sorry, I don't understand why this is too much code. OK, the static variant would be shorter, but I've described the disadvantages. And the action to be started needs to be passed. We could also add such a method to the Action subclass in the (B)SAF, but that's not the best place. And we often need to cast, because the ActionMap returns javax.swing.Action instances. Do you have an alternative solution? Bye, Stefan maybe we should consider using this method as a shortcut SwingUtilities.notifyAction(Action action, KeyStroke ks, KeyEvent event, Object sender, int modifiers) The method is static by default, which we can keep that way, and it will generate the ActionCommand for the created ActionEvent in a proper way. What would be the benefit of SwingUtilities.notifyAction(...) compared to my workaround proposal above? Stefan Well I think it's quite similar, except than that this one is static and in the SwingUtilities. Maybe it's better to reuse existing swing functionality instead of creating new things. It's actually a shorthand for action.actionPerformed(new ActionEvent(sender, where we could create a convencience static method in ActionManager that calls this one with default argument. Actions don't necessarily need to be retrieved from an ActionMap. They can eg also be injected by a framework or so. I use aspectj eg to weave in some common application functionality. So declaring it static is ok for me. Yes, such a convencience method in ActionManager is what I'm looking for, see my proposal above. It doesn't matter for me which way the implementation works, maybe the SwingUtilities method is better. But I can't see any advantages... Stefan I think it would also be useful to give this 'utility' method the ability to set selected state for the action. Best way to implement this is to provide an overloaded version that allows you to pass a boolean that sets the selected property on the action. Also, we should not forget to check for enabled state before executing the action itself. |
|||||||||||||||||||||||||||||||||||||||||
Illya: The source of the event varies.