从 JComponent 的右下角动画缩小会导致卡顿

Posted

技术标签:

【中文标题】从 JComponent 的右下角动画缩小会导致卡顿【英文标题】:Animated zooming out from the right-bottom-corner from JComponent causes stuttering 【发布时间】:2012-03-25 17:59:23 【问题描述】:

我目前正在实现一个 swing JComponent 作为图像查看器,它能够缩放、旋转和显示居中的图像以及所有这些动画。我已经实现了所有这些功能,但是在从图像的右下角缩小时遇到了问题。 每次动画开始卡顿并且仅从面板的右侧或底部边缘开始。

@Override
protected void paintComponent(Graphics g) 
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    if (this.workingCopy != null) 
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        Point2D center = new Point2D.Double((getPreferredSize().width) / 2, (getPreferredSize().height) / 2);
        g2d.scale(getZoom(), getZoom());
        g2d.rotate(Math.toRadians(getRotation()), (center.getX() + 0) / getZoom(), (center.getY() + 0) / getZoom());
        g2d.drawImage(this.workingCopy,
                (int) Math.round(((getPreferredSize().width - (image.getWidth() * getZoom())) / 2) / getZoom()),
                (int) Math.round(((getPreferredSize().height - (image.getHeight() * getZoom())) / 2) / getZoom()), null);
    


public synchronized void setZoom(final double zoom, boolean animated, final Point point) 
    final double oldZoom = getZoom();

    final Dimension viewSize = getPreferredSize();
    final Rectangle viewRect = getVisibleRect();

    // get relative point
    double relX = viewRect.getX() / viewSize.getWidth();
    double relY = viewRect.getY() / viewSize.getHeight();

    // new size
    double newViewSizeWidth = (getImageBounds().getWidth() / oldZoom) * zoom;
    double newViewSizeHeight = (getImageBounds().getHeight() / oldZoom) * zoom;


    double deltaDiffX = (point.getX() - viewRect.getX()) / viewSize.getWidth();
    double deltaDiffY = (point.getY() - viewRect.getY()) / viewSize.getHeight();

    double newDiffX = newViewSizeWidth * deltaDiffX;
    double newDiffY = newViewSizeHeight * deltaDiffY;

    double viewPositionX = (newViewSizeWidth * relX) + newDiffX - (point.getX() - viewRect.getX());
    double viewPositionY = (newViewSizeHeight * relY) + newDiffY - (point.getY() - viewRect.getY());

    final Point newPoint = new Point((int) Math.round(viewPositionX), (int) Math.round(viewPositionY));

    if (animated && !zooming) 

        Animator animator = new Animator(getAnimationSpeed(), new TimingTargetAdapter() 

            @Override
            public void begin() 
                super.begin();
                zooming = true;
            

            @Override
            public void timingEvent(final float fraction) 
                super.timingEvent(fraction);
                double zoomDiff = zoom - oldZoom;
                setZoom(oldZoom + (fraction * zoomDiff),
                        new Point(
                        (int) Math.round(viewRect.getX() - (viewRect.getX() - newPoint.getX()) * fraction),
                        (int) Math.round(viewRect.getY() - (viewRect.getY() - newPoint.getY()) * fraction)));
            

            @Override
            public void end() 
                super.end();
                zooming = false;
            
        );
        animator.start();
     else 
        setZoom(zoom, newPoint);
    

有人可以指出我做错了什么或忘记考虑缩放动画吗? 除了动画缩小期间的口吃之外,一切正常。

提前感谢您的帮助。

【问题讨论】:

为了更好的帮助,请尽快使用SSCCE编辑您的问题 角落总是一个问题。 FauxImage 可能有助于创建 sscce。 我有一个解决方法,但仍然很高兴知道是否有更好的方法来解决问题。我引入了内部变量“宽度”和“高度”,并将 250 像素添加到首选大小作为缓冲区。此外,我限制了组件的 scrollToVisibleRect 方法,并检查每个转换并更新可见矩形是否不显示缓冲区的一部分。 @user1291485 由您发布的代码也许这里没有任何关于您的更好方法的建议 【参考方案1】:

好的,我偶然发现了这个问题。问题是 JPanel 仍然有一个 LayoutManager,这在从右/下角缩小时导致了问题。 在我将 LayoutManager 设置为 null 后,一切正常。

【讨论】:

以上是关于从 JComponent 的右下角动画缩小会导致卡顿的主要内容,如果未能解决你的问题,请参考以下文章

TransformAnimation - 一个超简单的导航转换动画

TransformAnimation - 一个超简单的导航转换动画

滚动脚本上的动画更改徽标大小会导致库冲突或其他一些加载问题

在非活动选项卡上调用事件以进行控制会导致异常

SwiftUI:输入字段键盘动画导致选项卡视图中的其他视图动画

烦死了,电脑卡死