insureVisibleLocation does not work correctly if the
component is placed in a parent whose position in the
viewport is different from (0,0).
The reason is that the the components coordinates are
transformed to the parents coordinate system. The
transformation is stopped here, but it should go on
with the parents parent etc. until a parent is equal to
the viewport.
In my bugfixed version of the
junit.extensions.jfcunit.eventdata.MenuEventData class
insureVisibleLocation looks like that:
public void insureVisibleLocation(final Point p) {
// Need to get the parent viewport.
Component m_comp = getSource();
Component parent = m_comp.getParent();
if (parent instanceof JComponent) { // not really
necessary, the else part would do it anyway. But why
not use the jdk method
((JComponent)parent).scrollRectToVisible( new
Rectangle(p, m_comp.getSize()) );
}
else {
// find the viewport
for (parent = parent.getParent();
(parent != null) && !(parent instanceof
JViewport);
parent = parent.getParent())
{
Rectangle bounds = parent.getBounds();
// adapt the coordinates
p.x += bounds.x;
p.y += bounds.y;
}
if (parent!=null && parent instanceof JViewport) {
JViewport viewport = (JViewport)parent;
Rectangle rect = viewport.getViewRect();
rect.x = p.x - (rect.width / 2);
rect.y = p.y - (rect.height / 2);
viewport.scrollRectToVisible(rect);
}
}
}
prepareComponent had also been changed to prevent doing
the first transformation twice:
public boolean prepareComponent() {
Component m_comp = getComponent();
if (!isValidForProcessing(m_comp)) {
return false;
}
// Note: don't follow the scroll issue from the
other MouseEventData sub-classes here
// that is done only for specialized EventData classes.
Rectangle rect = new Rectangle(m_comp.getSize());
insureVisibleLocation(calculatePoint(rect));
rect.setLocation(m_comp.getLocationOnScreen());
setLocationOnScreen(calculatePoint(rect));
return true;
}
If you have questions, you may contact me per email:
stephan.mueller@sdm.de