The ApplicationCommandManager needs to know where to start looking for a suitable target when a command is invoked. By default, it will check for one that has been set via setFirstCommandTarget(), and if one has not been specified, it will call findDefaultComponentTarget(), which starts with what currently has focus.
When it looks at the focused component, it will try to find the first component which implements ApplicationCommandTarget (checking that one before each of its ancestors). If it belongs to a TopLevelWindow, that is obviously where the search will stop (as it’s the top level - there are no components above it). If the target you expect to receive the command lives inside a different TopLevelWindow to the currently focused component, it will never be found by this default behaviour; the search will be taking place in an entirely separate tree of objects.
So, you need to customise this behaviour according to your needs. The first thing to do is decide on how you’d want this search to be started; if you just want to have a fixed starting point (or one which you can change manually when necessary), you can call setFirstCommandTarget(). If you want it to use some kind of logic to decide on where to start for each case, you can override getFirstCommandTarget(), so you can leave it to sort itself out as needed. One simple approach would be to give your manager an array of CommandIDs which should always go to one particular target; if that array contains the current CommandID you’d return that target, otherwise return findDefaultComponentTarget().
Remember that you also must implement getNextCommandTarget() for each target. The stuff above covers the start of the search for a target, whereas this controls how the search progresses from one target to the next. This is therefore another place where you can influence a command’s journey to its target. The ‘default’ thing you’d normally do (as suggested by the docs) is return findFirstTargetParentComponent(). You might want to provide a means of jumping from a target in one window to a suitable one in another. You’d have to be careful that all commands are handled somewhere though if there’s a chance the targets might direct themselves into an infinite loop! I guess you could create some kind of TargetTraverser object which (after getting reset in getFirstCommandTarget()) keeps track of which targets have been visited; each target could then be written to use that traverser to return the next target. That’s probably only worth bothering with if you have an extremely complicated setup though, and if it’s that complex, you’d probably be better off redesigning your program!
TBH, I think just choosing between a specific target and the default focus search based on command ID is probably the easiest approach to take (going from the information you have given).