// and then further ensure that nothing else holds a strong reference
// to the component (by waiting for the component to be garbage
// collected).
JComponent component = createTestComponent();
JComponent overlay = createTestOverlay();
final ReferenceQueue rq = new ReferenceQueue();
final PhantomReference componentRef = new PhantomReference(component, rq);
final JRootPane rootPane = new JRootPane() {
public boolean isVisible() {
return true;
}
public boolean isShowing() {
return true;
}
protected JLayeredPane createLayeredPane() {
return new JLayeredPane() {
public boolean isVisible() {
return true;
}
public boolean isShowing() {
return true;
}
};
}
};
final int lpcount = rootPane.getLayeredPane().getComponentCountInLayer(JLayeredPane.PALETTE_LAYER.intValue());
OverlayHelper.attachOverlay(overlay, component, 0, 0, 0);
assertEquals(lpcount, rootPane.getLayeredPane().getComponentCountInLayer(JLayeredPane.PALETTE_LAYER.intValue()));
rootPane.getContentPane().add(component);
// updateOverlay is "invokedLater", so wait for it...
waitUntilEventQueueIsEmpty();
assertEquals(lpcount + 1, rootPane.getLayeredPane().getComponentCountInLayer(JLayeredPane.PALETTE_LAYER.intValue()));
rootPane.getContentPane().remove(component);
// the remove operation make be invoked later, so wait for it...
waitUntilEventQueueIsEmpty();
// Clear out our strong references so it gets garbage collected.
component = null;
overlay = null;
// Make sure the overlay was removed from the layered pane.
assertEquals("It appears the overlay was not removed from the layered pane when its component was removed from the content pane", lpcount, rootPane.getLayeredPane().getComponentCountInLayer(JLayeredPane.PALETTE_LAYER.intValue()));
// Make sure no other references are held... wait up to 15 seconds for
// the object to be garbage collected.
// Note: we may want to remove this section from the test as it
// presumes the VM will garbage collect the reference fairly quickly
// once a System.gc() is invoked.
// There is no guarantee this will happen, so the assumption may be
// faulty. If it ends up being a problem, or starts yielding
// inconsistent test results, then feel free to yank it.
PhantomReference pr;
final long end = System.currentTimeMillis() + 15000;
do {
System.gc();
} while((pr = (PhantomReference)rq.remove(100)) == null && System.currentTimeMillis() < end);
if(pr != null) {
pr.clear();
}
assertSame("Either something else is still holding a strong reference to the component, or the VM is not garbage collecting it. See comments in OverlayHelperTests.testRegressionOverlayHelperLeak() for more detail", pr, componentRef);
}