2013-04-05 42 views
4

我可以使用setVvalue(double)和setHvalue(double)方法移動JavaFX ScrollPane中的視口。我正在努力做的是根據其位置將滾動窗格內容中的特定節點居​​中。我嘗試了各種各樣的localToScene()和boundsInParent()的組合。我讀過(很多),看到這個例子JavaFX ScrollPane以編程方式移動視口 - 居中內容

How to scroll to make a Node within the content of a ScrollPane visible?

這是接近但不居中的對象只是把它們可見。內置的鼠標平移功能非常出色,但是我正在爲編程平移做好準備。

最終我需要能夠進行縮放,因此我已將實際形狀放入組中並將組添加到滾動窗格內容。我認爲我應該在組上進行縮放,並且我需要能夠縮放組的中心,以便我們回到操縱和識別當前中心位置。任何可以提供的指針或例子都會非常感謝。上面鏈接中的代碼示例是一個很好的SSCCE。

由於提前,

安迪

+0

Hmmmm,但在我看來,問題沒有得到的回答#如果他們真的很容易,提問者是一個白癡,或者真的很難,沒有人可以打擾一個答案!我很高興被告知我是個白癡! – andyw 2013-04-09 07:07:04

+0

你是怎麼修復它的? – kingkong 2014-01-15 15:56:29

+0

如果其中一個答案適合您,請考慮接受其中一個答案! – 2015-11-20 19:08:10

回答

0

我知道,這是有點晚了,但也許有人會覺得它有用。:)

至於爲中心,這是不是硬任務它只需要一點數學。你需要兩件事。 ScrollPane的全部內容的大小(可滾動區域的寬度和高度,不僅包含帶滾動條的框架,而且完全像沒有滾動條一樣)以及居中對象在ScrollPane內容中的位置。

你得到的內容大小是這樣的:scrollPane.getContent().getBoundsInLocal().getHeight() or .getWidth()

和你對象的位置:node.getBoundsInParent().getMinY() or .getMinX() - 對象的最低位置。你也可以得到它的高度和寬度。

然後根據此公式計算您的中心位置並移動滾動條。

double vScrollBarPosition = scrollPane.getVMax() * (yPositionOfCenter/heightOfScrollPaneContent)

+0

這不會精確地居中組件,因爲您認爲滾動窗格可以滾動其內容窗格的整個高度。 – 2014-05-07 13:12:20

7

我會嘗試沒有代碼解釋這一點,因爲我不認爲這是必要的在這裏。

比方說,你滾動窗格的內容具有高度h,和視口的高度是v。如果h = v,那麼內容將完全適合視口,並且您將不需要滾動條。在這種情況下(使用不可移動的滾動條),對於要居中的元素,它需要位於滾動窗格內容的中心。您無法通過滾動將其移動到視口中心。

現在考慮hv(即h = 2v)的兩倍大小。在這種情況下,滾動窗格內容的上部1/4和下部1/4不能通過滾動居中。

(如果你絕對需要通過滾動,你應該考慮你的填充內容窗格中心的任何部件,但我們會繼續與這裏未填充液)

當你想想看,你會發現滾動條可能的可滾動距離爲h - v,您將通過將vvalue設置爲1.0來滾動該數值。

爲中心的點y(這裏的點y是滾動窗格的內容窗格中的座標),您可以使用以下VVALUE:

vvalue = (y - 0.5 * v)/(h - v) 

該表達式的提名是對什麼是Y座標當點y在視口內居中時顯示在視口的頂部。分母是可滾動的總距離。

編輯:無論如何添加一些代碼!

public void centerNodeInScrollPane(ScrollPane scrollPane, Node node) { 
    double h = scrollPane.getContent().getBoundsInLocal().getHeight(); 
    double y = (node.getBoundsInParent().getMaxY() + 
       node.getBoundsInParent().getMinY())/2.0; 
    double v = scrollPane.getViewportBounds().getHeight(); 
    scrollPane.setVvalue(scrollPane.getVmax() * ((y - 0.5 * v)/(h - v))); 
} 

(請注意,這個假設節點是滾動面板的contentPane而直接子)

希望這有助於! :)

0

這是一個關於如何居中已經旋轉過的圖片的例子。 代碼是Scala,因此適用於ScalaFX,但JavaFX和Java開發人員將能夠讀取/使用它:

def turnPic(angle:Int) { 
    val virtualSurfaceMultiplier = 8.0; 
    currentAngle = (floor((currentAngle % 360)/90) * 90 + angle + 360) % 360; 
    imageView.rotate = currentAngle; 
    val orientationSwitched = (currentAngle/90) % 2 > 0; 
    val width= scrollPane.getViewportBounds().getWidth(); 
    val height= scrollPane.getViewportBounds().getHeight(); 
    val viewPort = new Rectangle2D(0, 0, image.width.value, image.height.value); 
    imageView.setViewport(viewPort); 
    imageView.fitHeight.value = virtualSurfaceMultiplier * height; 
    imageView.fitWidth.value = 0 //virtualSurfaceMultiplier * width; 
    def centerV(picHeight:Double) { 
     val node = scrollPane.getContent(); 
     val totalHeight = scrollPane.getContent().getBoundsInLocal().getHeight(); 
     val offsetToCenter = (node.getBoundsInParent().getMaxY() + node.getBoundsInParent().getMinY())/2.0; 
     val viewportWidth = scrollPane.getViewportBounds().getHeight(); 
     val res = (scrollPane.getVmax() * ((offsetToCenter - 0.5 * picHeight * zoomFactor)/(totalHeight - picHeight * zoomFactor))); 
     scrollPane.setVvalue(res); 
    } 
    def centerH(picWidth:Double) { 
     val node = scrollPane.getContent(); 
     val totalWidth = scrollPane.getContent().getBoundsInLocal().getWidth(); 
     val offsetToCenter = (node.getBoundsInParent().getMaxX() + node.getBoundsInParent().getMinX())/2.0; 
     val viewportWidth = scrollPane.getViewportBounds().getWidth(); 
     val res = (scrollPane.getHmax() * ((offsetToCenter - 0.5 * picWidth * zoomFactor)/(totalWidth - picWidth * zoomFactor))); 
     scrollPane.setHvalue(res); 
     System.err.println(s"trace centerH> $FILE:$LINE:" + " totalWidth:" + totalWidth + " offsetToCenter=" + offsetToCenter + " vWidth=" + viewportWidth + "res=" + res); 
    } 
    if (orientationSwitched) { 
     zoomFactor = 1.0/(virtualSurfaceMultiplier * image.width.value/image.height.value); 
     centerH(height); 
     centerV(width); 
    } 
    else 
    { 
     zoomFactor = 1.0/virtualSurfaceMultiplier; 
     centerH(width); 
     centerV(height); 
    } 
    imageView.setScaleX(zoomFactor); 
    imageView.setScaleY(zoomFactor); 
    } 
+2

當你創建一個答案時,你需要格式化代碼,這是完全不可讀的。 – 2015-06-02 19:59:17

相關問題