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

相关问题