如何使javafx 8滚动窗格的内容居中

时间:2015-06-06 22:03:44

标签: javafx-8

我有一个ScrollPane,它包含一个GridPane,其中包含一个ImageView,其中包含一个Image。我想要的是图像在GridPane中居中。

没有ScrollPane,我可以使用setAlignment(Pos.TOP_CENTER)完成此操作,但是一旦我将GridPane添加到ScrollPane,图像就会显示在左上角。

如何让ScrollPane使用setAlignment()值或手动居中图像?

---示例编辑---

没有滚动窗格的代码:

public class ImageDB extends Application
{
  @Override
  public void start(Stage root)
  {
    Image image = new Image("0.jpg");
    ImageView view = new ImageView();
    view.setImage(image);

    GridPane grid = new GridPane();
    grid.getChildren().add(view);

    grid.setAlignment(Pos.TOP_CENTER);

    BorderPane border = new BorderPane();
    border.setCenter(grid);

    root.setScene(new Scene(border));
    root.setMaximized(true);
    root.show();
  }
}

结果: https://i.imgur.com/eWvBQy6.png

带滚动窗格的

代码:

public class ImageDB extends Application
{
  @Override
  public void start(Stage root)
  {
    Image image = new Image("0.jpg");
    ImageView view = new ImageView();
    view.setImage(image);

    ScrollPane scroll = new ScrollPane();
    scroll.setContent(view);

    GridPane grid = new GridPane();
    grid.getChildren().add(scroll);

    grid.setAlignment(Pos.TOP_CENTER);

    BorderPane border = new BorderPane();
    border.setCenter(scroll);

    root.setScene(new Scene(border));
    root.setMaximized(true);
    root.show();
  }
}

结果: https://i.imgur.com/1aJDX4m.png

4 个答案:

答案 0 :(得分:7)

虽然imageHolder.minWidthProperty().bind(Bindings.createDoubleBinding(() -> scroll.getViewportBounds().getWidth(), scroll.viewportBoundsProperty()));确实可以解决问题,但似乎存在一些问题(例如,有时会显示错误的滚动条/闪烁内容等)。

我发现简单的scroll.setFitToWidth(true);(和/或scroll.setFitToHeight(true);)也会使滚动窗格保持内容大小,但没有上述问题!

答案 1 :(得分:5)

当网格窗格以滚动窗格为中心时,图像视图位于滚动窗格的左上角。

一种解决方法是将图像视图包装在堆栈窗格中(默认居中),并确保堆栈窗格至少与滚动窗格的视口一样宽:

SSCCE:

import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class ImageDB extends Application
{
  @Override
  public void start(Stage root)
  {
//    Image image = new Image("0.jpg");
    Image image = createImage();
    ImageView view = new ImageView();
    view.setImage(image);
    StackPane imageHolder = new StackPane(view);

    ScrollPane scroll = new ScrollPane();
    scroll.setContent(imageHolder);

    GridPane grid = new GridPane();

    imageHolder.minWidthProperty().bind(Bindings.createDoubleBinding(() -> 
        scroll.getViewportBounds().getWidth(), scroll.viewportBoundsProperty()));
    grid.getChildren().add(imageHolder);

//    grid.setAlignment(Pos.TOP_CENTER);

    BorderPane border = new BorderPane();
    border.setCenter(scroll);

    root.setScene(new Scene(border));
    root.setMaximized(true);
    root.show();
  }

  private Image createImage() {
      return new Rectangle(400, 200, Color.CORNFLOWERBLUE).snapshot(null, null);
  }

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

答案 2 :(得分:0)

通过viewportBoundsProperty提供更好的解决方案:

import javafx.application.Application;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class ImageDB extends Application {
    final static int WIDTH = 400;
    final static int HEIGHT = 200;

    @Override
    public void start(Stage root) {
        // Image image = new Image("0.jpg");
        Image image = this.createImage();
        ImageView view = new ImageView();
        view.setImage(image);
        GridPane grid = new GridPane();
        grid.getChildren().add(view);

        ScrollPane scroll = new ScrollPane();
        scroll.setContent(grid);

        BorderPane border = new BorderPane();
        border.setCenter(scroll);

        this.center(scroll.getViewportBounds(), grid);
        scroll.viewportBoundsProperty().addListener((observable, oldValue, newValue) -> {
            this.center(newValue, grid);
        });

        root.setScene(new Scene(border));
        root.setMaximized(true);
        root.show();
    }

    private Image createImage() {
        return new Rectangle(ImageDB.WIDTH, ImageDB.HEIGHT, Color.CORNFLOWERBLUE).snapshot(null, null);
    }

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

    private void center(Bounds viewPortBounds, Node centeredNode) {
        double width = viewPortBounds.getWidth();
        double height = viewPortBounds.getHeight();
        if (width > ImageDB.WIDTH) {
            centeredNode.setTranslateX((width - ImageDB.WIDTH) / 2);
        } else {
            centeredNode.setTranslateX(0);
        }
        if (height > ImageDB.HEIGHT) {
            centeredNode.setTranslateY((height - ImageDB.HEIGHT) / 2);
        } else {
            centeredNode.setTranslateY(0);
        }

    }

}

答案 3 :(得分:0)

在某些情况下,这可能有所帮助:

<ScrollPane fitToWidth="true" fitToHeight="true">