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.HPos;
  37 
  38 
  39 /**
  40  * Defines optional layout constraints for a column in a {@link GridPane}.
  41  * If a ColumnConstraints object is added for a column in a gridpane, the gridpane
  42  * will use those constraint values when computing the column's width and layout.
  43  * <p>
  44  * For example, to create a GridPane with 5 columns 100 pixels wide:
  45  * <pre><code>
  46  *     GridPane gridpane = new GridPane();
  47  *     for (int i = 0; i < 5; i++) {
  48  *         ColumnConstraints column = new ColumnConstraints(100);
  49  *         gridpane.getColumnConstraints().add(column);
  50  *     }
  51  * </code></pre>
  52  * Or, to create a GridPane where columns take 25%, 50%, 25% of its width:
  53  * <pre><code>
  54  *     GridPane gridpane = new GridPane();
  55  *     ColumnConstraints col1 = new ColumnConstraints();
  56  *     col1.setPercentWidth(25);
  57  *     ColumnConstraints col2 = new ColumnConstraints();
  58  *     col2.setPercentWidth(50);
  59  *     ColumnConstraints col3 = new ColumnConstraints();
  60  *     col3.setPercentWidth(25);
  61  *     gridpane.getColumnConstraints().addAll(col1,col2,col3);
  62  * </code></pre>
  63  *
  64  * Note that adding an empty ColumnConstraints object has the effect of not setting
  65  * any constraints, leaving the GridPane to compute the column's layout based
  66  * solely on its content's size preferences and constraints.
  67  *
  68  * @since JavaFX 2.0
  69  */
  70 public class ColumnConstraints extends ConstraintsBase {
  71 
  72     /**
  73      * Create a column constraint object with no properties set.
  74      */
  75     public ColumnConstraints() {
  76         super();
  77     }
  78 
  79     /**
  80      * Creates a column constraint object with a fixed width.
  81      * This is a convenience for setting the preferred width constraint to the
  82      * fixed value and the minWidth and maxWidth constraints to the USE_PREF_SIZE
  83      * flag to ensure the column is always that width.
  84      *
  85      * @param width the width of the column
  86      */
  87     public ColumnConstraints(double width) {
  88         this();
  89         setMinWidth(USE_PREF_SIZE);
  90         setPrefWidth(width);
  91         setMaxWidth(USE_PREF_SIZE);
  92     }
  93 
  94     /**
  95      * Creates a column constraint object with a fixed size range.
  96      * This is a convenience for setting the minimum, preferred, and maximum
  97      * width constraints.
  98      *
  99      */
 100     public ColumnConstraints(double minWidth, double prefWidth, double maxWidth) {
 101         this();
 102         setMinWidth(minWidth);
 103         setPrefWidth(prefWidth);
 104         setMaxWidth(maxWidth);
 105     }
 106 
 107     /**
 108      * Creates a column constraint object with a fixed size range, horizontal
 109      * grow priority, horizonal alignment, and horizontal fill behavior.
 110      *
 111      */
 112     public ColumnConstraints(double minWidth, double prefWidth, double maxWidth, Priority hgrow, HPos halignment, boolean fillWidth) {
 113         this(minWidth, prefWidth, maxWidth);
 114         setHgrow(hgrow);
 115         setHalignment(halignment);
 116         setFillWidth(fillWidth);
 117     }
 118 
 119     /**
 120      * The minimum width for the column.
 121      * This property is ignored if percentWidth is set.
 122      * <p>
 123      * The default value is USE_COMPUTED_SIZE, which means the minimum width
 124      * will be computed to be the largest minimum width of the column's content.
 125      */
 126     private DoubleProperty minWidth;
 127 
 128     public final void setMinWidth(double value) {
 129         minWidthProperty().set(value);
 130     }
 131 
 132     public final double getMinWidth() {
 133         return minWidth == null ? USE_COMPUTED_SIZE : minWidth.get();
 134     }
 135 
 136     public final DoubleProperty minWidthProperty() {
 137         if (minWidth == null) {
 138             minWidth = new DoublePropertyBase(USE_COMPUTED_SIZE) {
 139 
 140                 @Override
 141                 protected void invalidated() {
 142                     requestLayout();
 143                 }
 144 
 145                 @Override
 146                 public Object getBean() {
 147                     return ColumnConstraints.this;
 148                 }
 149 
 150                 @Override
 151                 public String getName() {
 152                     return "minWidth";
 153                 }
 154             };
 155         }
 156         return minWidth;
 157     }
 158 
 159     /**
 160      * The preferred width for the column.
 161      * This property is ignored if percentWidth is set.
 162      * <p>
 163      * The default value is USE_COMPUTED_SIZE, which means the preferred width
 164      * will be computed to be the largest preferred width of the column's content.
 165      */
 166     private DoubleProperty prefWidth;
 167 
 168     public final void setPrefWidth(double value) {
 169         prefWidthProperty().set(value);
 170     }
 171 
 172     public final double getPrefWidth() {
 173         return prefWidth == null ? USE_COMPUTED_SIZE : prefWidth.get();
 174     }
 175 
 176     public final DoubleProperty prefWidthProperty() {
 177         if (prefWidth == null) {
 178             prefWidth = new DoublePropertyBase(USE_COMPUTED_SIZE) {
 179 
 180                 @Override
 181                 protected void invalidated() {
 182                     requestLayout();
 183                 }
 184 
 185                 @Override
 186                 public Object getBean() {
 187                     return ColumnConstraints.this;
 188                 }
 189 
 190                 @Override
 191                 public String getName() {
 192                     return "prefWidth";
 193                 }
 194             };
 195         }
 196         return prefWidth;
 197     }
 198 
 199     /**
 200      * The maximum width for the column.
 201      * This property is ignored if percentWidth is set.
 202      * <p>
 203      * The default value is USE_COMPUTED_SIZE, which means the maximum width
 204      * will be computed to be the smallest maximum width of the column's content.
 205      */
 206     private DoubleProperty maxWidth;
 207 
 208     public final void setMaxWidth(double value) {
 209         maxWidthProperty().set(value);
 210     }
 211 
 212     public final double getMaxWidth() {
 213         return maxWidth == null ? USE_COMPUTED_SIZE : maxWidth.get();
 214     }
 215 
 216     public final DoubleProperty maxWidthProperty() {
 217         if (maxWidth == null) {
 218             maxWidth = new DoublePropertyBase(USE_COMPUTED_SIZE) {
 219 
 220                 @Override
 221                 protected void invalidated() {
 222                     requestLayout();
 223                 }
 224 
 225                 @Override
 226                 public Object getBean() {
 227                     return ColumnConstraints.this;
 228                 }
 229 
 230                 @Override
 231                 public String getName() {
 232                     return "maxWidth";
 233                 }
 234             };
 235         }
 236         return maxWidth;
 237     }
 238 
 239     /**
 240      * The width percentage of the column.  If set to a value greater than 0,
 241      * the column will be resized to this percentage of the gridpane's available
 242      * width and the other size constraints (minWidth, prefWidth, maxWidth, hgrow)
 243      * will be ignored.
 244      *
 245      * The default value is -1, which means the percentage will be ignored.
 246      */
 247     private DoubleProperty percentWidth;
 248 
 249     public final void setPercentWidth(double value) {
 250         percentWidthProperty().set(value);
 251     }
 252 
 253     public final double getPercentWidth() {
 254         return percentWidth == null ? -1 : percentWidth.get();
 255     }
 256 
 257     public final DoubleProperty percentWidthProperty() {
 258         if (percentWidth == null) {
 259             percentWidth = new DoublePropertyBase(-1) {
 260 
 261                 @Override
 262                 protected void invalidated() {
 263                     requestLayout();
 264                 }
 265 
 266                 @Override
 267                 public Object getBean() {
 268                     return ColumnConstraints.this;
 269                 }
 270 
 271                 @Override
 272                 public String getName() {
 273                     return "percentWidth";
 274                 }
 275             };
 276         }
 277         return percentWidth;
 278     }
 279 
 280 
 281     /**
 282      * The horizontal grow priority for the column.  If set, the gridpane will
 283      * use this priority to determine whether the column should be given any
 284      * additional width if the gridpane is resized larger than its preferred width.
 285      * This property is ignored if percentWidth is set.
 286      * <p>
 287      * This default value is null, which means that the column's grow priority
 288      * will be derived from largest grow priority set on a content node.
 289      */
 290     private ObjectProperty<Priority> hgrow;
 291 
 292     public final void setHgrow(Priority value) {
 293         hgrowProperty().set(value);
 294     }
 295 
 296     public final Priority getHgrow() {
 297         return hgrow == null ? null : hgrow.get();
 298     }
 299 
 300     public final ObjectProperty<Priority> hgrowProperty() {
 301         if (hgrow == null) {
 302             hgrow = new ObjectPropertyBase<Priority>() {
 303 
 304                 @Override
 305                 protected void invalidated() {
 306                     requestLayout();
 307                 }
 308 
 309                 @Override
 310                 public Object getBean() {
 311                     return ColumnConstraints.this;
 312                 }
 313 
 314                 @Override
 315                 public String getName() {
 316                     return "hgrow";
 317                 }
 318             };
 319         }
 320         return hgrow;
 321     }
 322 
 323     /**
 324      * The horizontal alignment for the column. If set, will be the default
 325      * horizontal alignment for nodes contained within the column.
 326      * <p>
 327      * The default value is null, which means the column alignment will fall
 328      * back to the default halignment set on the gridpane.
 329      */
 330     private ObjectProperty<HPos> halignment;
 331 
 332     public final void setHalignment(HPos value) {
 333         halignmentProperty().set(value);
 334     }
 335 
 336     public final HPos getHalignment() {
 337         return halignment == null ? null : halignment.get();
 338     }
 339 
 340     public final ObjectProperty<HPos> halignmentProperty() {
 341         if (halignment == null) {
 342             halignment = new ObjectPropertyBase<HPos>() {
 343 
 344                 @Override
 345                 protected void invalidated() {
 346                     requestLayout();
 347                 }
 348 
 349                 @Override
 350                 public Object getBean() {
 351                     return ColumnConstraints.this;
 352                 }
 353 
 354                 @Override
 355                 public String getName() {
 356                     return "halignment";
 357                 }
 358             };
 359         }
 360         return halignment;
 361     }
 362 
 363     /**
 364      * The horizontal fill policy for the column.  The gridpane will
 365      * use this property to determine whether nodes contained within the column
 366      * should be expanded to fill the column or kept to their preferred widths.
 367      * <p>
 368      * The default value is true.
 369      *
 370      */
 371     private BooleanProperty fillWidth;
 372 
 373     public final void setFillWidth(boolean value) {
 374         fillWidthProperty().set(value);
 375     }
 376 
 377     public final boolean isFillWidth() {
 378         return fillWidth == null ? true : fillWidth.get();
 379     }
 380 
 381     public final BooleanProperty fillWidthProperty() {
 382         if (fillWidth == null) {
 383             fillWidth = new BooleanPropertyBase(true) {
 384 
 385                 @Override
 386                 protected void invalidated() {
 387                     requestLayout();
 388                 }
 389 
 390                 @Override
 391                 public Object getBean() {
 392                     return ColumnConstraints.this;
 393                 }
 394 
 395                 @Override
 396                 public String getName() {
 397                     return "fillWidth";
 398                 }
 399             };
 400         }
 401         return fillWidth;
 402     }
 403 
 404     /**
 405      * Returns a string representation of this {@code ColumnConstraints} object.
 406      * @return a string representation of this {@code ColumnConstraints} object.
 407      */
 408     @Override public String toString() {
 409         return "ColumnConstraints percentWidth="+getPercentWidth()+
 410                 " minWidth="+getMinWidth()+
 411                 " prefWidth="+getPrefWidth()+
 412                 " maxWidth="+getMaxWidth()+
 413                 " hgrow="+getHgrow()+
 414                 " fillWidth="+isFillWidth()+
 415                 " halignment="+getHalignment();
 416     }
 417 }