【问题标题】:JavaFX - Adjusting the ImageView in the centerJavaFX - 在中心调整 ImageView
【发布时间】:2016-10-10 16:43:54
【问题描述】:

我正在使用 JavaFX 开发图片查看器。 我目前的问题如下:

每次在ImageViewer 中显示新的Image 时(当用户单击“上一个”或“下一个”时),ImageViewer 应在其Parent 节点中居中,在本例中为@ 987654325@。我正在使用setTranslate 方法,它工作正常,但它不能正常工作,因为每次加载新的ImageImageView 都处于不同的位置。

我正在使用这种方法来重新定位ImageView

public void adjustImageViewBounds()
{
    double windowWidth = MAIN.getWindow().getScene().getWidth();
    double windowHeight = MAIN.getWindow().getScene().getHeight();
    double imageWidth = GUI.getImageView().getImage().getWidth();
    double imageHeight = GUI.getImageView().getImage().getHeight();
    boolean isFullScreen = MAIN.getWindow().isFullScreen();

    GUI.getImageView().setFitWidth(windowWidth - 50 > imageWidth ? imageWidth : windowWidth - 50);

    // 50 ~ 25px space on the left and right side

    boolean scrollBarVisible = false;
    Set<Node> nodes = GUI.getImageViewScrollPane().lookupAll(".scroll-bar");
    for(Node currentNode : nodes)
    {
        if(currentNode instanceof ScrollBar)
            if(((ScrollBar) currentNode).getOrientation() == Orientation.VERTICAL)
                if(currentNode.isVisible())
                    scrollBarVisible = true;    
    }
    if(!scrollBarVisible && !isFullScreen)
    {
        // 80 ~ GUI.getInfoBoxAndImageView().getLayoutY() -> The Y position within the window of my whole ImageView container (HBox)
        // 65 ~ GUI.getLowerControl().getHeight() -> The height of the controlbar under the ImageView
        double newTranslateY = (windowHeight / 2) - 80 - (VISIBLE_IMAGE_HEIGHT.divide(2).doubleValue());
        GUI.getInfoBoxAndImageView().setTranslateY(newTranslateY >= 0 && (newTranslateY + 80 + VISIBLE_IMAGE_HEIGHT.doubleValue()) < (windowHeight - 65) ? newTranslateY : 0);
    }
    else if(scrollBarVisible)
    {
        GUI.getInfoBoxAndImageView().setTranslateY(0);
    }
    else if(isFullScreen)
    {
        double newTranslateY = (windowHeight / 2) - 80 - (VISIBLE_IMAGE_HEIGHT.divide(2).doubleValue());
        GUI.getInfoBoxAndImageView().setTranslateY(newTranslateY >= 0 && (newTranslateY + 80 + VISIBLE_IMAGE_HEIGHT.doubleValue()) < (windowHeight - 65) ? newTranslateY : 0);
    }
}

只要我在加载Image 之后调用它,该方法就可以工作,但是当我在设置新的Image 之后调用它时,它就不起作用。 以下是设置新 Image 时的示例:

public void nextClicked()
     {
        if(PICTURE_INDEX < picturePaths.size() - 1)
        {
            String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString();
            GUI.getImageView().setImage(new Image(path));
            adjustImageViewBounds(); 
            PICTURE_INDEX += 1;
        }
     }

为了解决这个问题,我一直在尝试使用不同的Listeners

GUI.getImageViewer().imageProperty().addListener(newImage -> 
{
   while(newImage.getProgress() < 1.0)
   {
      //Do nothing until the Image is completely loaded
   }
   adjustImageViewBounds();
   System.out.println("End reached");
});

其实已经到了终点,但是方法并没有影响ImageView的位置?!? 也不起作用:

public void nextClicked()
{
   if(PICTURE_INDEX < picturePaths.size() - 1)
   {
      String path = picturePaths.get(PICTURE_INDEX + 1).toURI().toString();
      Image newImage = new Image(path);
      newImage.progressProperty().addListener((obs, oldV, newV) -> 
      {
         if(newV.doubleValue() == 1.0)
            adjustImageViewBounds();
      });
      GUI.getImageView().setImage(newImage); 
      PICTURE_INDEX += 1;
    }
}

只是为了好玩,我尝试了这个并且它有效,但它当然不是一个合理的解决方案:

GUI.getImageView().setOnMouseClicked(event -> adjustImageViewBounds());

总结所有令人困惑的信息: 我希望我的ImageView 通过adjustImageViewBounds() 方法重新居中,该方法本身有效! 居中意味着将我的ImageView 放在Scene 的中间,XY 位置。

提前感谢您的支持。

【问题讨论】:

  • 这看起来你做的工作太多了。结构是什么? HBox 内的 ScrollPane 内的 ImageView?并且要求图像采用其自然大小并且如果其自然大小大于可用空间则可以滚动?
  • 嘿,James_D,可能。我用基本的 Java 编程了一年,但我一点经验都没有,我现在学习 JavaFX 大约 6 个月。我感谢有关我的代码的任何提示!结构如下:HBox 中的 ImageView 和 VBox 以及 ScrollPane 中的 HBox。
  • 并且Image取Scene的宽高的宽高。 preserveRatio 设置为 true。
  • 当我增加窗口的大小时,只要图像小于其“自然”大小,图像就会与场景一起“增长”。当我减小窗口的大小时,它也在缩小,直到达到 minSize。你知道我的意思吗?
  • 不太确定我是否理解这些要求。如果您根据场景大小设置fitWidthfitHeight,听起来您正在尝试确保图像始终完全可见并尽可能大,在这种情况下,您并不清楚为什么需要滚动窗格。我猜你希望它在保持比率力的情况下居中,例如图像周围有一些水平空间?

标签: image javafx imageview


【解决方案1】:

与其使用setTranslateY(...)ImageView 从其父级为其确定的位置移动,不如选择和配置一个首先将其定位为您想要的方式的父级。例如,HBoxVBox 都有一个setAlignment(..) 方法,用于确定父节点中子节点的整体对齐方式。最“通用”(即灵活)的预定义布局是GridPane,其中子节点位于网格中,并且可以跨越网格中的多个单元格。网格中的不同列和行可以有不同的宽度和高度,您可以配置子节点在其分配的单元格的空间大于节点的首选大小时的行为方式。

一些有用的链接:

tutorial 中提供了所有布局窗格的概述。 parleys.com 上提供了关于整体布局机制的稍旧但仍然有用的演示文稿(需要注册)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-09
    • 2020-06-07
    • 2018-09-26
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    相关资源
    最近更新 更多