Merge
This commit is contained in:
commit
6898039064
@ -6492,7 +6492,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
// will need some help.
|
||||
Container parent = this.parent;
|
||||
if (parent != null && parent.peer instanceof LightweightPeer) {
|
||||
nativeInLightFixer = new NativeInLightFixer();
|
||||
relocateComponent();
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
@ -6603,10 +6603,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
}
|
||||
}
|
||||
|
||||
if (nativeInLightFixer != null) {
|
||||
nativeInLightFixer.uninstall();
|
||||
}
|
||||
|
||||
ComponentPeer p = peer;
|
||||
if (p != null) {
|
||||
boolean isLightweight = isLightweight();
|
||||
@ -8514,8 +8510,6 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
setComponentOrientation(orientation);
|
||||
}
|
||||
|
||||
transient NativeInLightFixer nativeInLightFixer;
|
||||
|
||||
/**
|
||||
* Checks that this component meets the prerequesites to be focus owner:
|
||||
* - it is enabled, visible, focusable
|
||||
@ -8541,188 +8535,25 @@ public abstract class Component implements ImageObserver, MenuContainer,
|
||||
}
|
||||
|
||||
/**
|
||||
* This odd class is to help out a native component that has been
|
||||
* embedded in a lightweight component. Moving lightweight
|
||||
* components around and changing their visibility is not seen
|
||||
* by the native window system. This is a feature for lightweights,
|
||||
* but a problem for native components that depend upon the
|
||||
* lightweights. An instance of this class listens to the lightweight
|
||||
* parents of an associated native component (the outer class).
|
||||
*
|
||||
* @author Timothy Prinzing
|
||||
* Fix the location of the HW component in a LW container hierarchy.
|
||||
*/
|
||||
final class NativeInLightFixer implements ComponentListener, ContainerListener {
|
||||
|
||||
NativeInLightFixer() {
|
||||
lightParents = new Vector();
|
||||
install(parent);
|
||||
}
|
||||
|
||||
void install(Container parent) {
|
||||
lightParents.clear();
|
||||
Container p = parent;
|
||||
boolean isLwParentsVisible = true;
|
||||
// stash a reference to the components that are being observed so that
|
||||
// we can reliably remove ourself as a listener later.
|
||||
for (; p.peer instanceof LightweightPeer; p = p.parent) {
|
||||
|
||||
// register listeners and stash a reference
|
||||
p.addComponentListener(this);
|
||||
p.addContainerListener(this);
|
||||
lightParents.addElement(p);
|
||||
isLwParentsVisible &= p.isVisible();
|
||||
final void relocateComponent() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer == null) {
|
||||
return;
|
||||
}
|
||||
// register with the native host (native parent of associated native)
|
||||
// to get notified if the top-level lightweight is removed.
|
||||
nativeHost = p;
|
||||
p.addContainerListener(this);
|
||||
|
||||
// kick start the fixup. Since the event isn't looked at
|
||||
// we can simulate movement notification.
|
||||
componentMoved(null);
|
||||
if (!isLwParentsVisible) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer != null) {
|
||||
peer.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void uninstall() {
|
||||
if (nativeHost != null) {
|
||||
removeReferences();
|
||||
}
|
||||
}
|
||||
|
||||
// --- ComponentListener -------------------------------------------
|
||||
|
||||
/**
|
||||
* Invoked when one of the lightweight parents has been resized.
|
||||
* This doesn't change the position of the native child so it
|
||||
* is ignored.
|
||||
*/
|
||||
public void componentResized(ComponentEvent e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when one of the lightweight parents has been moved.
|
||||
* The native peer must be told of the new position which is
|
||||
* relative to the native container that is hosting the
|
||||
* lightweight components.
|
||||
*/
|
||||
public void componentMoved(ComponentEvent e) {
|
||||
synchronized (getTreeLock()) {
|
||||
int nativeX = x;
|
||||
int nativeY = y;
|
||||
for(Component c = parent; (c != null) &&
|
||||
(c.peer instanceof LightweightPeer);
|
||||
c = c.parent) {
|
||||
|
||||
nativeX += c.x;
|
||||
nativeY += c.y;
|
||||
}
|
||||
if (peer != null) {
|
||||
peer.setBounds(nativeX, nativeY, width, height,
|
||||
ComponentPeer.SET_LOCATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a lightweight parent component has been
|
||||
* shown. The associated native component must also be
|
||||
* shown if it hasn't had an overriding hide done on it.
|
||||
*/
|
||||
public void componentShown(ComponentEvent e) {
|
||||
if (shouldShow()) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer != null) {
|
||||
peer.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when one of the lightweight parents become visible.
|
||||
* Returns true if component and all its lightweight
|
||||
* parents are visible.
|
||||
*/
|
||||
private boolean shouldShow() {
|
||||
boolean isLwParentsVisible = visible;
|
||||
for (int i = lightParents.size() - 1;
|
||||
i >= 0 && isLwParentsVisible;
|
||||
i--)
|
||||
int nativeX = x;
|
||||
int nativeY = y;
|
||||
for (Component cont = getContainer();
|
||||
cont != null && cont.isLightweight();
|
||||
cont = cont.getContainer())
|
||||
{
|
||||
isLwParentsVisible &=
|
||||
((Container) lightParents.elementAt(i)).isVisible();
|
||||
nativeX += cont.x;
|
||||
nativeY += cont.y;
|
||||
}
|
||||
return isLwParentsVisible;
|
||||
peer.setBounds(nativeX, nativeY, width, height,
|
||||
ComponentPeer.SET_LOCATION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when component has been hidden.
|
||||
*/
|
||||
public void componentHidden(ComponentEvent e) {
|
||||
if (visible) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (peer != null) {
|
||||
peer.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- ContainerListener ------------------------------------
|
||||
|
||||
/**
|
||||
* Invoked when a component has been added to a lightweight
|
||||
* parent. This doesn't effect the native component.
|
||||
*/
|
||||
public void componentAdded(ContainerEvent e) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked when a lightweight parent has been removed.
|
||||
* This means the services of this listener are no longer
|
||||
* required and it should remove all references (ie
|
||||
* registered listeners).
|
||||
*/
|
||||
public void componentRemoved(ContainerEvent e) {
|
||||
Component c = e.getChild();
|
||||
if (c == Component.this) {
|
||||
removeReferences();
|
||||
} else {
|
||||
int n = lightParents.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Container p = (Container) lightParents.elementAt(i);
|
||||
if (p == c) {
|
||||
removeReferences();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes references to this object so it can be
|
||||
* garbage collected.
|
||||
*/
|
||||
void removeReferences() {
|
||||
int n = lightParents.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
Container c = (Container) lightParents.elementAt(i);
|
||||
c.removeComponentListener(this);
|
||||
c.removeContainerListener(this);
|
||||
}
|
||||
nativeHost.removeContainerListener(this);
|
||||
lightParents.clear();
|
||||
nativeHost = null;
|
||||
}
|
||||
|
||||
Vector lightParents;
|
||||
Container nativeHost;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -832,16 +832,8 @@ public class Container extends Component {
|
||||
}
|
||||
if (!comp.isLightweight() && isLightweight()) {
|
||||
// If component is heavyweight and one of the containers is lightweight
|
||||
// some NativeInLightFixer activity should be performed
|
||||
if (!curParent.isLightweight()) {
|
||||
// Moving from heavyweight container to lightweight container - should create NativeInLightFixer
|
||||
// since addNotify does this
|
||||
comp.nativeInLightFixer = new NativeInLightFixer();
|
||||
} else {
|
||||
// Component already has NativeInLightFixer - just reinstall it
|
||||
// because hierarchy changed and he needs to rebuild list of parents to listen.
|
||||
comp.nativeInLightFixer.install(this);
|
||||
}
|
||||
// the location of the component should be fixed.
|
||||
comp.relocateComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3953,6 +3945,83 @@ public class Container extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
private void recursiveShowHeavyweightChildren() {
|
||||
if (!hasHeavyweightDescendants() || !isVisible()) {
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < getComponentCount(); index++) {
|
||||
Component comp = getComponent(index);
|
||||
if (comp.isLightweight()) {
|
||||
if (comp instanceof Container) {
|
||||
((Container)comp).recursiveShowHeavyweightChildren();
|
||||
}
|
||||
} else {
|
||||
if (comp.isVisible()) {
|
||||
ComponentPeer peer = comp.getPeer();
|
||||
if (peer != null) {
|
||||
peer.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recursiveHideHeavyweightChildren() {
|
||||
if (!hasHeavyweightDescendants()) {
|
||||
return;
|
||||
}
|
||||
for (int index = 0; index < getComponentCount(); index++) {
|
||||
Component comp = getComponent(index);
|
||||
if (comp.isLightweight()) {
|
||||
if (comp instanceof Container) {
|
||||
((Container)comp).recursiveHideHeavyweightChildren();
|
||||
}
|
||||
} else {
|
||||
if (comp.isVisible()) {
|
||||
ComponentPeer peer = comp.getPeer();
|
||||
if (peer != null) {
|
||||
peer.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void recursiveRelocateHeavyweightChildren(Point origin) {
|
||||
for (int index = 0; index < getComponentCount(); index++) {
|
||||
Component comp = getComponent(index);
|
||||
if (comp.isLightweight()) {
|
||||
if (comp instanceof Container &&
|
||||
((Container)comp).hasHeavyweightDescendants())
|
||||
{
|
||||
final Point newOrigin = new Point(origin);
|
||||
newOrigin.translate(comp.getX(), comp.getY());
|
||||
((Container)comp).recursiveRelocateHeavyweightChildren(newOrigin);
|
||||
}
|
||||
} else {
|
||||
ComponentPeer peer = comp.getPeer();
|
||||
if (peer != null) {
|
||||
peer.setBounds(origin.x + comp.getX(), origin.y + comp.getY(),
|
||||
comp.getWidth(), comp.getHeight(),
|
||||
ComponentPeer.SET_LOCATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Consider the heavyweight container hides or shows the HW descendants
|
||||
* automatically. Therefore we care of LW containers' visibility only.
|
||||
*/
|
||||
private boolean isRecursivelyVisibleUpToHeavyweightContainer() {
|
||||
if (!isLightweight()) {
|
||||
return true;
|
||||
}
|
||||
return isVisible() && (getContainer() == null ||
|
||||
getContainer().isRecursivelyVisibleUpToHeavyweightContainer());
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnShowing() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
@ -3961,6 +4030,10 @@ public class Container extends Component {
|
||||
|
||||
boolean isLightweight = isLightweight();
|
||||
|
||||
if (isLightweight && isRecursivelyVisibleUpToHeavyweightContainer()) {
|
||||
recursiveShowHeavyweightChildren();
|
||||
}
|
||||
|
||||
if (!isLightweight || (isLightweight && hasHeavyweightDescendants())) {
|
||||
recursiveApplyCurrentShape();
|
||||
}
|
||||
@ -3969,6 +4042,42 @@ public class Container extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnHiding(boolean isLightweight) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
mixingLog.fine("this = " + this +
|
||||
"; isLightweight=" + isLightweight);
|
||||
}
|
||||
if (isLightweight) {
|
||||
recursiveHideHeavyweightChildren();
|
||||
}
|
||||
super.mixOnHiding(isLightweight);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnReshaping() {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
mixingLog.fine("this = " + this);
|
||||
}
|
||||
if (isLightweight() && hasHeavyweightDescendants()) {
|
||||
final Point origin = new Point(getX(), getY());
|
||||
for (Container cont = getContainer();
|
||||
cont != null && cont.isLightweight();
|
||||
cont = cont.getContainer())
|
||||
{
|
||||
origin.translate(cont.getX(), cont.getY());
|
||||
}
|
||||
|
||||
recursiveRelocateHeavyweightChildren(origin);
|
||||
}
|
||||
super.mixOnReshaping();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void mixOnZOrderChanging(int oldZorder, int newZorder) {
|
||||
synchronized (getTreeLock()) {
|
||||
if (mixingLog.isLoggable(Level.FINE)) {
|
||||
|
Loading…
Reference in New Issue
Block a user