/*
 * Copyright (c) 2014, 2017, 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.control;

import com.sun.javafx.scene.control.Properties;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.layout.HBox;

import com.sun.javafx.util.Utils;
import javafx.scene.control.skin.ButtonBarSkin;
import javafx.beans.value.WritableValue;
import javafx.css.StyleableProperty;

import java.util.Map;

A ButtonBar is essentially a HBox, with the additional functionality for operating system specific button placement. In other words, any Node may be annotated (via the setButtonData(Node, ButtonData) method, placed inside a ButtonBar (via the getButtons() list), and will then be positioned relative to all other nodes in the button list based on their annotations, as well as the overarching button order specified for the ButtonBar.

Uniform button sizing

By default all buttons are uniformly sized in a ButtonBar, meaning that all buttons take the width of the widest button. It is possible to opt-out of this on a per-button basis, but calling the setButtonUniformSize(Node, boolean) method with a boolean value of false.

If a button is excluded from uniform sizing, it is both excluded from being resized away from its preferred size, and also excluded from the measuring process, so its size will not influence the maximum size calculated for all buttons in the ButtonBar.

Screenshots

Because a ButtonBar comes with built-in support for Windows, Mac OS and Linux, there are three screenshots shown below, with the same buttons laid out on each of the three operating systems.

Windows:

Mac OS:

Linux:

Code Samples

Instantiating and using the ButtonBar is simple, simply do the following:


// Create the ButtonBar instance
ButtonBar buttonBar = new ButtonBar();
// Create the buttons to go into the ButtonBar
Button yesButton = new Button("Yes");
ButtonBar.setButtonData(yesButton, ButtonData.YES);
Button noButton = new Button("No");
ButtonBar.setButtonData(noButton, ButtonData.NO);
// Add buttons to the ButtonBar
buttonBar.getButtons().addAll(yesButton, noButton);

The code sample above will position the Yes and No buttons relative to the users operating system. This means that on Windows and Linux the Yes button will come before the No button, whereas on Mac OS it'll be No and then Yes.

In most cases the OS-specific layout is the best choice, but in cases where you want a custom layout, this is achieved be modifying the button order property. These are cryptic-looking strings that are shorthand representations for the button order. The built-in orders for Windows, Mac OS and Linux are:

ButtonBar Layout Table
Operating System Button Order
Windows L_E+U+FBXI_YNOCAH_R
Mac OS L_HE+U+FBIX_NCYOA_R
Linux L_HE+UNYACBXIO_R

You should refer to the ButtonData enumeration for a description of what each of these characters mean. However, if your ButtonBar only consisted of ButtonData.YES and ButtonData.NO buttons, you always wanted the yes buttons before the no buttons, and you wanted the buttons to be right-aligned, you could do the following:


// Create the ButtonBar instance
ButtonBar buttonBar = new ButtonBar();
// Set the custom button order
buttonBar.setButtonOrder("+YN");
See Also:
Since:JavaFX 8u40
/** * A ButtonBar is essentially a {@link HBox}, with the additional functionality * for operating system specific button placement. In other words, any Node may * be annotated (via the {@link ButtonBar#setButtonData(Node, ButtonData)} * method, placed inside a ButtonBar (via the {@link #getButtons()} list), and will * then be positioned relative to all other nodes in the button list based on their * annotations, as well as the overarching * {@link #buttonOrderProperty() button order} specified for the ButtonBar. * * <h3>Uniform button sizing</h3> * <p>By default all buttons are uniformly sized in a ButtonBar, meaning that all * buttons take the width of the widest button. It is possible to opt-out of this * on a per-button basis, but calling the {@link #setButtonUniformSize(Node, boolean)} method with * a boolean value of false. * * <p>If a button is excluded from uniform sizing, it is both excluded from * being resized away from its preferred size, and also excluded from the * measuring process, so its size will not influence the maximum size calculated * for all buttons in the ButtonBar. * * <h3>Screenshots</h3> * <p>Because a ButtonBar comes with built-in support for Windows, Mac OS * and Linux, there are three screenshots shown below, with the same buttons * laid out on each of the three operating systems. * * <p> * <strong>Windows:</strong><p><img src="doc-files/buttonBar-windows.png" alt=""></p> * <strong>Mac OS:</strong><p><img src="doc-files/buttonBar-mac.png" alt=""></p> * <strong>Linux:</strong><p><img src="doc-files/buttonBar-linux.png" alt=""></p> * * <h3>Code Samples</h3> * <p>Instantiating and using the ButtonBar is simple, simply do the following: * * <pre> * {@code * // Create the ButtonBar instance * ButtonBar buttonBar = new ButtonBar(); * * // Create the buttons to go into the ButtonBar * Button yesButton = new Button("Yes"); * ButtonBar.setButtonData(yesButton, ButtonData.YES); * * Button noButton = new Button("No"); * ButtonBar.setButtonData(noButton, ButtonData.NO); * * // Add buttons to the ButtonBar * buttonBar.getButtons().addAll(yesButton, noButton); * }</pre> * * <p>The code sample above will position the Yes and No buttons relative to the * users operating system. This means that on Windows and Linux the Yes button * will come before the No button, whereas on Mac OS it'll be No and then Yes. * * <p>In most cases the OS-specific layout is the best choice, but in cases * where you want a custom layout, this is achieved be modifying the * {@link #buttonOrderProperty() button order property}. These are cryptic-looking * strings that are shorthand representations for the button order. The built-in * orders for Windows, Mac OS and Linux are: * * <table> * <caption>ButtonBar Layout Table</caption> * <tr> * <th scope="col">Operating System</th> * <th scope="col">Button Order</th> * </tr> * <tr> * <th scope="row">Windows</th> * <td>L_E+U+FBXI_YNOCAH_R</td> * </tr> * <tr> * <th scope="row">Mac OS</th> * <td>L_HE+U+FBIX_NCYOA_R</td> * </tr> * <tr> * <th scope="row">Linux</th> * <td>L_HE+UNYACBXIO_R</td> * </tr> * </table> * * <p>You should refer to the {@link ButtonData} enumeration for a description of * what each of these characters mean. However, if your ButtonBar only consisted * of {@link ButtonData#YES} and {@link ButtonData#NO} buttons, you always * wanted the yes buttons before the no buttons, and you wanted the buttons to * be {@link ButtonData#BIG_GAP right-aligned}, you could do the following: * * <pre> * {@code * // Create the ButtonBar instance * ButtonBar buttonBar = new ButtonBar(); * * // Set the custom button order * buttonBar.setButtonOrder("+YN"); * }</pre> * * @see ButtonData * @since JavaFX 8u40 */
public class ButtonBar extends Control { // TODO add support for BUTTON_ORDER_NONE // TODO test and document what happens with unexpected button order strings /************************************************************************** * * Static fields * **************************************************************************/
The default button ordering on Windows.
/** * The default button ordering on Windows. */
public static final String BUTTON_ORDER_WINDOWS = "L_E+U+FBXI_YNOCAH_R"; //$NON-NLS-1$
The default button ordering on Mac OS.
/** * The default button ordering on Mac OS. */
public static final String BUTTON_ORDER_MAC_OS = "L_HE+U+FBIX_NCYOA_R"; //$NON-NLS-1$
The default button ordering on Linux (specifically, GNOME).
/** * The default button ordering on Linux (specifically, GNOME). */
public static final String BUTTON_ORDER_LINUX = "L_HE+UNYACBXIO_R"; //$NON-NLS-1$
A button ordering string that specifies there is no button ordering. In other words, buttons will be placed in the order that exist in the getButtons() list. The only aspect of layout that makes this different than using an HBox is that the buttons are right-aligned.
/** * A button ordering string that specifies there is no button ordering. In * other words, buttons will be placed in the order that exist in the * {@link #getButtons()} list. The only aspect of layout that makes this * different than using an HBox is that the buttons are right-aligned. */
public static final String BUTTON_ORDER_NONE = ""; //$NON-NLS-1$ /************************************************************************** * * Static enumerations * **************************************************************************/
An enumeration of all available button data annotations. By annotating every button in a ButtonBar with one of these annotations, the buttons will be appropriately positioned relative to all other buttons in the ButtonBar.

For details on the button order code for each ButtonData, refer to the javadoc comment.

Since:JavaFX 8u40
/** * An enumeration of all available button data annotations. By annotating * every button in a {@link ButtonBar} with one of these annotations, the * buttons will be appropriately positioned relative to all other buttons in * the ButtonBar. * * <p>For details on the button order code for each ButtonData, refer to * the javadoc comment. * * @since JavaFX 8u40 */
public static enum ButtonData {
Buttons with this style tag will statically end up on the left end of the bar.

Button order code: L

/** * Buttons with this style tag will statically end up on the left end of the bar. * * <p><strong>Button order code:</strong> L */
LEFT("L",false,false), //$NON-NLS-1$
Buttons with this style tag will statically end up on the right end of the bar.

Button order code: R

/** * Buttons with this style tag will statically end up on the right end of the bar. * * <p><strong>Button order code:</strong> R */
RIGHT("R", false, false), //$NON-NLS-1$
A tag for the "help" button that normally is supposed to be on the right.

Button order code: H

/** * A tag for the "help" button that normally is supposed to be on the right. * * <p><strong>Button order code:</strong> H */
HELP("H", false, false ), //$NON-NLS-1$
A tag for the "help2" button that normally is supposed to be on the left.

Button order code: E

/** * A tag for the "help2" button that normally is supposed to be on the left. * * <p><strong>Button order code:</strong> E */
HELP_2("E", false, false), //$NON-NLS-1$
A tag for the "yes" button.

Is default button: True

Button order code: Y

/** * A tag for the "yes" button. * * <p><strong>Is default button:</strong> True * <p><strong>Button order code:</strong> Y */
YES("Y", false, true), //$NON-NLS-1$
A tag for the "no" button.

Is cancel button: True

Button order code: N

/** * A tag for the "no" button. * * <p><strong>Is cancel button:</strong> True * <p><strong>Button order code:</strong> N */
NO("N", true, false), //$NON-NLS-1$
A tag for the "next" or "forward" button.

Is default button: True

Button order code: X

/** * A tag for the "next" or "forward" button. * * <p><strong>Is default button:</strong> True * <p><strong>Button order code:</strong> X */
NEXT_FORWARD("X", false, true), //$NON-NLS-1$
A tag for the "back" or "previous" button.

Button order code: B

/** * A tag for the "back" or "previous" button. * * <p><strong>Button order code:</strong> B */
BACK_PREVIOUS("B", false, false), //$NON-NLS-1$
A tag for the "finish".

Is default button: True

Button order code: I

/** * A tag for the "finish". * * <p><strong>Is default button:</strong> True * <p><strong>Button order code:</strong> I */
FINISH("I", false, true), //$NON-NLS-1$
A tag for the "apply" button.

Button order code: A

/** * A tag for the "apply" button. * * <p><strong>Button order code:</strong> A */
APPLY("A", false, false), //$NON-NLS-1$
A tag for the "cancel" or "close" button.

Is cancel button: True

Button order code: C

/** * A tag for the "cancel" or "close" button. * * <p><strong>Is cancel button:</strong> True * <p><strong>Button order code:</strong> C */
CANCEL_CLOSE("C", true, false), //$NON-NLS-1$
A tag for the "ok" or "done" button.

Is default button: True

Button order code: O

/** * A tag for the "ok" or "done" button. * * <p><strong>Is default button:</strong> True * <p><strong>Button order code:</strong> O */
OK_DONE("O", false, true), //$NON-NLS-1$
All Uncategorized, Other, or "Unknown" buttons. Tag will be "other".

Button order code: U

/** * All Uncategorized, Other, or "Unknown" buttons. Tag will be "other". * * <p><strong>Button order code:</strong> U */
OTHER("U", false, false), //$NON-NLS-1$
A glue push gap that will take as much space as it can and at least an "unrelated" gap. (Platform dependent)

Button order code: +

/** * A glue push gap that will take as much space as it can and at least * an "unrelated" gap. (Platform dependent) * * <p><strong>Button order code:</strong> + */
BIG_GAP("+", false, false), //$NON-NLS-1$
An "unrelated" gap. (Platform dependent)

Button order code: _ (underscore)

/** * An "unrelated" gap. (Platform dependent) * * <p><strong>Button order code:</strong> _ (underscore) */
SMALL_GAP("_", false, false); //$NON-NLS-1$ private final String typeCode; private final boolean cancelButton; private final boolean defaultButton; private ButtonData(String type, boolean cancelButton, boolean defaultButton) { this.typeCode = type; this.cancelButton = cancelButton; this.defaultButton = defaultButton; }
Returns the single character code used to represent the ButtonData annotation in the button order string.
Returns:the single character code used to represent the ButtonData annotation
/** * Returns the single character code used to represent the ButtonData * annotation in the {@link ButtonBar#buttonOrderProperty() button order} * string. * @return the single character code used to represent the ButtonData * annotation */
public String getTypeCode() { return typeCode; }
Indicates whether buttons created from the ButtonData enumeration should be the 'cancel' button in the user interface. This typically means that the button will respond to the escape key press, even if the button does not have focus.

ButtonData enumeration values that can be the cancel button have a comment stating this in their javadoc.

Returns:true if this is a 'cancel' button
/** * Indicates whether buttons created from the ButtonData enumeration * should be the 'cancel' button in the user interface. This typically * means that the button will respond to the escape key press, even if * the button does not have focus. * * <p>ButtonData enumeration values that can be the cancel button have a * comment stating this in their javadoc. * @return true if this is a 'cancel' button */
public final boolean isCancelButton() { return cancelButton; }
Indicates whether buttons created from the ButtonData enumeration should be the 'default' button in the user interface. This typically means that the button will respond to enter key presses, even if the button does not have focus.

ButtonData enumeration values that can be the default button have a comment stating this in their javadoc.

Returns:true if this is a 'default' button
/** * Indicates whether buttons created from the ButtonData enumeration * should be the 'default' button in the user interface. This typically * means that the button will respond to enter key presses, even if the * button does not have focus. * * <p>ButtonData enumeration values that can be the default button have * a comment stating this in their javadoc. * @return true if this is a 'default' button */
public final boolean isDefaultButton() { return defaultButton; } }
Sets the given ButtonData on the given button. If this button is subsequently placed in a ButtonBar it will be placed in the correct position relative to all other buttons in the bar.
Params:
  • button – The button to annotate with the given ButtonData value.
  • buttonData – The ButtonData to designate the button as.
/** * Sets the given ButtonData on the given button. If this button is * subsequently placed in a {@link ButtonBar} it will be placed in the * correct position relative to all other buttons in the bar. * * @param button The button to annotate with the given {@link ButtonData} value. * @param buttonData The ButtonData to designate the button as. */
public static void setButtonData(Node button, ButtonData buttonData) { final Map<Object,Object> properties = button.getProperties(); final ObjectProperty<ButtonData> property = (ObjectProperty<ButtonData>) properties.getOrDefault( Properties.BUTTON_DATA_PROPERTY, new SimpleObjectProperty<>(button, "buttonData", buttonData)); property.set(buttonData); properties.putIfAbsent(Properties.BUTTON_DATA_PROPERTY, property); }
Returns the previously set ButtonData property on the given button. If this was never set, this method will return null.
Params:
  • button – The button to return the previously set ButtonData for.
Returns:the previously set ButtonData property on the given button
/** * Returns the previously set ButtonData property on the given button. If this * was never set, this method will return null. * * @param button The button to return the previously set ButtonData for. * @return the previously set ButtonData property on the given button */
public static ButtonData getButtonData(Node button) { final Map<Object,Object> properties = button.getProperties(); if (properties.containsKey(Properties.BUTTON_DATA_PROPERTY)) { ObjectProperty<ButtonData> property = (ObjectProperty<ButtonData>) properties.get(Properties.BUTTON_DATA_PROPERTY); return property == null ? null : property.get(); } return null; }
By default all buttons are uniformly sized in a ButtonBar, meaning that all buttons take the width of the widest button. It is possible to opt-out of this on a per-button basis, but calling the setButtonUniformSize method with a boolean value of false.

If a button is excluded from uniform sizing, it is both excluded from being resized away from its preferred size, and also excluded from the measuring process, so its size will not influence the maximum size calculated for all buttons in the ButtonBar.

Params:
  • button – The button to include / exclude from uniform sizing.
  • uniformSize – Boolean true to force uniform sizing on the button, false to exclude the button from uniform sizing.
/** * By default all buttons are uniformly sized in a ButtonBar, meaning that all * buttons take the width of the widest button. It is possible to opt-out of this * on a per-button basis, but calling the setButtonUniformSize method with * a boolean value of false. * * <p>If a button is excluded from uniform sizing, it is both excluded from * being resized away from its preferred size, and also excluded from the * measuring process, so its size will not influence the maximum size calculated * for all buttons in the ButtonBar. * * @param button The button to include / exclude from uniform sizing. * @param uniformSize Boolean true to force uniform sizing on the button, * false to exclude the button from uniform sizing. */
public static void setButtonUniformSize(Node button, boolean uniformSize) { // we store the false, but remove the true (as the isButtonUniformSize // method returns true by default) if (uniformSize) { button.getProperties().remove(Properties.BUTTON_SIZE_INDEPENDENCE); } else { button.getProperties().put(Properties.BUTTON_SIZE_INDEPENDENCE, uniformSize); } }
Returns whether the given node is part of the uniform sizing calculations or not. By default all nodes that have not opted out (via setButtonUniformSize(Node, boolean)) will return true here.
Params:
  • button – the button
Returns:true if button is part of the uniform sizing calculations
/** * Returns whether the given node is part of the uniform sizing calculations * or not. By default all nodes that have not opted out (via * {@link #setButtonUniformSize(Node, boolean)}) will return true here. * @param button the button * @return true if button is part of the uniform sizing calculations */
public static boolean isButtonUniformSize(Node button) { return (boolean) button.getProperties().getOrDefault(Properties.BUTTON_SIZE_INDEPENDENCE, true); }
Private fields
/************************************************************************** * * Private fields * **************************************************************************/
private ObservableList<Node> buttons = FXCollections.<Node>observableArrayList(); /************************************************************************** * * Constructors * **************************************************************************/
Creates a default ButtonBar instance using the default properties for the users operating system.
/** * Creates a default ButtonBar instance using the default properties for * the users operating system. */
public ButtonBar() { this(null); }
Creates a ButtonBar with the given button order (refer to buttonOrderProperty() for more information).
Params:
  • buttonOrder – The button order to use in this button bar instance.
/** * Creates a ButtonBar with the given button order (refer to * {@link #buttonOrderProperty()} for more information). * * @param buttonOrder The button order to use in this button bar instance. */
public ButtonBar(final String buttonOrder) { getStyleClass().add("button-bar"); //$NON-NLS-1$ // we allow for the buttons inside the ButtonBar to be focus traversable, // but the ButtonBar itself is not. // focusTraversable is styleable through css. Calling setFocusTraversable // makes it look to css like the user set the value and css will not // override. Initializing focusTraversable by calling set on the // CssMetaData ensures that css will be able to override the value. ((StyleableProperty<Boolean>)(WritableValue<Boolean>)focusTraversableProperty()).applyStyle(null, Boolean.FALSE); final boolean buttonOrderEmpty = buttonOrder == null || buttonOrder.isEmpty(); if (Utils.isMac()) { setButtonOrder(buttonOrderEmpty ? BUTTON_ORDER_MAC_OS : buttonOrder); setButtonMinWidth(70); } else if (Utils.isUnix()) { setButtonOrder(buttonOrderEmpty ? BUTTON_ORDER_LINUX : buttonOrder); setButtonMinWidth(85); } else { // windows by default setButtonOrder(buttonOrderEmpty ? BUTTON_ORDER_WINDOWS : buttonOrder); setButtonMinWidth(75); } } /************************************************************************** * * Public API * **************************************************************************/
{@inheritDoc}
/** * {@inheritDoc} */
@Override protected Skin<?> createDefaultSkin() { return new ButtonBarSkin(this); }
Placing buttons inside this ObservableList will instruct the ButtonBar to position them relative to each other based on their specified ButtonData. To set the ButtonData for a button, simply call setButtonData(Node, ButtonData), passing in the relevant ButtonData.
Returns:A list containing all buttons currently in the button bar, and allowing for further buttons to be added or removed.
/** * Placing buttons inside this ObservableList will instruct the ButtonBar * to position them relative to each other based on their specified * {@link ButtonData}. To set the ButtonData for a button, simply call * {@link ButtonBar#setButtonData(Node, ButtonData)}, passing in the * relevant ButtonData. * * @return A list containing all buttons currently in the button bar, and * allowing for further buttons to be added or removed. */
public final ObservableList<Node> getButtons() { return buttons; } /************************************************************************** * * Properties * **************************************************************************/ // --- Button order
The order for the typical buttons in a standard button bar. It is one letter per ButtonData enumeration value. Default button orders for operating systems are also available: BUTTON_ORDER_WINDOWS, BUTTON_ORDER_MAC_OS, and BUTTON_ORDER_LINUX.
Returns:the button order property
/** * The order for the typical buttons in a standard button bar. It is * one letter per {@link ButtonData} enumeration value. Default button orders * for operating systems are also available: {@link #BUTTON_ORDER_WINDOWS}, * {@link #BUTTON_ORDER_MAC_OS}, and {@link #BUTTON_ORDER_LINUX}. * @return the button order property */
public final StringProperty buttonOrderProperty() { return buttonOrderProperty; } private final StringProperty buttonOrderProperty = new SimpleStringProperty(this, "buttonOrder"); //$NON-NLS-1$
Sets the button order
Params:
  • buttonOrder – The currently set button order, which by default will be the OS-specific button order.
/** * Sets the {@link #buttonOrderProperty() button order} * @param buttonOrder The currently set button order, which by default will * be the OS-specific button order. */
public final void setButtonOrder(String buttonOrder) { buttonOrderProperty.set(buttonOrder); }
Returns the current button order.
Returns:The current button order.
/** * Returns the current {@link #buttonOrderProperty() button order}. * @return The current {@link #buttonOrderProperty() button order}. */
public final String getButtonOrder() { return buttonOrderProperty.get(); } // --- button min width
Specifies the minimum width of all buttons placed in this button bar.
Returns:the minimum width property
/** * Specifies the minimum width of all buttons placed in this button bar. * @return the minimum width property */
public final DoubleProperty buttonMinWidthProperty() { return buttonMinWidthProperty; } private final DoubleProperty buttonMinWidthProperty = new SimpleDoubleProperty(this, "buttonMinWidthProperty"); //$NON-NLS-1$
Sets the minimum width of all buttons placed in this button bar.
Params:
  • value – the minimum width value
/** * Sets the minimum width of all buttons placed in this button bar. * @param value the minimum width value */
public final void setButtonMinWidth(double value) { buttonMinWidthProperty.set(value); }
Returns the minimum width of all buttons placed in this button bar.
Returns:the minimum width value
/** * Returns the minimum width of all buttons placed in this button bar. * @return the minimum width value */
public final double getButtonMinWidth() { return buttonMinWidthProperty.get(); } /************************************************************************** * * Implementation * **************************************************************************/
Returns the initial focus traversable state of this control, for use by the JavaFX CSS engine to correctly set its initial value. This method is overridden as by default UI controls have focus traversable set to true, but that is not appropriate for this control.
Since:9
/** * Returns the initial focus traversable state of this control, for use * by the JavaFX CSS engine to correctly set its initial value. This method * is overridden as by default UI controls have focus traversable set to true, * but that is not appropriate for this control. * * @since 9 */
@Override protected Boolean getInitialFocusTraversable() { return Boolean.FALSE; } /************************************************************************** * * Support classes / enums * **************************************************************************/ }