modules/controls/src/main/java/javafx/scene/control/ButtonBar.java

Print this page
rev 9240 : 8076423: JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization


   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 package javafx.scene.control;
  26 
  27 import javafx.beans.InvalidationListener;
  28 import javafx.beans.Observable;
  29 import javafx.beans.property.DoubleProperty;
  30 import javafx.beans.property.ObjectProperty;
  31 import javafx.beans.property.SimpleDoubleProperty;
  32 import javafx.beans.property.SimpleObjectProperty;
  33 import javafx.beans.property.SimpleStringProperty;
  34 import javafx.beans.property.StringProperty;
  35 import javafx.collections.FXCollections;
  36 import javafx.collections.ObservableList;
  37 import javafx.scene.Node;
  38 import javafx.scene.layout.HBox;
  39 
  40 import com.sun.javafx.util.Utils;
  41 import com.sun.javafx.scene.control.skin.ButtonBarSkin;
  42 import com.sun.javafx.scene.traversal.Algorithm;
  43 import com.sun.javafx.scene.traversal.Direction;
  44 import com.sun.javafx.scene.traversal.ParentTraversalEngine;
  45 import com.sun.javafx.scene.traversal.TraversalContext;
  46 import javafx.beans.value.WritableValue;
  47 import javafx.css.StyleableProperty;
  48 
  49 import java.util.Map;
  50 
  51 /**
  52  * A ButtonBar is essentially a {@link HBox}, with the additional functionality
  53  * for operating system specific button placement. In other words, any Node may
  54  * be annotated (via the {@link ButtonBar#setButtonData(Node, ButtonData)}
  55  * method, placed inside a ButtonBar (via the {@link #getButtons()} list), and will
  56  * then be positioned relative to all other nodes in the button list based on their
  57  * annotations, as well as the overarching
  58  * {@link #buttonOrderProperty() button order} specified for the ButtonBar.
  59  * 
  60  * <strong>Uniform button sizing</strong>
  61  * <p>By default all buttons are uniformly sized in a ButtonBar, meaning that all
  62  * buttons take the width of the widest button. It is possible to opt-out of this
  63  * on a per-button basis, but calling the {@link #setButtonUniformSize(Node, boolean)} method with
  64  * a boolean value of false.
  65  * 


 350          * a comment stating this in their javadoc.
 351          */
 352         public final boolean isDefaultButton() {
 353             return defaultButton;
 354         }
 355     }
 356     
 357 
 358     /**
 359      * Sets the given ButtonData on the given button. If this button is
 360      * subsequently placed in a {@link ButtonBar} it will be placed in the 
 361      * correct position relative to all other buttons in the bar.
 362      * 
 363      * @param button The button to annotate with the given {@link ButtonData} value.
 364      * @param buttonData The ButtonData to designate the button as.
 365      */
 366     public static void setButtonData(Node button, ButtonData buttonData) {
 367         final Map<Object,Object> properties = button.getProperties();
 368         final ObjectProperty<ButtonData> property =
 369                 (ObjectProperty<ButtonData>) properties.getOrDefault(
 370                         ButtonBarSkin.BUTTON_DATA_PROPERTY,
 371                         new SimpleObjectProperty<>(button, "buttonData", buttonData));
 372 
 373         property.set(buttonData);
 374         properties.putIfAbsent(ButtonBarSkin.BUTTON_DATA_PROPERTY, property);
 375     }
 376     
 377     /**
 378      * Returns the previously set ButtonData property on the given button. If this
 379      * was never set, this method will return null. 
 380      *       
 381      * @param button The button to return the previously set ButtonData for.
 382      */
 383     public static ButtonData getButtonData(Node button) {
 384         final Map<Object,Object> properties = button.getProperties();
 385         if (properties.containsKey(ButtonBarSkin.BUTTON_DATA_PROPERTY)) {
 386             ObjectProperty<ButtonData> property = (ObjectProperty<ButtonData>) properties.get(ButtonBarSkin.BUTTON_DATA_PROPERTY);
 387             return property == null ? null : property.get();
 388         }
 389         return null;
 390     }
 391 
 392     /**
 393      * By default all buttons are uniformly sized in a ButtonBar, meaning that all
 394      * buttons take the width of the widest button. It is possible to opt-out of this
 395      * on a per-button basis, but calling the setButtonUniformSize method with
 396      * a boolean value of false.
 397      * 
 398      * <p>If a button is excluded from uniform sizing, it is both excluded from
 399      * being resized away from its preferred size, and also excluded from the
 400      * measuring process, so its size will not influence the maximum size calculated
 401      * for all buttons in the ButtonBar.
 402      * 
 403      * @param button The button to include / exclude from uniform sizing.
 404      * @param uniformSize Boolean true to force uniform sizing on the button, 
 405      *        false to exclude the button from uniform sizing.
 406      */
 407     public static void setButtonUniformSize(Node button, boolean uniformSize) {
 408         // we store the false, but remove the true (as the isButtonUniformSize 
 409         // method returns true by default)
 410         if (uniformSize) {
 411             button.getProperties().remove(ButtonBarSkin.BUTTON_SIZE_INDEPENDENCE);
 412         } else {
 413             button.getProperties().put(ButtonBarSkin.BUTTON_SIZE_INDEPENDENCE, uniformSize);
 414         }
 415     }
 416     
 417     /**
 418      * Returns whether the given node is part of the uniform sizing calculations
 419      * or not. By default all nodes that have not opted out (via 
 420      * {@link #setButtonUniformSize(Node, boolean)}) will return true here.
 421      */
 422     public static boolean isButtonUniformSize(Node button) {
 423         return (boolean) button.getProperties().getOrDefault(ButtonBarSkin.BUTTON_SIZE_INDEPENDENCE, true);
 424     }
 425 
 426 
 427 
 428     /**************************************************************************
 429      * 
 430      * Private fields
 431      * 
 432      **************************************************************************/
 433 
 434     private ObservableList<Node> buttons = FXCollections.<Node>observableArrayList();
 435 
 436 
 437 
 438     /**************************************************************************
 439      * 
 440      * Constructors
 441      * 
 442      **************************************************************************/
 443 




   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 package javafx.scene.control;
  26 
  27 import com.sun.javafx.scene.control.Properties;

  28 import javafx.beans.property.DoubleProperty;
  29 import javafx.beans.property.ObjectProperty;
  30 import javafx.beans.property.SimpleDoubleProperty;
  31 import javafx.beans.property.SimpleObjectProperty;
  32 import javafx.beans.property.SimpleStringProperty;
  33 import javafx.beans.property.StringProperty;
  34 import javafx.collections.FXCollections;
  35 import javafx.collections.ObservableList;
  36 import javafx.scene.Node;
  37 import javafx.scene.layout.HBox;
  38 
  39 import com.sun.javafx.util.Utils;
  40 import javafx.scene.control.skin.ButtonBarSkin;




  41 import javafx.beans.value.WritableValue;
  42 import javafx.css.StyleableProperty;
  43 
  44 import java.util.Map;
  45 
  46 /**
  47  * A ButtonBar is essentially a {@link HBox}, with the additional functionality
  48  * for operating system specific button placement. In other words, any Node may
  49  * be annotated (via the {@link ButtonBar#setButtonData(Node, ButtonData)}
  50  * method, placed inside a ButtonBar (via the {@link #getButtons()} list), and will
  51  * then be positioned relative to all other nodes in the button list based on their
  52  * annotations, as well as the overarching
  53  * {@link #buttonOrderProperty() button order} specified for the ButtonBar.
  54  * 
  55  * <strong>Uniform button sizing</strong>
  56  * <p>By default all buttons are uniformly sized in a ButtonBar, meaning that all
  57  * buttons take the width of the widest button. It is possible to opt-out of this
  58  * on a per-button basis, but calling the {@link #setButtonUniformSize(Node, boolean)} method with
  59  * a boolean value of false.
  60  * 


 345          * a comment stating this in their javadoc.
 346          */
 347         public final boolean isDefaultButton() {
 348             return defaultButton;
 349         }
 350     }
 351     
 352 
 353     /**
 354      * Sets the given ButtonData on the given button. If this button is
 355      * subsequently placed in a {@link ButtonBar} it will be placed in the 
 356      * correct position relative to all other buttons in the bar.
 357      * 
 358      * @param button The button to annotate with the given {@link ButtonData} value.
 359      * @param buttonData The ButtonData to designate the button as.
 360      */
 361     public static void setButtonData(Node button, ButtonData buttonData) {
 362         final Map<Object,Object> properties = button.getProperties();
 363         final ObjectProperty<ButtonData> property =
 364                 (ObjectProperty<ButtonData>) properties.getOrDefault(
 365                         Properties.BUTTON_DATA_PROPERTY,
 366                         new SimpleObjectProperty<>(button, "buttonData", buttonData));
 367 
 368         property.set(buttonData);
 369         properties.putIfAbsent(Properties.BUTTON_DATA_PROPERTY, property);
 370     }
 371     
 372     /**
 373      * Returns the previously set ButtonData property on the given button. If this
 374      * was never set, this method will return null. 
 375      *       
 376      * @param button The button to return the previously set ButtonData for.
 377      */
 378     public static ButtonData getButtonData(Node button) {
 379         final Map<Object,Object> properties = button.getProperties();
 380         if (properties.containsKey(Properties.BUTTON_DATA_PROPERTY)) {
 381             ObjectProperty<ButtonData> property = (ObjectProperty<ButtonData>) properties.get(Properties.BUTTON_DATA_PROPERTY);
 382             return property == null ? null : property.get();
 383         }
 384         return null;
 385     }
 386 
 387     /**
 388      * By default all buttons are uniformly sized in a ButtonBar, meaning that all
 389      * buttons take the width of the widest button. It is possible to opt-out of this
 390      * on a per-button basis, but calling the setButtonUniformSize method with
 391      * a boolean value of false.
 392      * 
 393      * <p>If a button is excluded from uniform sizing, it is both excluded from
 394      * being resized away from its preferred size, and also excluded from the
 395      * measuring process, so its size will not influence the maximum size calculated
 396      * for all buttons in the ButtonBar.
 397      * 
 398      * @param button The button to include / exclude from uniform sizing.
 399      * @param uniformSize Boolean true to force uniform sizing on the button, 
 400      *        false to exclude the button from uniform sizing.
 401      */
 402     public static void setButtonUniformSize(Node button, boolean uniformSize) {
 403         // we store the false, but remove the true (as the isButtonUniformSize 
 404         // method returns true by default)
 405         if (uniformSize) {
 406             button.getProperties().remove(Properties.BUTTON_SIZE_INDEPENDENCE);
 407         } else {
 408             button.getProperties().put(Properties.BUTTON_SIZE_INDEPENDENCE, uniformSize);
 409         }
 410     }
 411     
 412     /**
 413      * Returns whether the given node is part of the uniform sizing calculations
 414      * or not. By default all nodes that have not opted out (via 
 415      * {@link #setButtonUniformSize(Node, boolean)}) will return true here.
 416      */
 417     public static boolean isButtonUniformSize(Node button) {
 418         return (boolean) button.getProperties().getOrDefault(Properties.BUTTON_SIZE_INDEPENDENCE, true);
 419     }
 420 
 421 
 422 
 423     /**************************************************************************
 424      * 
 425      * Private fields
 426      * 
 427      **************************************************************************/
 428 
 429     private ObservableList<Node> buttons = FXCollections.<Node>observableArrayList();
 430 
 431 
 432 
 433     /**************************************************************************
 434      * 
 435      * Constructors
 436      * 
 437      **************************************************************************/
 438