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.property.ObjectProperty;
033import javafx.geometry.HPos;
034import javafx.geometry.Orientation;
035import javafx.geometry.VPos;
036
037import javafx.css.StyleableObjectProperty;
038import javafx.css.CssMetaData;
039import javafx.css.PseudoClass;
040import com.sun.javafx.css.converters.EnumConverter;
041import com.sun.javafx.scene.control.skin.SeparatorSkin;
042import javafx.css.Styleable;
043import javafx.css.StyleableProperty;
044
045/**
046 * A horizontal or vertical separator line. The visual appearance of this
047 * separator can be controlled via CSS. A horizontal separator occupies the
048 * full horizontal space allocated to it (less padding), and a vertical
049 * separator occupies the full vertical space allocated to it (less padding).
050 * The {@link #halignment} and {@link #valignment} properties determine how the
051 * separator is positioned in the other dimension, for example, how a horizontal
052 * separator is positioned vertically within its allocated space.
053 * <p>
054 * The separator is horizontal (i.e. <code>isVertical() == false</code>) by default.
055 * <p>
056 * The style-class for this control is "separator".
057 * <p>
058 * The separator provides two pseudo-classes "horizontal" and "vertical" which
059 * are mutually exclusive. The "horizontal" pseudo-class applies if the
060 * separator is horizontal, and the "vertical" pseudo-class applies if the
061 * separator is vertical.
062 *
063 * <p>
064 * Separator sets focusTraversable to false.
065 * </p>
066 */
067public class Separator extends Control {
068
069    /***************************************************************************
070     *                                                                         *
071     * Constructors                                                            *
072     *                                                                         *
073     **************************************************************************/
074
075    /**
076     * Creates a new horizontal separator with halignment and valignment set to their
077     * respective CENTER values.
078     */
079    public Separator() {
080        getStyleClass().setAll(DEFAULT_STYLE_CLASS);
081        // focusTraversable is styleable through css. Calling setFocusTraversable
082        // makes it look to css like the user set the value and css will not 
083        // override. Initializing focusTraversable by calling applyStyle with null
084        // StyleOrigin ensures that css will be able to override the value.
085        ((StyleableProperty)focusTraversableProperty()).applyStyle(null, Boolean.FALSE);
086        
087        // initialize pseudo-class state
088        pseudoClassStateChanged(HORIZONTAL_PSEUDOCLASS_STATE, true);
089    }
090
091    /**
092     * Creates a new separator with halignment and valignment set to their respective CENTER
093     * values. The direction of the separator is specified by the vertical property.
094     *
095     * @param orientation Specifies whether the Separator instance is initially
096     *      vertical or horizontal.
097     */
098    public Separator(Orientation orientation) {
099        this();
100        setOrientation(orientation);
101    }
102
103    /***************************************************************************
104     *                                                                         *
105     * Properties                                                              *
106     *                                                                         *
107     **************************************************************************/
108
109    /**
110     * The orientation of the {@code Separator} can either be horizontal
111     * or vertical.
112     */
113    private ObjectProperty<Orientation> orientation = 
114        new StyleableObjectProperty<Orientation>(Orientation.HORIZONTAL) {
115
116            @Override protected void invalidated() {
117                final boolean isVertical = (get() == Orientation.VERTICAL);
118                pseudoClassStateChanged(VERTICAL_PSEUDOCLASS_STATE,    isVertical);
119                pseudoClassStateChanged(HORIZONTAL_PSEUDOCLASS_STATE, !isVertical);
120            }
121
122            @Override 
123            public CssMetaData<Separator,Orientation> getCssMetaData() {
124                return StyleableProperties.ORIENTATION;
125            }
126
127            @Override
128            public Object getBean() {
129                return Separator.this;
130            }
131
132            @Override
133            public String getName() {
134                return "orientation";
135            }
136        };
137    public final void setOrientation(Orientation value) { orientation.set(value); }
138    public final Orientation getOrientation() { return orientation.get(); }
139    public final ObjectProperty<Orientation> orientationProperty() { return orientation; }
140
141    /**
142     * For vertical separators, specifies the horizontal position of the
143     * separator line within the separator control's space. Ignored for
144     * horizontal separators.
145     */
146    private ObjectProperty<HPos> halignment;
147
148    public final void setHalignment(HPos value) {
149        halignmentProperty().set(value);
150    }
151
152    public final HPos getHalignment() {
153        return halignment == null ? HPos.CENTER : halignment.get();
154    }
155
156    public final ObjectProperty<HPos> halignmentProperty() {
157        if (halignment == null) {
158            halignment = new StyleableObjectProperty<HPos>(HPos.CENTER) {
159
160                @Override
161                public Object getBean() {
162                    return Separator.this;
163                }
164
165                @Override
166                public String getName() {
167                    return "halignment";
168                }
169
170                @Override
171                public CssMetaData<Separator,HPos> getCssMetaData() {
172                    return StyleableProperties.HALIGNMENT;
173                }
174                
175            };
176        }
177        return halignment;
178    }
179
180    /**
181     * For horizontal separators, specifies the vertical alignment of the
182     * separator line within the separator control's space. Ignored for
183     * vertical separators.
184     */
185    private ObjectProperty<VPos> valignment;
186    public final void setValignment(VPos value) {
187        valignmentProperty().set(value);
188    }
189
190    public final VPos getValignment() {
191        return valignment == null ? VPos.CENTER : valignment.get();
192    }
193
194    public final ObjectProperty<VPos> valignmentProperty() {
195        if (valignment == null) {
196            valignment = new StyleableObjectProperty<VPos>(VPos.CENTER) {
197
198                @Override
199                public Object getBean() {
200                    return Separator.this;
201                }
202
203                @Override
204                public String getName() {
205                    return "valignment";
206                }
207
208                @Override
209                public CssMetaData<Separator,VPos> getCssMetaData() {
210                    return StyleableProperties.VALIGNMENT;
211                }
212                
213            };
214        }
215        return valignment;
216    }
217
218    /** {@inheritDoc} */
219    @Override protected Skin<?> createDefaultSkin() {
220        return new SeparatorSkin(this);
221    }
222
223    /***************************************************************************
224     *                                                                         *
225     * Stylesheet Handling                                                     *
226     *                                                                         *
227     **************************************************************************/
228
229    private static final String DEFAULT_STYLE_CLASS = "separator";
230
231    private static final String PSEUDO_CLASS_VERTICAL = "vertical";
232    private static final String PSEUDO_CLASS_HORIZONTAL = "horizontal";
233
234    private static class StyleableProperties {
235        private static final CssMetaData<Separator,Orientation> ORIENTATION = 
236                new CssMetaData<Separator,Orientation>("-fx-orientation",
237                new EnumConverter<Orientation>(Orientation.class),
238                Orientation.HORIZONTAL) {
239
240            @Override
241            public Orientation getInitialValue(Separator node) {
242                // A vertical Separator should remain vertical 
243                return node.getOrientation();
244            }
245
246            @Override
247            public boolean isSettable(Separator n) {
248                return n.orientation == null || !n.orientation.isBound();
249            }
250
251            @Override
252            public StyleableProperty<Orientation> getStyleableProperty(Separator n) {
253                return (StyleableProperty<Orientation>)n.orientationProperty();
254            }
255        };
256        
257        private static final CssMetaData<Separator,HPos> HALIGNMENT = 
258                new CssMetaData<Separator,HPos>("-fx-halignment",
259                new EnumConverter<HPos>(HPos.class),
260                HPos.CENTER) {
261
262            @Override
263            public boolean isSettable(Separator n) {
264                return n.halignment == null || !n.halignment.isBound();
265            }
266
267            @Override
268            public StyleableProperty<HPos> getStyleableProperty(Separator n) {
269                return (StyleableProperty<HPos>)n.halignmentProperty();
270            }
271        };
272        
273        private static final CssMetaData<Separator,VPos> VALIGNMENT = 
274                new CssMetaData<Separator,VPos>("-fx-valignment",
275                new EnumConverter<VPos>(VPos.class),
276                VPos.CENTER){
277
278            @Override
279            public boolean isSettable(Separator n) {
280                return n.valignment == null || !n.valignment.isBound();
281            }
282
283            @Override
284            public StyleableProperty<VPos> getStyleableProperty(Separator n) {
285                return (StyleableProperty<VPos>)n.valignmentProperty();
286            }
287        };
288
289        private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES;
290        static {
291            final List<CssMetaData<? extends Styleable, ?>> styleables =
292                new ArrayList<CssMetaData<? extends Styleable, ?>>(Control.getClassCssMetaData());
293            styleables.add(ORIENTATION);
294            styleables.add(HALIGNMENT);
295            styleables.add(VALIGNMENT);
296            STYLEABLES = Collections.unmodifiableList(styleables);
297        }
298    }
299
300    /**
301     * @return The CssMetaData associated with this class, which may include the
302     * CssMetaData of its super classes.
303     */
304    public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() {
305        return Separator.StyleableProperties.STYLEABLES;
306    }
307
308    /**
309     * RT-19263
310     * @treatAsPrivate implementation detail
311     * @deprecated This is an experimental API that is not intended for general use and is subject to change in future versions
312     */
313    @Deprecated
314    @Override protected List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() {
315        return getClassCssMetaData();
316    }
317
318    private static final PseudoClass VERTICAL_PSEUDOCLASS_STATE = PseudoClass.getPseudoClass("vertical");
319    private static final PseudoClass HORIZONTAL_PSEUDOCLASS_STATE = PseudoClass.getPseudoClass("horizontal");
320    
321    /**
322      * Most Controls return true for focusTraversable, so Control overrides
323      * this method to return true, but Separator returns false for
324      * focusTraversable's initial value; hence the override of the override. 
325      * This method is called from CSS code to get the correct initial value.
326      * @treatAsPrivate implementation detail
327      */
328    @Deprecated @Override
329    protected /*do not make final*/ Boolean impl_cssGetFocusTraversableInitialValue() {
330        return Boolean.FALSE;
331    }
332    
333}