JavaFX - 在中心调整ImageView

时间:2016-10-10 16:43:54

标签: image javafx imageview

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

每当Image中显示新的ImageViewer时(当用户点击“上一个”或“下一个”时),ImageViewer就会在其Parent中被重新定位节点,在这种情况下它是HBox。我正在使用setTranslate方法并且它工作正常,但它无法正常工作,因为ImageView每次加载新的Image时都会采用不同的位置。

我正在使用此方法重新定位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()方法进行重新定位,这种方法可以自行运行! Recenter意味着将ImageView放在Scene的中间位置,XY位置。

提前感谢您的支持。

1 个答案:

答案 0 :(得分:1)

使用ImageView而不是将setTranslateY(...)从其父级确定的位置移开,而选择和配置父级的方式几乎肯定会更好想要在第一时间。例如,HBoxVBox都有一个setAlignment(..)方法,用于确定父节点内子节点的整体对齐方式。最常见的&#34;一般&#34; (即灵活的)预定义布局是GridPane,其中子节点位于网格中,并且可以跨越网格中的多个单元。网格中的不同列和行可以具有不同的宽度和高度,并且您可以配置子节点在其分配的单元格具有比节点的首选大小更多的空间时的行为。

一些有用的链接:

tutorial中给出了所有布局窗格的概述。有关整体布局机制的略有陈旧但仍然有用的演示文稿可在parleys.com上找到(需要注册)。