|
Evaluation
|
We need to improve setComponentZOrder() not not remove peer in the described situation.
This will make lw&hw mixing even closer :)
Posted Date : 2007-05-03 07:18:01.0
The easiest way to get the expected results is to modify the isRemoveNotifyNeeded() method in order to allow skipping of removeNotify() for any LW component. The current logic is:
if (comp.isLightweight()) {
if (comp instanceof Container) {
return ((Container)comp).hasHeavyweightDescendants();
} else {
return false;
}
}
The line that returns the result of the hasHWDesc() method could simply be modified to return false in any case. Nothing bad was observed when using this approach. Yet.
Though we might want to extend the logic in order to handle LW container containing HW children just the same way as regular HW components are handled.
Posted Date : 2007-07-27 12:42:22.0
The suggested fix successfully fixes the problem. Actually there's only one case left: the peer gets destroyed when the user minimizes the JInternalFrame. I'm in doubt whether this case should be fixed with this CR or be fixed at all.
Posted Date : 2007-08-01 13:39:58.0
The final idea of the fix is as follows. setComponentZOrder() actually verifies the return value of the isRemoveNotifyNeeded(Component comp, Container oldContainer, Container newContainer) to check whether it's necessary to remove the peer of the component. Thefore it is the isRemoveNotifyNeeded() method that should be fixed.
Our implementation of the method does some common checks:
1. If the oldContainer is null or the component has no peer curretnly, there's no need to remove the peer.
2. If the newContainer doesn't have a peer, we need to remove the peer from the component.
As the second step this method separates handling of LW and HW components.
1. If the component is LW:
a) If it's a Container, then return the result of the hasHeavyweightDescendants() method. That means that the peer gets destroyed if the LW container has any HW descendants.
b) Otherwise, simply return flase. The peer should not be destroyed if this is a "simple" LW.
2. If the component is HW:
At first, we retrieve the nearest heavyweight containers of both the oldContainer and the newContainer.
a) If the nearest HW containers are the same, we return the result of the !newHWContainer.isRestackSupported(). I.e. if the 'restack' operation is supported, there's no need to remove the peer.
b) If the HW containers differ: we return the result of the !comp.peer.isReparentSupported(), i.e. we check whether the component may safely be reparented.
The problem described at this CR actually happens at the step 1. In other words, we should handle a LW container having HW descendants just the same way as a regular HW component (just like, say, the HW/LW mixing code assumes, see CR 4811096 for more information).
The proposed fix changes the handling at the second step in the following way:
1. If the component is LW:
If it's not a Container or contains no HW descendants, the method returns false, meaning there's no need to destroy the peer. Otherwise proceed to the step 2.
2. If this point is reached, the component is either a regular HW, or a LW container with HW descendants. The handling of this case is performed in the old way.
This successfully fixes the problem described at the Description. However, there's one concern left: we cannot be sure that it's correct to query the peer of a LW component about whether the "reparent" operation is supported as it happens at step 2-b). It seems that the support of the "reparent" operation should solely be the responsibility of the container (either the old one, or the new one, or even both). Only the operation itself should slightly depend on the kind of the component (we should either reparent the component itself if it's a HW, or should recursevely reparent all the HW descendants of the LW container we're currently reparenting).
Posted Date : 2007-08-07 10:14:07.0
|