1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.layout;
  27 
  28 import static javafx.scene.layout.Region.USE_COMPUTED_SIZE;
  29 import static javafx.scene.layout.Region.USE_PREF_SIZE;
  30 import javafx.beans.property.BooleanProperty;
  31 import javafx.beans.property.BooleanPropertyBase;
  32 import javafx.beans.property.DoubleProperty;
  33 import javafx.beans.property.DoublePropertyBase;
  34 import javafx.beans.property.ObjectProperty;
  35 import javafx.beans.property.ObjectPropertyBase;
  36 import javafx.geometry.VPos;
  37 
  38 
  39 /**
  40  * Defines optional layout constraints for a row in a {@link GridPane}.
  41  * If a RowConstraints object is added for a row in a gridpane, the gridpane
  42  * will use those constraint values when computing the row's height and layout.
  43  * <p>
  44  * For example, to create a GridPane with 10 rows 50 pixels tall:
  45  * <pre><code>
  46  *     GridPane gridpane = new GridPane();
  47  *     for (int i = 0; i < 10; i++) {
  48  *         RowConstraints row = new RowConstraints(50);
  49  *         gridpane.getRowConstraints().add(row);
  50  *     }
  51  * </code></pre>
  52  * Or, to create a GridPane where rows take 25%, 50%, 25% of its width:
  53  * <pre><code>
  54  *     GridPane gridpane = new GridPane();
  55  *     RowConstraints row1 = new RowConstraints();
  56  *     row1.setPercentWidth(25);
  57  *     RowConstraints row2 = new RowConstraints();
  58  *     row2.setPercentWidth(50);
  59  *     RowConstraints row3 = new RowConstraints();
  60  *     row3.setPercentWidth(25);
  61  *     gridpane.getRowConstraints().addAll(row1,row2,row3);
  62  * </code></pre>
  63  *
  64  * Note that adding an empty RowConstraints object has the effect of not setting
  65  * any constraints, leaving the GridPane to compute the row's layout based
  66  * solely on its content's size preferences and constraints.
  67  *
  68  * @since JavaFX 2.0
  69  */
  70 public class RowConstraints extends ConstraintsBase {
  71 
  72     /**
  73      * Creates a row constraints object with no properties set.
  74      */
  75     public RowConstraints() {
  76         super();
  77     }
  78 
  79     /**
  80      * Creates a row constraint object with a fixed height.
  81      * This is a convenience for setting the preferred height constraint to the
  82      * fixed value and the minHeight and maxHeight constraints to the USE_PREF_SIZE
  83      * flag to ensure the row is always that height.
  84      *
  85      * @param height the height of the row
  86      */
  87     public RowConstraints(double height) {
  88         this();
  89         setMinHeight(USE_PREF_SIZE);
  90         setPrefHeight(height);
  91         setMaxHeight(USE_PREF_SIZE);
  92     }
  93 
  94     /**
  95      * Creates a row constraint object with a fixed size range.
  96      * This is a convenience for setting the minimum, preferred, and maximum
  97      * height constraints.
  98      *
  99      */
 100     public RowConstraints(double minHeight, double prefHeight, double maxHeight) {
 101         this();
 102         setMinHeight(minHeight);
 103         setPrefHeight(prefHeight);
 104         setMaxHeight(maxHeight);
 105     }
 106 
 107     /**
 108      * Creates a row constraint object with a fixed size range, vertical
 109      * grow priority, vertical alignment, and vertical fill behavior.
 110      *
 111      */
 112     public RowConstraints(double minHeight, double prefHeight, double maxHeight, Priority vgrow, VPos valignment, boolean fillHeight) {
 113         this(minHeight, prefHeight, maxHeight);
 114         setVgrow(vgrow);
 115         setValignment(valignment);
 116         setFillHeight(fillHeight);
 117     }
 118 
 119     /**
 120      * The minimum height for the row.
 121      * This property is ignored if percentHeight is set.
 122      * <p>
 123      * The default value is USE_COMPUTED_SIZE, which means the minimum height
 124      * will be computed to be the largest minimum height of the row's content.
 125      */
 126     private DoubleProperty minHeight;
 127 
 128     public final void setMinHeight(double value) {
 129         minHeightProperty().set(value);
 130     }
 131 
 132     public final double getMinHeight() {
 133         return minHeight == null ? USE_COMPUTED_SIZE : minHeight.get();
 134     }
 135 
 136     public final DoubleProperty minHeightProperty() {
 137         if (minHeight == null) {
 138             minHeight = new DoublePropertyBase(USE_COMPUTED_SIZE) {
 139 
 140                 @Override
 141                 protected void invalidated() {
 142                     requestLayout();
 143                 }
 144 
 145                 @Override
 146                 public Object getBean() {
 147                     return RowConstraints.this;
 148                 }
 149 
 150                 @Override
 151                 public String getName() {
 152                     return "minHeight";
 153                 }
 154             };
 155         }
 156         return minHeight;
 157     }
 158 
 159     /**
 160      * The preferred height for the row.
 161      * This property is ignored if percentHeight is set.
 162      * <p>
 163      * The default value is USE_COMPUTED_SIZE, which means the preferred height
 164      * will be computed to be the largest preferred height of the row's content.
 165      */
 166     private DoubleProperty prefHeight;
 167 
 168     public final void setPrefHeight(double value) {
 169         prefHeightProperty().set(value);
 170     }
 171 
 172     public final double getPrefHeight() {
 173         return prefHeight == null ? USE_COMPUTED_SIZE : prefHeight.get();
 174     }
 175 
 176     public final DoubleProperty prefHeightProperty() {
 177         if (prefHeight == null) {
 178             prefHeight = new DoublePropertyBase(USE_COMPUTED_SIZE) {
 179 
 180                 @Override
 181                 protected void invalidated() {
 182                     requestLayout();
 183                 }
 184 
 185                 @Override
 186                 public Object getBean() {
 187                     return RowConstraints.this;
 188                 }
 189 
 190                 @Override
 191                 public String getName() {
 192                     return "prefHeight";
 193                 }
 194             };
 195         }
 196         return prefHeight;
 197     }
 198 
 199     /**
 200      * The maximum height for the row.
 201      * This property is ignored if percentHeight is set.
 202      * <p>
 203      * The default value is USE_COMPUTED_SIZE, which means the maximum height
 204      * will be computed to be the smallest maximum height of the row's content.
 205      */
 206     private DoubleProperty maxHeight;
 207 
 208     public final void setMaxHeight(double value) {
 209         maxHeightProperty().set(value);
 210     }
 211 
 212     public final double getMaxHeight() {
 213         return maxHeight == null ? USE_COMPUTED_SIZE : maxHeight.get();
 214     }
 215 
 216     public final DoubleProperty maxHeightProperty() {
 217         if (maxHeight == null) {
 218             maxHeight = new DoublePropertyBase(USE_COMPUTED_SIZE) {
 219 
 220                 @Override
 221                 protected void invalidated() {
 222                     requestLayout();
 223                 }
 224 
 225                 @Override
 226                 public Object getBean() {
 227                     return RowConstraints.this;
 228                 }
 229 
 230                 @Override
 231                 public String getName() {
 232                     return "maxHeight";
 233                 }
 234             };
 235         }
 236         return maxHeight;
 237     }
 238 
 239     /**
 240      * The height percentage of the row.  If set to a value greater than 0, the
 241      * row will be resized to that percentage of the available gridpane height and
 242      * the other size constraints (minHeight, prefHeight, maxHeight, vgrow) will
 243      * be ignored.
 244      *
 245      * The default value is -1, which means the percentage will be ignored.
 246      */
 247     private DoubleProperty percentHeight;
 248 
 249     public final void setPercentHeight(double value) {
 250         percentHeightProperty().set(value);
 251     }
 252 
 253     public final double getPercentHeight() {
 254         return percentHeight == null ? -1 : percentHeight.get();
 255     }
 256 
 257     public final DoubleProperty percentHeightProperty() {
 258         if (percentHeight == null) {
 259             percentHeight = new DoublePropertyBase(-1) {
 260 
 261                 @Override
 262                 protected void invalidated() {
 263                     requestLayout();
 264                 }
 265 
 266                 @Override
 267                 public Object getBean() {
 268                     return RowConstraints.this;
 269                 }
 270 
 271                 @Override
 272                 public String getName() {
 273                     return "percentHeight";
 274                 }
 275             };
 276         }
 277         return percentHeight;
 278     }
 279 
 280     /**
 281      * The vertical grow priority for the row.  If set, the gridpane will
 282      * use this priority to determine whether the row should be given any
 283      * additional height if the gridpane is resized larger than its preferred height.
 284      * This property is ignored if percentHeight is set.
 285      * <p>
 286      * This default value is null, which means that the row's grow priority
 287      * will be derived from largest grow priority set on a content node.
 288      */
 289     private ObjectProperty<Priority> vgrow;
 290 
 291     public final void setVgrow(Priority value) {
 292         vgrowProperty().set(value);
 293     }
 294 
 295     public final Priority getVgrow() {
 296         return vgrow == null ? null : vgrow.get();
 297     }
 298 
 299     public final ObjectProperty<Priority> vgrowProperty() {
 300         if (vgrow == null) {
 301             vgrow = new ObjectPropertyBase<Priority>() {
 302 
 303                 @Override
 304                 protected void invalidated() {
 305                     requestLayout();
 306                 }
 307 
 308                 @Override
 309                 public Object getBean() {
 310                     return RowConstraints.this;
 311                 }
 312 
 313                 @Override
 314                 public String getName() {
 315                     return "vgrow";
 316                 }
 317             };
 318         }
 319         return vgrow;
 320     }
 321 
 322     /**
 323      * The vertical alignment for the row. If set, will be the default
 324      * vertical alignment for nodes contained within the row.
 325      * If this property is set to VPos.BASELINE, then the fillHeight property
 326      * will be ignored and nodes will always be resized to their preferred heights.
 327      */
 328     private ObjectProperty<VPos> valignment;
 329 
 330     public final void setValignment(VPos value) {
 331         valignmentProperty().set(value);
 332     }
 333 
 334     public final VPos getValignment() {
 335         return valignment == null ? null : valignment.get();
 336     }
 337 
 338     public final ObjectProperty<VPos> valignmentProperty() {
 339         if (valignment == null) {
 340             valignment = new ObjectPropertyBase<VPos>() {
 341 
 342                 @Override
 343                 protected void invalidated() {
 344                     requestLayout();
 345                 }
 346 
 347                 @Override
 348                 public Object getBean() {
 349                     return RowConstraints.this;
 350                 }
 351 
 352                 @Override
 353                 public String getName() {
 354                     return "valignment";
 355                 }
 356             };
 357         }
 358         return valignment;
 359     }
 360 
 361     /**
 362      * The vertical fill policy for the row.  The gridpane will
 363      * use this property to determine whether nodes contained within the row
 364      * should be expanded to fill the row's height or kept to their preferred heights.
 365      * <p>
 366      * The default value is true.
 367      */
 368     private BooleanProperty fillHeight;
 369 
 370     public final void setFillHeight(boolean value) {
 371         fillHeightProperty().set(value);
 372     }
 373 
 374     public final boolean isFillHeight() {
 375         return fillHeight == null ? true : fillHeight.get();
 376     }
 377 
 378     public final BooleanProperty fillHeightProperty() {
 379         if (fillHeight == null) {
 380             fillHeight = new BooleanPropertyBase(true) {
 381                 @Override
 382                 protected void invalidated() {
 383                     requestLayout();
 384                 }
 385 
 386                 @Override
 387                 public Object getBean() {
 388                     return RowConstraints.this;
 389                 }
 390 
 391                 @Override
 392                 public String getName() {
 393                     return "fillHeight";
 394                 }
 395             };
 396         }
 397         return fillHeight;
 398     }
 399 
 400     /**
 401      * Returns a string representation of this {@code RowConstraints} object.
 402      * @return a string representation of this {@code RowConstraints} object.
 403      */
 404     @Override public String toString() {
 405         return "RowConstraints percentHeight="+getPercentHeight()+
 406                 " minHeight="+getMinHeight()+
 407                 " prefHeight="+getPrefHeight()+
 408                 " maxHeight="+getMaxHeight()+
 409                 " vgrow="+getVgrow()+
 410                 " fillHeight="+isFillHeight()+
 411                 " valignment="+getValignment();
 412     }
 413 }