Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8116841

AnchorPane doesn't fully respect min size of it's children in certain cases

XMLWordPrintable

      Minimum size is not used properly in layout, but it is in rendering. The result is that parent bounds appear to be miscalculated.

      Try the following:


      package layoutbounds;

      import javafx.application.Application;
      import javafx.event.EventHandler;
      import javafx.geometry.Bounds;
      import javafx.geometry.Point2D;
      import javafx.geometry.Pos;
      import javafx.scene.Scene;
      import javafx.scene.control.Label;
      import javafx.scene.input.MouseEvent;
      import javafx.scene.layout.AnchorPane;
      import javafx.scene.layout.BorderPane;
      import javafx.scene.layout.HBox;
      import javafx.scene.layout.Priority;
      import javafx.scene.layout.StackPane;
      import javafx.scene.layout.VBox;
      import javafx.scene.paint.Color;
      import javafx.scene.shape.Rectangle;
      import javafx.stage.Stage;

      /**
       * Resize the child by dragging the green square. JavaFX 2.2 and JavaFX 8
       * behave very differently.
       * @author scott.palmer
       */
      public class LayoutBounds extends Application {

          static class Widget extends AnchorPane {

              private final VBox vbox;
              private final BorderPane contentPane;
              private final AnchorPane contentStack;
              private final StackPane contentWrapper;
              private final AnchorPane childrenGroup;
              private final AnchorPane connectionGroup;
              private final HBox bottomPane;

              public Widget(String title) {
                  vbox = new VBox();
                  vbox.setFillWidth(true);
                  vbox.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
                  AnchorPane.setTopAnchor(vbox, 0.0);
                  AnchorPane.setRightAnchor(vbox, 0.0);
                  AnchorPane.setBottomAnchor(vbox, 0.0);
                  AnchorPane.setLeftAnchor(vbox, 0.0);
                  getChildren().add(vbox);

                  Label titleBar = new Label(title);
                  titleBar.setAlignment(Pos.CENTER);
                  titleBar.setMaxWidth(Double.MAX_VALUE);
                  titleBar.setTextFill(Color.WHITE);
                  titleBar.setStyle("-fx-background-color: BLUE;");
                  vbox.getChildren().add(titleBar);

                  contentStack = new AnchorPane();
                  contentWrapper = new StackPane();

                  bottomPane = new HBox();
                  bottomPane.getChildren().add(new Label("resize->"));
                  
                  contentPane = new BorderPane();
                  contentPane.setBottom(bottomPane);
                  contentPane.setPickOnBounds(false);

                  childrenGroup = new AnchorPane();
                  contentWrapper.getChildren().add(childrenGroup);
                  contentPane.setCenter(contentWrapper);

                  connectionGroup = new AnchorPane();

                  AnchorPane.setTopAnchor(contentPane, 0.0);
                  AnchorPane.setRightAnchor(contentPane, 0.0);
                  AnchorPane.setBottomAnchor(contentPane, 0.0);
                  AnchorPane.setLeftAnchor(contentPane, 0.0);

                  contentStack.getChildren().add(connectionGroup);
                  contentStack.getChildren().add(contentPane);
                  contentStack.setMaxHeight(Double.MAX_VALUE);
                  VBox.setVgrow(contentStack, Priority.ALWAYS);
                  vbox.getChildren().add(contentStack);

                  Rectangle sizer = new Rectangle(16, 16);
                  sizer.setFill(Color.GREENYELLOW);
                  AnchorPane.setRightAnchor(sizer, 0.0);
                  AnchorPane.setBottomAnchor(sizer, 0.0);
                  getChildren().add(sizer);
                  
                  sizer.setOnMouseDragged(resizeDragHandler);
                  setStyle("-fx-background-color: SKYBLUE; -fx-border-color: YELLOW; -fx-border-width: 3px;");
              }

              void addComponent(Widget child) {
                  childrenGroup.getChildren().add(child);
              }

              private EventHandler<MouseEvent> resizeDragHandler = new EventHandler<MouseEvent>() {
                  @Override
                  public void handle(MouseEvent me) {
                      Point2D dragPoint = Widget.this.sceneToLocal(new Point2D(me.getSceneX(), me.getSceneY()));
                      sizeToPoint(dragPoint);
                      me.consume();
                  }
              };
              private void sizeToPoint(Point2D dragPoint) {
                  Bounds bounds = getBoundsInLocal();
                  setMinSize(Math.max(0, dragPoint.getX()-bounds.getMinX()),
                             Math.max(0, dragPoint.getY()-bounds.getMinY()));
              }
          }
          
          @Override
          public void start(Stage primaryStage) {
              Widget rectA = new Widget("Parent");
              Widget rectB = new Widget("Child");
              rectA.addComponent(rectB);
              AnchorPane root = new AnchorPane();
              root.getChildren().add(rectA);
              Scene scene = new Scene(root, 400, 300);
              primaryStage.setTitle("Layout Bounds Issues");
              primaryStage.setScene(scene);
              primaryStage.show();
          }

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

            msladecek Martin Sládeček
            swpalmer Scott Palmer
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported: