From 0f3f5fe944e41d698df22637837c2d5297bf81d2 Mon Sep 17 00:00:00 2001 From: Daniel_M_Williams Date: Sat, 25 Jul 2020 20:05:22 -0400 Subject: [PATCH 1/2] [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. --- .../gui/scalefigure/AbstractScaleFigure.java | 17 ++++----- .../gui/scalefigure/ScaleScrollPane.java | 37 ++++++++++--------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java b/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java index 60575caf5..faba2ee35 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/AbstractScaleFigure.java @@ -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 diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java index e5d665889..69cc67ef6 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java @@ -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(); } } From 0c1029ac1d289ede25982c8fdac5ea237e65cffb Mon Sep 17 00:00:00 2001 From: Daniel_M_Williams Date: Sun, 26 Jul 2020 10:01:04 -0400 Subject: [PATCH 2/2] [fix] RocketFigure always shows scrollbars -- and compensates for this size when zooming to fit. --- .../gui/scalefigure/ScaleScrollPane.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java index 69cc67ef6..35e213a5f 100644 --- a/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java +++ b/swing/src/net/sf/openrocket/gui/scalefigure/ScaleScrollPane.java @@ -63,13 +63,13 @@ public class ScaleScrollPane extends JScrollPane 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; - + + // magic number. I don't know why this number works, but this nudges the figures to zoom correctly. + // n.b. it is slightly large than the ruler.width + scrollbar.width + final Dimension viewportMarginPx = new Dimension( 40, 40); + /** * Create a scale scroll pane. * @@ -103,22 +103,22 @@ public class ScaleScrollPane extends JScrollPane this.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY)); - setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); + setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); getHorizontalScrollBar().setUnitIncrement(50); //getHorizontalScrollBar().setBlockIncrement(viewport.getWidth()); // the default value is good - setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); getVerticalScrollBar().setUnitIncrement(50); //getVerticalScrollBar().setBlockIncrement(viewport.getHeight()); // the default value is good viewport.addMouseListener(this); viewport.addMouseMotionListener(this); - + figure.addChangeListener( e -> { horizontalRuler.updateSize(); verticalRuler.updateSize(); if(fit) { - final java.awt.Dimension calculatedViewSize = new java.awt.Dimension(getWidth() - viewportMarginPx, getHeight() - viewportMarginPx); + final java.awt.Dimension calculatedViewSize = new java.awt.Dimension(getWidth() - viewportMarginPx.width, getHeight() - viewportMarginPx.height); figure.scaleTo(calculatedViewSize); } }); @@ -127,7 +127,7 @@ public class ScaleScrollPane extends JScrollPane @Override public void componentResized(ComponentEvent e) { if(fit) { - final Dimension calculatedViewSize = new Dimension(getWidth() - viewportMarginPx, getHeight() - viewportMarginPx); + final Dimension calculatedViewSize = new Dimension(getWidth() - viewportMarginPx.width, getHeight() - viewportMarginPx.height); figure.scaleTo(calculatedViewSize); } figure.updateFigure();