【问题标题】:Resizing images to fit the parent node调整图像大小以适合父节点
【发布时间】:2012-09-19 18:21:57
【问题描述】:

如何让 ImageView 中的图像自动调整大小以使其始终适合父节点?

这是一个小代码示例:

@Override
public void start(Stage stage) throws Exception {
    BorderPane pane = new BorderPane();
    ImageView img = new ImageView("http://...");

    //didn't work for me:
    //img.fitWidthProperty().bind(new SimpleDoubleProperty(stage.getWidth())); 

    pane.setCenter(img);

    Scene scene = new Scene(pane);
    stage.setScene(scene);
    stage.show();
}

【问题讨论】:

标签: imageview javafx-2 scaling


【解决方案1】:
@Override
public void start(Stage stage) throws Exception {
    BorderPane pane = new BorderPane();
    ImageView img = new ImageView("http://...");

    img.fitWidthProperty().bind(stage.widthProperty()); 

    pane.setCenter(img);

    Scene scene = new Scene(pane);
    stage.setScene(scene);
    stage.show();
}

【讨论】:

  • JavaFX2 很简单,但并不总是一目了然。一旦你习惯了这些概念,它就会变得轻而易举。
  • *facepalm* 真的吗?布局系统自己做不到?
  • 我在 ImageView 上遇到了类似的问题,因为它确实 not 自动适应其父级。我现在需要一种方法来获得最大可用宽度和高度(我的布局要复杂得多,所以不能简单地采用舞台或 BorderPane 的宽度)。我找到的最简单的解决方案是将 ImageView 包装在一个 VBox 中,幸运的是它默认适合其父级,并将 ImageView 的大小属性绑定到 VBox 的大小属性(类似于上面的代码)。
  • 如何在 fxml 中设置
  • 我选择了:img.setPreserveRatio(true); img.fitWidthProperty().bind(stage.widthProperty()); img.fitHeightProperty().bind(stage.heightProperty());
【解决方案2】:

使用 ScrollPane 或简单的 Pane 来解决这个问题: 示例:

 img_view1.fitWidthProperty().bind(scrollpane_imageview1.widthProperty()); 
 img_view1.fitHeightProperty().bind(scrollpane_imageview1.heightProperty());

【讨论】:

  • 如何在 FXML 中设置?
  • 不起作用。如果我调整窗口大小,窗格的宽度和高度保持不变,因此图像视图也保持不变。
【解决方案3】:

这是一个比绑定 width 属性更好的解决方案(更好,因为通常在将子项绑定到其容器时,可能无法使容器更小。在其他情况下,容器甚至可能会自动开始增长)。

下面的解决方案依赖于覆盖 ImageView,以便我们可以让它表现为“可调整大小”,然后提供最小、首选和最大宽度/高度的实现。同样重要的是实际实现 resize() 调用。

class WrappedImageView extends ImageView
{
    WrappedImageView()
    {
        setPreserveRatio(false);
    }

    @Override
    public double minWidth(double height)
    {
        return 40;
    }

    @Override
    public double prefWidth(double height)
    {
        Image I=getImage();
        if (I==null) return minWidth(height);
        return I.getWidth();
    }

    @Override
    public double maxWidth(double height)
    {
        return 16384;
    }

    @Override
    public double minHeight(double width)
    {
        return 40;
    }

    @Override
    public double prefHeight(double width)
    {
        Image I=getImage();
        if (I==null) return minHeight(width);
        return I.getHeight();
    }

    @Override
    public double maxHeight(double width)
    {
        return 16384;
    }

    @Override
    public boolean isResizable()
    {
        return true;
    }

    @Override
    public void resize(double width, double height)
    {
        setFitWidth(width);
        setFitHeight(height);
    }
}

【讨论】:

  • 谢谢,这对您很有帮助
  • 对于像我这样也想要居中的人,请看这里stackoverflow.com/questions/32781362/…;代替 setX setY 使用 setTranslateX setTranslateY,将中心调用放在 resize 方法中。
  • 如何将它与@FXML 文件一起使用?
【解决方案4】:

如果您希望 ImageView 适合 Windows 框架,请使用以下代码行: imageView.fitWidthProperty().bind(scene.widthProperty()).

请注意,我使用的是场景的 widthProperty 而不是舞台。 示例:

import java.io.FileNotFoundException;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.stage.Stage;

public class MapViewer extends Application {

    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws FileNotFoundException {
        String strTitle = "Titulo de la Ventana";
        int w_width = 800;
        int w_height = 412;
        primaryStage.setTitle(strTitle);
        primaryStage.setWidth(w_width);
        primaryStage.setHeight(w_height);

        Group root = new Group();
        Scene scene = new Scene(root);

        final ImageView imv = new ImageView("file:C:/Users/utp/Documents/1.2008.png");
        imv.fitWidthProperty().bind(scene.widthProperty());
        imv.setPreserveRatio(true);

        root.getChildren().add(imv);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

}

舞台(primaryStage)的宽高比应该与图像(1.2008.png)的宽高比相似

【讨论】:

    【解决方案5】:

    这是一种计算宽度的方法,去除滚动条的宽度。

    第一:
    myImageView.setPreserveRatio(true);

    监控滚动条宽度变化:

    scrollPane.widthProperty().addListener((observable, oldValue, newValue) -> {
                myImageView.setFitWidth(newValue.doubleValue() - (oldValue.doubleValue() - scrollPane.getViewportBounds().getWidth()));
            });
    

    滚动条宽度:
    oldValue.doubleValue() - scrollPane.getViewportBounds().getWidth()

    如何设置初始宽度?
    primaryStage.show(); 之后

    myImageView.setFitWidth(scrollPane.getViewportBounds().getWidth());

    【讨论】:

      【解决方案6】:

      填充父级宽高比,这解决了父级高度和宽度不像图像那样处于适当比例时的问题。

      Image image = new Image(getClass().getResource(%path%).toString());
      double ratio = image.getWidth() / image.getHeight();
      double width = stage.getScene().getWidth();
      
      ImageView imageView.setImage(image);
      imageView.setFitWidth(width);
      imageView.setFitHeight(width/ratio);
      imageView.setPreserveRatio(true);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-05
        • 2013-12-21
        • 1970-01-01
        • 2014-01-27
        相关资源
        最近更新 更多