2012-10-31 104 views
9

我需要在放大圖像時計算視口的新位置。JScrollPane - 相對於鼠標位置的縮放

的UI建成如下:

  • ImagePanel繪製圖像
  • ImagePanelWrapper是圍繞imagePanel
  • JScrollPane的一個JPanel包裝包含ImagePanelWrapper

或縮小時出,ImagePanel的縮放因子被改變,並且重新計算ImagePanel的首選大小。因此,即使ImagePanel停留在相同的視口點,該面板上的圖像也會移動。

當用戶按住CTRL並使用鼠標滾輪時,將調用以下方法。給定的是由MouseWheelListener提供的遊標位置。利用這些方法的功能,圖像在放大或縮小時已經停留在相同的左上角位置。

問題是我不知道如何相對於鼠標移動,例如Paint.NET。有任何想法嗎?

/** 
* 
*/ 
public void zoomOut(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int) (pos.x * 0.9f); 
    int newY = (int) (pos.y * 0.9f); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

/** 
* 
*/ 
public void zoomIn(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int) (pos.x * 1.1f); 
    int newY = (int) (pos.y * 1.1f); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

回答

34

如果這些假設是正確的:

  • 提供的點相對於視口的左上角。
  • 視口的尺寸小於底層的ImagePanel。

然後視口可以調整,使得光標在圖像中的相同點之前和變焦操作後,如果移動以下列方式:

/** 
* 
*/ 
public void zoomOut(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 0.9f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int)(point.x*(0.9f - 1f) + 0.9f*pos.x); 
    int newY = (int)(point.y*(0.9f - 1f) + 0.9f*pos.y); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

/** 
* 
*/ 
public void zoomIn(Point point) { 
    this.imagePanel.setZoom(this.imagePanel.getZoom() * 1.1f); 
    Point pos = this.getViewport().getViewPosition(); 

    int newX = (int)(point.x*(1.1f - 1f) + 1.1f*pos.x); 
    int newY = (int)(point.y*(1.1f - 1f) + 1.1f*pos.y); 
    this.getViewport().setViewPosition(new Point(newX, newY)); 

    this.imagePanel.revalidate(); 
    this.imagePanel.repaint(); 
} 

下面是完整的數學'爲了:

enter image description here

+1

+1真棒,回答。最近我見過一段時間。 – max

+0

你先生配得上謝謝:) – EyeSpy

+0

我有一個類似的問題。我試圖使用AffineTransform來做同樣的事情,而且我在應用這個問題的數學方面遇到了一些麻煩。如果你找到時間,你能幫助我嗎? http://stackoverflow.com/questions/37509908/zoom-in-at-mouse-cursor – bigblind

2

你應該能夠得到使用point.xpoint.y鼠標指針的位置 - 參見Point文檔here。根據MouseMotionEvent文檔herepoint.xpoint.y是相對於鼠標下的組件(JScrollPane)。

您可以將這些值合併到您的計算中。這是你在找什麼?

相關問題