Problem with viewport scrollbars after zoom


#1

I’ve got a view that has been zoomed by calling setTransform() on it. Its wrapped in a viewport with vertical and horizontal scroll bars.

As I zoom into the view, the scroll bars in the viewport shrink, to show that the scrollable area has increased. Unfortunately, although the scrollbars move, they scroll exactly the same distance they did before the transformation happened. Although they’re smaller, they won’t scroll to show me the full view.

I’m sure there’s just something silly on my end that I’ve forgotten to do, but I’m not sure what. Any ideas?


#2

The Viewport class is smart enough to deal with transformed views - the geometry gets really complicated when you start doing things like that. Best to put your transformed component inside a non-transformed container and use that as the view if you want to do this kind of thing.


#3

I’m not sure if I follow. You’re suggesting the following view hierarchy:

Window
ViewPort
Untransformed container
Transformed component

Since the bounds of the transformed component are increasing as I zoom, won’t the fact that its inside a non-transformed container mean that I’ll be able to see less and less of it as I zoom in? If the scrollers on the viewPort are watching the
untransformed container, then I wouldn’t think they would adjust as the transformed component becomes larger.

Clearly, I’m missing something here.


#4

You’d obviously have to increase the size of the non-transformed component, to fit it correctly.


#5

Sorry, I’m just getting back to this.

I had naively assumed that if I scaled a component using setTransform(), that its bounds would also change accordingly, and I could thus use childBoundsChanged() to get informed of the change in the container component above the transformed component.

I realize now, however, that the bounds of a component don’t change as a result of the Transform. Is there a clever way to make this happen? Does the routine that calls setTransform() also have to calculate the new bounds for component using the same transform matrix, or is there a simpler way?


#6

Try Component::getBoundsInParent(), perhaps?


#7

Brilliant! That worked like a charm.

I’ve got a follow-up, however.

To draw an image like an ellipse, my paint() routine looks at the graphics state:
Rectangle theFrameRect(g.getClipBounds());
And then draw the ellipse within the bounds of the returned rect.

When the component in which the ellipse is placed is zoomed, and I scroll, I can watch the ellipse flatten as it reaches the edge of the viewable area. Clearly, the clip rect is being flattened as the image goes off view.

What’s the correct way to do this? getScreenBounds()?


#8

You can’t use the clip region as a reference for laying things out! All it tells you is the area that needs painting, which could be ANY sub-region of your component!


#9

Agreed.

Is getLocalBounds() the rect to use when drawing to get the correct extent of the component?


#10

Yes, if you want the component’s size.