/* * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javafx.scene.layout; import java.util.List; import javafx.geometry.Bounds; import javafx.geometry.Insets; import javafx.geometry.Orientation; import javafx.scene.Node; /** * AnchorPane allows the edges of child nodes to be anchored to an offset from * the anchor pane's edges. If the anchor pane has a border and/or padding set, the * offsets will be measured from the inside edge of those insets. *
* AnchorPane lays out each managed child regardless of the child's visible property value; * unmanaged children are ignored for all layout calculations.
** AnchorPanes may be styled with backgrounds and borders using CSS. See * {@link javafx.scene.layout.Region Region} superclass for details.
* ** The application sets anchor constraints on each child to configure the anchors * on one or more sides. If a child is anchored on opposite sides (and is resizable), the * anchor pane will resize it to maintain both offsets, otherwise the anchor pane * will resize it to its preferred size. If in the former case (anchored on opposite * sides) and the child is not resizable, then only the top/left anchor will be honored. * AnchorPane provides a static method for setting each anchor constraint. *
* *Constraint | Type | Description |
---|---|---|
topAnchor | double | distance from the anchor pane's top insets to the child's top edge. |
leftAnchor | double | distance from the anchor pane's left insets to the child's left edge. |
bottomAnchor | double | distance from the anchor pane's bottom insets to the child's bottom edge. |
rightAnchor | double | distance from the anchor pane's right insets to the child's right edge. |
* AnchorPane Example: *
AnchorPane anchorPane = new AnchorPane();
* // List should stretch as anchorPane is resized
* ListView list = new ListView();
* AnchorPane.setTopAnchor(list, 10.0);
* AnchorPane.setLeftAnchor(list, 10.0);
* AnchorPane.setRightAnchor(list, 65.0);
* // Button will float on right edge
* Button button = new Button("Add");
* AnchorPane.setTopAnchor(button, 10.0);
* AnchorPane.setRightAnchor(button, 10.0);
* anchorPane.getChildren().addAll(list, button);
*
*
* * An anchor pane's parent will resize the anchor pane within the anchor pane's resizable range * during layout. By default the anchor pane computes this range based on its content * as outlined in the table below. *
* *width | height | |
---|---|---|
minimum | *left/right insets plus width required to display children anchored at left/right with at least their min widths | *top/bottom insets plus height required to display children anchored at top/bottom with at least their min heights |
preferred | *left/right insets plus width required to display children anchored at left/right with at least their pref widths | *top/bottom insets plus height required to display children anchored at top/bottom with at least their pref heights |
maximum | *Double.MAX_VALUE | Double.MAX_VALUE |
* An anchor pane's unbounded maximum width and height are an indication to the parent that * it may be resized beyond its preferred size to fill whatever space is assigned * to it. *
* AnchorPane provides properties for setting the size range directly. These * properties default to the sentinel value Region.USE_COMPUTED_SIZE, however the * application may set them to other values as needed: *
anchorPane.setPrefSize(300, 300);
*
* Applications may restore the computed values by setting these properties back
* to Region.USE_COMPUTED_SIZE.
* * AnchorPane does not clip its content by default, so it is possible that children's * bounds may extend outside its own bounds if the anchor pane is resized smaller * than its preferred size.
* * @since JavaFX 2.0 */ public class AnchorPane extends Pane { private static final String TOP_ANCHOR = "pane-top-anchor"; private static final String LEFT_ANCHOR = "pane-left-anchor"; private static final String BOTTOM_ANCHOR = "pane-bottom-anchor"; private static final String RIGHT_ANCHOR = "pane-right-anchor"; /******************************************************************** * BEGIN static methods ********************************************************************/ /** * Sets the top anchor for the child when contained by an anchor pane. * If set, the anchor pane will maintain the child's size and position so * that it's top is always offset by that amount from the anchor pane's top * content edge. * Setting the value to null will remove the constraint. * @param child the child node of an anchor pane * @param value the offset from the top of the anchor pane */ public static void setTopAnchor(Node child, Double value) { setConstraint(child, TOP_ANCHOR, value); } /** * Returns the child's top anchor constraint if set. * @param child the child node of an anchor pane * @return the offset from the top of the anchor pane or null if no top anchor was set */ public static Double getTopAnchor(Node child) { return (Double)getConstraint(child, TOP_ANCHOR); } /** * Sets the left anchor for the child when contained by an anchor pane. * If set, the anchor pane will maintain the child's size and position so * that it's left is always offset by that amount from the anchor pane's left * content edge. * Setting the value to null will remove the constraint. * @param child the child node of an anchor pane * @param value the offset from the left of the anchor pane */ public static void setLeftAnchor(Node child, Double value) { setConstraint(child, LEFT_ANCHOR, value); } /** * Returns the child's left anchor constraint if set. * @param child the child node of an anchor pane * @return the offset from the left of the anchor pane or null if no left anchor was set */ public static Double getLeftAnchor(Node child) { return (Double)getConstraint(child, LEFT_ANCHOR); } /** * Sets the bottom anchor for the child when contained by an anchor pane. * If set, the anchor pane will maintain the child's size and position so * that it's bottom is always offset by that amount from the anchor pane's bottom * content edge. * Setting the value to null will remove the constraint. * @param child the child node of an anchor pane * @param value the offset from the bottom of the anchor pane */ public static void setBottomAnchor(Node child, Double value) { setConstraint(child, BOTTOM_ANCHOR, value); } /** * Returns the child's bottom anchor constraint if set. * @param child the child node of an anchor pane * @return the offset from the bottom of the anchor pane or null if no bottom anchor was set */ public static Double getBottomAnchor(Node child) { return (Double)getConstraint(child, BOTTOM_ANCHOR); } /** * Sets the right anchor for the child when contained by an anchor pane. * If set, the anchor pane will maintain the child's size and position so * that it's right is always offset by that amount from the anchor pane's right * content edge. * Setting the value to null will remove the constraint. * @param child the child node of an anchor pane * @param value the offset from the right of the anchor pane */ public static void setRightAnchor(Node child, Double value) { setConstraint(child, RIGHT_ANCHOR, value); } /** * Returns the child's right anchor constraint if set. * @param child the child node of an anchor pane * @return the offset from the right of the anchor pane or null if no right anchor was set */ public static Double getRightAnchor(Node child) { return (Double)getConstraint(child, RIGHT_ANCHOR); } /** * Removes all anchor pane constraints from the child node. * @param child the child node */ public static void clearConstraints(Node child) { setTopAnchor(child, null); setRightAnchor(child, null); setBottomAnchor(child, null); setLeftAnchor(child, null); } /******************************************************************** * END static methods ********************************************************************/ /** * Creates an AnchorPane layout. */ public AnchorPane() { super(); } /** * Creates an AnchorPane layout with the given children. * @param children The initial set of children for this pane. * @since JavaFX 8.0 */ public AnchorPane(Node... children) { super(); getChildren().addAll(children); } @Override protected double computeMinWidth(double height) { return computeWidth(true, height); } @Override protected double computeMinHeight(double width) { return computeHeight(true, width); } @Override protected double computePrefWidth(double height) { return computeWidth(false, height); } @Override protected double computePrefHeight(double width) { return computeHeight(false, width); } private double computeWidth(final boolean minimum, final double height) { double max = 0; double contentHeight = height != -1 ? height - getInsets().getTop() - getInsets().getBottom() : -1; final List