Как подогнать ImageView к дочернему узлу GridPane - PullRequest
0 голосов
/ 05 июня 2018

Я использую SceneBuilder для создания вида моей программы.Мне нужно иметь изображения внутри узлов (ячеек) GridPane, но проблема в том, что они должны быть вписаны в ячейку.

Другими словами, как только я изменяю размер окна приложения, gridPade изменяет размеры соответственно, но изображения внутри ячеек остаются фиксированными до того же размера.Наличие окна приложения и всех его элементов с изменяемым размером также является требованием, которое мне было дано, поэтому я не могу управлять представлением по-другому.

1 Ответ

0 голосов
/ 05 июня 2018

Используйте ImageView.fitWidth и ImageView.fitHeight, чтобы установить размер изображения.Предполагая, что дети вашего GridPane вытягивают Region, вы можете сделать это в методе layoutChildren:

public class ImageCell extends Region {
    private final ImageView imageView;

    public ImageCell(Image image) {
        imageView = new ImageView(image);
        getChildren().add(imageView);
    }

    public ImageCell() {
        this(null);
    }

    public final void setImage(Image value) {
        imageView.setImage(value);
    }

    public final Image getImage() {
        return imageView.getImage();
    }

    public final ObjectProperty<Image> imageProperty() {
        return imageView.imageProperty();
    }

    @Override
    protected void layoutChildren() {
        super.layoutChildren();
        Insets insets = getInsets();
        double x = insets.getLeft();
        double y = insets.getTop();
        double width = getWidth() - x - insets.getRight();
        double height = getHeight() - y - insets.getBottom();

        Image image = getImage();
        double imageWidth = 0;
        double imageHeight = 0;
        if (image != null) {
            imageWidth = image.getWidth();
            imageHeight = image.getHeight();
        }

        // scale ImageView to available size
        double factor = Math.min(width / imageWidth, height / imageHeight);
        if (Double.isFinite(factor) && factor > 0) {
            imageView.setFitHeight(factor * imageHeight);
            imageView.setFitWidth(factor * imageWidth);
            imageView.setVisible(true);
        } else {
            imageView.setVisible(false);
        }

        // center ImageView in available area
        layoutInArea(imageView, x, y, width, height, 0, HPos.CENTER, VPos.CENTER);
    }

}

Чтобы заполнить область, вам просто нужно убедиться, что GridPane выращивает детей:

@Override
public void start(Stage primaryStage) throws Exception {
    GridPane gridPane = new GridPane();
    RowConstraints rowConstraints = new RowConstraints();
    rowConstraints.setPercentHeight(50);
    ColumnConstraints columnConstraints = new ColumnConstraints();
    columnConstraints.setPercentWidth(50);

    gridPane.getRowConstraints().addAll(rowConstraints, rowConstraints);
    gridPane.getColumnConstraints().addAll(columnConstraints, columnConstraints);
    gridPane.addRow(0, new ImageCell(new Image("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/se/se-icon.png")),
            new ImageCell(new Image("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-icon.png")));
    gridPane.addRow(1, new ImageCell(new Image("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/sf/sf-icon.png")),
            new ImageCell(new Image("https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/su/su-icon.png")));

    primaryStage.setScene(new Scene(gridPane));
    primaryStage.show();
}
...