2012-03-25 84 views
2

我目前正在實現一個圖像查看器的揮杆JComponent,可以縮放,旋轉和顯示圖像居中,並且所有動畫都是這樣。我已經實現了所有這些功能,但在從圖像右下角縮小期間遇到問題。 動畫每次開始時都會出現口吃,只能從面板的右側或底部邊緣開始。動畫從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); 
    } 
} 

有人可以指出我做了什麼我做錯了或忘了爲縮放動畫進行合併? 除了在動畫縮小過程中的口吃,一切都可以工作。

在此先感謝您的幫助。

+3

爲更好地幫助更快地編輯您的問題與[SSCCE](http://sscce.org/) – mKorbel 2012-03-25 18:12:16

+0

角落總是一個問題。 A ['FauxImage'](http://stackoverflow.com/a/8090328/230513)可能會用於創建youe [sscce](http://sscce.org/)。 – trashgod 2012-03-25 19:02:09

+0

我有一個解決方法,但仍然很高興知道是否有更好的方法來解決問題。我引入了內部變量的'寬度'和'高度',並將250px添加到首選大小作爲緩衝區。此外,我限制組件的scrollToVisibleRect方法並檢查每個變換並更新可見矩形是否不顯示緩衝區的一部分。 – user1291485 2012-03-25 19:17:18

回答

1

好的,我偶然發現了這個問題。問題是JPanel仍然有一個LayoutManager,當從右下角縮小時會導致問題。 當我將LayoutManager設置爲null後,所有事情都按照它應該的方式工作。