[fixes #696] Fixes occassional zitter when auto-zooming at some sizes

Ultimate cause is some very odd behavior from JViewPort.

This code is in effect, a workaround for that odd behavior.  It IS therefore 2/3 ugly hack :(

Also, refined some of the zoom calculations to be more exact.
This commit is contained in:
Daniel_M_Williams 2020-07-25 20:05:22 -04:00
parent 6b609809e0
commit 0f3f5fe944
2 changed files with 27 additions and 27 deletions

View File

@ -109,7 +109,6 @@ public abstract class AbstractScaleFigure extends JPanel {
* @param visibleBounds the visible bounds upon the Figure
*/
public void scaleTo(final double newScaleRequest, final Dimension visibleBounds) {
// System.err.println(String.format(" ::scaleTo: %6.4f ==>> %6.4f, %d x %d", userScale, newScaleRequest, visibleBounds.width, visibleBounds.height));
if (MathUtil.equals(this.userScale, newScaleRequest, 0.01) &&
(visibleBounds_px.width == visibleBounds.width) &&
(visibleBounds_px.height == visibleBounds.height) )
@ -117,7 +116,6 @@ public abstract class AbstractScaleFigure extends JPanel {
return;}
if (Double.isInfinite(newScaleRequest) || Double.isNaN(newScaleRequest) || 0 > newScaleRequest) {
return;}
// System.err.println(String.format(" => continue"));
this.userScale = MathUtil.clamp( newScaleRequest, MINIMUM_ZOOM, MAXIMUM_ZOOM);
this.scale = baseScale * userScale;
@ -133,7 +131,6 @@ public abstract class AbstractScaleFigure extends JPanel {
* @param visibleBounds the visible bounds to scale this figure to.
*/
public void scaleTo(Dimension visibleBounds) {
// System.err.println(String.format(" ::scaleTo: %d x %d", visibleBounds.width, visibleBounds.height));
if( 0 >= visibleBounds.getWidth() || 0 >= visibleBounds.getHeight())
return;
@ -141,8 +138,8 @@ public abstract class AbstractScaleFigure extends JPanel {
updateCanvasSize();
updateCanvasOrigin();
final double width_scale = (visibleBounds.width) / ((subjectBounds_m.getWidth() * baseScale) + 2 * borderThickness_px.width);
final double height_scale = (visibleBounds.height) / ((subjectBounds_m.getHeight() * baseScale) + 2 * borderThickness_px.height);
final double width_scale = (visibleBounds.width - 2 * borderThickness_px.width) / (subjectBounds_m.getWidth() * baseScale);
final double height_scale = (visibleBounds.height - 2 * borderThickness_px.height) / (subjectBounds_m.getHeight() * baseScale);
final double newScale = Math.min(height_scale, width_scale);
scaleTo(newScale, visibleBounds);
@ -168,10 +165,12 @@ public abstract class AbstractScaleFigure extends JPanel {
(int)(contentBounds_m.getHeight()*scale) + 2*borderThickness_px.height);
Dimension preferredFigureSize_px = new Dimension(desiredWidth, desiredHeight);
setPreferredSize(preferredFigureSize_px);
setMinimumSize(preferredFigureSize_px);
}
if( (getWidth() != preferredFigureSize_px.width) || (getHeight() != preferredFigureSize_px.height)) {
setPreferredSize(preferredFigureSize_px);
setMinimumSize(preferredFigureSize_px);
}
}
protected void updateTransform(){
// Calculate and store the transformation used

View File

@ -62,7 +62,11 @@ public class ScaleScrollPane extends JScrollPane
private DoubleModel rulerUnit;
private Ruler horizontalRuler;
private Ruler verticalRuler;
// magic number. I don't know why this number works, but this nudges the figures to zoom correctly.
// n.b. the ruler widths == 20 px
private static final int viewportMarginPx = 22;
// is the subject *currently* being fitting
private boolean fit = false;
@ -110,27 +114,26 @@ public class ScaleScrollPane extends JScrollPane
viewport.addMouseListener(this);
viewport.addMouseMotionListener(this);
figure.addChangeListener(new StateChangeListener() {
@Override
public void stateChanged(EventObject e) {
horizontalRuler.updateSize();
verticalRuler.updateSize();
if(fit) {
figure.scaleTo(viewport.getExtentSize());
}
figure.addChangeListener( e -> {
horizontalRuler.updateSize();
verticalRuler.updateSize();
if(fit) {
final java.awt.Dimension calculatedViewSize = new java.awt.Dimension(getWidth() - viewportMarginPx, getHeight() - viewportMarginPx);
figure.scaleTo(calculatedViewSize);
}
});
viewport.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
if(fit) {
figure.scaleTo(viewport.getExtentSize());
}
figure.updateFigure();
horizontalRuler.updateSize();
verticalRuler.updateSize();
if(fit) {
final Dimension calculatedViewSize = new Dimension(getWidth() - viewportMarginPx, getHeight() - viewportMarginPx);
figure.scaleTo(calculatedViewSize);
}
figure.updateFigure();
horizontalRuler.updateSize();
verticalRuler.updateSize();
}
});
@ -160,10 +163,8 @@ public class ScaleScrollPane extends JScrollPane
final Point zoomPoint = figure.getAutoZoomPoint();
final Rectangle zoomRectangle = new Rectangle(zoomPoint.x, zoomPoint.y, (int)(view.getWidth()), (int)(view.getHeight()));
// System.err.println(String.format("::zoom: @ %d, %d [ %d x %d ]", zoomRectangle.x, zoomRectangle.y, zoomRectangle.width, zoomRectangle.height));
figure.scrollRectToVisible(zoomRectangle);
figure.invalidate();
revalidate();
}
}