2013-04-05 5 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

흠, 그들이 경우 질문에 유래에 응답되지 않는 날 것으로 보인다 정말 쉽고 질문자가 바보가되거나 정말 힘들고 아무도 대답을 고치지 않을 수 있습니다! 나는 바보라고 들었 기 때문에 매우 기쁘다 !! – andyw

+0

어떻게 수정 했습니까? – kingkong

+0

답변 중 하나가 효과가 있다면 수락을 고려해보십시오! –

답변

0

내가 알고, 그것을 조금 늦게,하지만 어쩌면 누군가가 도움을 발견 할 것이다. :)

을 중심에 관하여는이 어려운 작업을하지 않습니다 수학은 조금 밖에 걸리지 않습니다. 두 가지가 필요합니다. ScrollPane의 전체 내용 크기 (스크롤바가있는 프레임뿐만 아니라 스크롤 막대의 너비와 높이, 스크롤 막대가없는 경우처럼 완성 됨) 및 ScrollPane 내용의 가운데에있는 객체의 위치입니다.

는이 같은 내용의 크기를 얻을 : scrollPane.getContent().getBoundsInLocal().getHeight() or .getWidth()

그리고 개체의 위치 : node.getBoundsInParent().getMinY() or .getMinX() - 객체의 최소한의 위치를. 높이와 너비도 얻을 수 있습니다.

그런 다음이 공식에 따라 센터의 위치를 ​​계산하고 스크롤 막대를 이동하십시오. 내가 그 여기에 필요하다고 생각하지 않기 때문에

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

+0

스크롤 창을 내용 분할 창의 전체 높이에 대해 스크롤 할 수 있다고 가정하기 때문에 구성 요소의 중심을 정확하게 지정하지는 않습니다. –

7

나는 코드없이 설명하려고합니다.

은의이 스크롤의 내용 높이 h을 가지고 있다고 가정 해 봅시다, 뷰포트의 높이가 v입니다. h = v이면 내용이 뷰포트에 완벽하게 맞을 것이므로 스크롤바가 필요하지 않습니다. 이 경우 (이동 불가능의 스크롤 바를 사용), 엘리먼트를 중앙에 배치하려면, 스크롤 구획의 컨텐츠의 중앙에 배치 할 필요가 있습니다. 스크롤을 사용하여 뷰포트의 중앙으로 이동할 수 없습니다.

이제 hv (즉, h = 2v)의 두 배가되는 것으로 간주합니다. 이 상황에서는, 스크롤 구획의 컨텐츠의 상부 1/4 및 하부 1/4가 스크롤링에 의해 중앙에 배치되지 않습니다.

(당신이 절대적으로 당신이 당신의 콘텐츠 창 패딩 고려해야 스크롤하여 구성 요소를 중심으로 필요하지만, 우리는 여기에 덧붙여지지 않은 솔루션을 계속하겠습니다 경우) 당신이 그것에 대해 생각하면

, 당신이 생각하는 것 스크롤바의 가능한 srollable 거리는 h - v이며, vvalue을 1.0으로 설정하여 스크롤 할 수 있습니다.

y 다음 vvalue을 사용할 수 있습니다 (여기에 포인트 Y는 스크롤 구획의 컨텐츠 구획의 좌표를) 센터 :

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

다음은 회전 된 사진을 가운데에 배치하는 방법에 대한 예입니다. 코드는 스칼라이고 ScalaFX에 적용 가능하지만, 자바 FX와 자바 개발자는 읽기 /를 사용할 수 있습니다 :

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

답안을 작성할 때 코드 서식을 지정해야합니다. 이는 완전히 읽을 수 없습니다. –