This is going to be a little complicated,
but I think it will handle your problems.
First, I presuming that no matter how
many changes are made to the children, only one pack is required for all
of the changes. That way we can do one pack only at the end of the transaction.
But first, let me see if I understand
your structure (I'm using what I'm guessing are the ULC names, I don't
know them exactly):
ULC Beans
Swing Visuals
ComponentManagers (one on client, one
on vm)
If this is correct, then after making
a bunch of different changes to the ULCButton, ULCPanel, and ULCShell,
then one ULCShell.pack() is needed to get all of this propagated over to
the swing visuals.
The way this can be done in an automated
way is to use a ComponentManagerExtension on ULCShell. We'll start from
the remote vm side and work our way back to the IDE side, explaining the
hooks as we go.
Take a look at jfc.vm.WindowManagerExtension.
I explain later how this gets hooked in, right now I'll just explain what
it does.
protected
void invalidated() {
if (packOnChange)
((Window)
getComponent()).pack();
}
When this WindowManagerExtension is
hooked in correctly for the top-level window (JFrame is an example of a
Window), this method will be called once at the end of the transaction.
It indicates that the window, or one of its children or grandchildren has
been invalidated and it is about to be validated. After this call is returned
from, the validation will occur. Validation in awt means to call validate()
on the JFrame. You can do something similar, but instead of calling pack
on the JFrame, you would call pack on the ULCShell. After the validate()
is done, the images are then requested.
This invalidate call is called once
at the end of every transaction that had children of the JFrame invalidated
(i.e. property settings were made). This is automatic on the vm side. The
process is kicked off by doing the revalidateBeanProxy() call on the IDE
side when a property is applied or canceled, or during initialization.
The WindowManagerExtension is code that
you hook into the ComponentManager. By registering with the ComponentManager
the extension can be notified of certain events, such as the invalidated
event. So when done your structure will look like this:
ULC Beans
Swing Visuals
ComponentManagers (one on client, one
on vm)
Now since the extension doesn't know
the ULCShell (it knows the JFrame, not the ULCShell), you need to tell
it the shell, so this will be the basic contents of your ULCShellManagerExtension:
public class ULCShellManagerExtension
extends ComponentManager.ComponentManagerExtension {
protected
ULCShell ulcShell;
public
void setULCShell(ULCShell ulcShell) {
this.ulcShell = ulcShell;
}
Now take a look at jfc.WindowManagerExtension
to see how it hooks in on the IDE side. The method getExtensionClassname
is used to return the name of the manager extension on the vm side. You
would return the vm.ULCShellManagerExtension as the classname. primGetExtensionProxy/primSetExtensionProxy
will be implemented the same for you as it is here.
Replace the packWindowOnValidate
with setULCShell(IProxy ulcShell, IExpression _expression_). And it
should call setULCShell on the vm WindowManagerProxy, passing in the IProxy
for the ulcShell to the IExpression. This will then setup the vm managerExtension
to know the ULCShell to pack.
Now we have both the IDE and VM UCLShellManagerExtensions
hooked together. We now look at the WindowProxyAdapter to see how it all
gets started. Here is the first hook:
protected
ComponentManager createComponentManager() {
ComponentManager cm = super.createComponentManager();
windowManager = new WindowManagerExtension();
cm.addComponentExtension(windowManager, null);
return cm;
}
This hooks in the ide WindowManagerExtension
into the window's ide ComponentManager. This will automatically hook in
the vm's manager extension when necessary. But we still need to give the
manager extension the proxy for the ULCShell. This is done in the primInstantiateBeanProxy
method. Here's an example that could be used for ULCShellProxyAdapter:
And that is it. The extension is now
hooked in. Whenever any child of the ULCShell has a propery applied, it
calls the revalidateBeanProxy() method. This will then tell the component
manager on the vm that the visual is invalid. It also tells all of the
parents, up to the JFrame at the top, that they are invalid. Then at the
end of the transaction, the component manager for the JFrame is told that
it is about to be validated. This will then call the ULCShellManagerExtension.invalidated()
method, which will cause your ULCShell to be packed. Thereby moving all
of the settings from the ULCBeans to the Swing visuals. After this the
validate() is called on the JFrame, and then the images are requested.