Spec-Zone .ru
спецификации, руководства, описания, API
001/*
002 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package javafx.scene.control;
027
028import java.util.ArrayList;
029import java.util.Collections;
030import java.util.List;
031
032import javafx.beans.DefaultProperty;
033import javafx.beans.property.ObjectProperty;
034import javafx.collections.FXCollections;
035import javafx.collections.ObservableList;
036import javafx.geometry.Orientation;
037import javafx.scene.Node;
038
039import javafx.css.StyleableObjectProperty;
040import javafx.css.CssMetaData;
041import javafx.css.PseudoClass;
042import com.sun.javafx.css.converters.EnumConverter;
043import com.sun.javafx.scene.control.skin.ToolBarSkin;
044import javafx.css.Styleable;
045import javafx.css.StyleableProperty;
046
047/**
048 * <p>
049 * A ToolBar is a control which displays items horizontally
050 * or vertically. The most common items to place within a {@code ToolBar}
051 * are {@link Button Buttons}, {@link ToggleButton ToggleButtons} and
052 * {@link Separator Separators}, but you are not restricted to just these, and
053 * can insert any {@link Node} into them.
054 * </p>
055 *
056 * <p>If there are too many items to fit in the ToolBar an overflow button will appear.
057 * The overflow button allows you to select items that are not currently visible in the toolbar.
058 * </p>
059 * <p>
060 * ToolBar sets focusTraversable to false.
061 * </p>
062 *
063 * <p>
064 * Example of a horizontal ToolBar with eight buttons separated with two vertical separators.
065 * </p>
066 * <pre><code>
067 * ToolBar toolBar = new ToolBar(
068 *     new Button("New"),
069 *     new Button("Open"),
070 *     new Button("Save"),
071 *     new Separator(true),
072 *     new Button("Clean"),
073 *     new Button("Compile"),
074 *     new Button("Run"),
075 *     new Separator(true),
076 *     new Button("Debug"),
077 *     new Button("Profile")
078 * );
079 * </code></pre>
080 *
081 */
082@DefaultProperty("items")
083public class ToolBar extends Control {
084
085    /***************************************************************************
086     *                                                                         *
087     * Constructors                                                            *
088     *                                                                         *
089     **************************************************************************/
090
091    /**
092     * Creates an empty tool bar.
093     */
094    public ToolBar() {
095        initialize();
096    }
097
098    /**
099     * Creates a tool bar populated with the specified nodes. None of the items
100     * can be null.
101     *
102     * @param items the items to add
103     */
104    public ToolBar(Node... items) {
105        initialize();
106        this.items.addAll(items);
107    }
108
109    private void initialize() {
110        getStyleClass().setAll(DEFAULT_STYLE_CLASS);
111        // focusTraversable is styleable through css. Calling setFocusTraversable
112        // makes it look to css like the user set the value and css will not 
113        // override. Initializing focusTraversable by calling set on the 
114        // CssMetaData ensures that css will be able to override the value.
115        ((StyleableProperty)focusTraversableProperty()).applyStyle(null, Boolean.FALSE);
116        
117        // initialize css pseudo-class state
118        pseudoClassStateChanged(HORIZONTAL_PSEUDOCLASS_STATE, true);
119        
120    }
121
122    /***************************************************************************
123     *                                                                         *
124     * Properties                                                              *
125     *                                                                         *
126     **************************************************************************/
127
128    /**
129     * The items contained in the {@code ToolBar}. Typical use case for a
130     * {@code ToolBar} suggest that the most common items to place within it
131     * are {@link Button Buttons}, {@link ToggleButton ToggleButtons}, and  {@link Separator Separators},
132     * but you are not restricted to just these, and can insert any {@link Node}.
133     * The items added must not be null.
134     */
135    public final ObservableList<Node> getItems() { return items; }
136
137    private final ObservableList<Node> items = FXCollections.<Node>observableArrayList();
138
139    /**
140     * The orientation of the {@code ToolBar} - this can either be horizontal
141     * or vertical.
142     */
143    private ObjectProperty<Orientation> orientation;
144    public final void setOrientation(Orientation value) {
145        orientationProperty().set(value);
146    };
147    public final Orientation getOrientation() {
148        return orientation == null ? Orientation.HORIZONTAL : orientation.get();
149    }
150    public final ObjectProperty<Orientation> orientationProperty() {
151        if (orientation == null) {
152            orientation = new StyleableObjectProperty<Orientation>(Orientation.HORIZONTAL) {
153                @Override public void invalidated() {
154                    final boolean isVertical = (get() == Orientation.VERTICAL);
155                    pseudoClassStateChanged(VERTICAL_PSEUDOCLASS_STATE,    isVertical);
156                    pseudoClassStateChanged(HORIZONTAL_PSEUDOCLASS_STATE, !isVertical);
157                }
158
159                @Override
160                public Object getBean() {
161                    return ToolBar.this;
162                }
163
164                @Override
165                public String getName() {
166                    return "orientation";
167                }
168
169                @Override
170                public CssMetaData<ToolBar,Orientation> getCssMetaData() {
171                    return StyleableProperties.ORIENTATION;
172                }
173            };
174        }
175        return orientation;
176    }
177
178    /***************************************************************************
179     *                                                                         *
180     * Methods                                                                 *
181     *                                                                         *
182     **************************************************************************/
183
184    /** {@inheritDoc} */
185    @Override protected Skin<?> createDefaultSkin() {
186        return new ToolBarSkin(this);
187    }
188
189    /***************************************************************************
190     *                                                                         *
191     *                         Stylesheet Handling                             *
192     *                                                                         *
193     **************************************************************************/
194
195    private static final String DEFAULT_STYLE_CLASS = "tool-bar";
196    private static final String PSEUDO_CLASS_VERTICAL = "vertical";
197    private static final String PSEUDO_CLASS_HORIZONTAL = "horizontal";
198
199    private static class StyleableProperties {
200        private static final CssMetaData<ToolBar,Orientation> ORIENTATION = 
201                new CssMetaData<ToolBar,Orientation>("-fx-orientation",
202                new EnumConverter<Orientation>(Orientation.class), 
203                Orientation.HORIZONTAL) {
204
205            @Override
206            public Orientation getInitialValue(ToolBar node) {
207                // A vertical ToolBar should remain vertical 
208                return node.getOrientation();
209            }
210            
211            @Override
212            public boolean isSettable(ToolBar n) {
213                return n.orientation == null || !n.orientation.isBound();
214            }
215
216            @Override
217            public StyleableProperty<Orientation> getStyleableProperty(ToolBar n) {
218                return (StyleableProperty<Orientation>)n.orientationProperty();
219            }
220        };
221
222        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
223        static {
224            final List<CssMetaData<? extends Styleable, ?>> styleables =
225                new ArrayList<CssMetaData<? extends Styleable, ?>>(Control.getClassCssMetaData());
226            styleables.add(ORIENTATION);
227            STYLEABLES = Collections.unmodifiableList(styleables);
228        }
229    }
230
231    /**
232     * @return The CssMetaData associated with this class, which may include the
233     * CssMetaData of its super classes.
234     */
235    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
236        return StyleableProperties.STYLEABLES;
237    }
238
239    /**
240     * {@inheritDoc}
241     */
242    @Override
243    public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
244        return getClassCssMetaData();
245    }
246
247    private static final PseudoClass VERTICAL_PSEUDOCLASS_STATE = PseudoClass.getPseudoClass("vertical");
248    private static final PseudoClass HORIZONTAL_PSEUDOCLASS_STATE = PseudoClass.getPseudoClass("horizontal");
249
250    /**
251      * Most Controls return true for focusTraversable, so Control overrides
252      * this method to return true, but ToolBar returns false for
253      * focusTraversable's initial value; hence the override of the override. 
254      * This method is called from CSS code to get the correct initial value.
255      * @treatAsPrivate implementation detail
256      */
257    @Deprecated @Override
258    protected /*do not make final*/ Boolean impl_cssGetFocusTraversableInitialValue() {
259        return Boolean.FALSE;
260    }
261
262}