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

View File

@ -62,7 +62,11 @@ public class ScaleScrollPane extends JScrollPane
private DoubleModel rulerUnit; private DoubleModel rulerUnit;
private Ruler horizontalRuler; private Ruler horizontalRuler;
private Ruler verticalRuler; 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 // is the subject *currently* being fitting
private boolean fit = false; private boolean fit = false;
@ -110,27 +114,26 @@ public class ScaleScrollPane extends JScrollPane
viewport.addMouseListener(this); viewport.addMouseListener(this);
viewport.addMouseMotionListener(this); viewport.addMouseMotionListener(this);
figure.addChangeListener(new StateChangeListener() { figure.addChangeListener( e -> {
@Override horizontalRuler.updateSize();
public void stateChanged(EventObject e) { verticalRuler.updateSize();
horizontalRuler.updateSize(); if(fit) {
verticalRuler.updateSize(); final java.awt.Dimension calculatedViewSize = new java.awt.Dimension(getWidth() - viewportMarginPx, getHeight() - viewportMarginPx);
if(fit) { figure.scaleTo(calculatedViewSize);
figure.scaleTo(viewport.getExtentSize());
}
} }
}); });
viewport.addComponentListener(new ComponentAdapter() { viewport.addComponentListener(new ComponentAdapter() {
@Override @Override
public void componentResized(ComponentEvent e) { public void componentResized(ComponentEvent e) {
if(fit) { if(fit) {
figure.scaleTo(viewport.getExtentSize()); final Dimension calculatedViewSize = new Dimension(getWidth() - viewportMarginPx, getHeight() - viewportMarginPx);
} figure.scaleTo(calculatedViewSize);
figure.updateFigure(); }
figure.updateFigure();
horizontalRuler.updateSize();
verticalRuler.updateSize(); horizontalRuler.updateSize();
verticalRuler.updateSize();
} }
}); });
@ -160,10 +163,8 @@ public class ScaleScrollPane extends JScrollPane
final Point zoomPoint = figure.getAutoZoomPoint(); final Point zoomPoint = figure.getAutoZoomPoint();
final Rectangle zoomRectangle = new Rectangle(zoomPoint.x, zoomPoint.y, (int)(view.getWidth()), (int)(view.getHeight())); 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.scrollRectToVisible(zoomRectangle);
figure.invalidate();
revalidate(); revalidate();
} }
} }