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 028 029import com.sun.javafx.css.Selector; 030import com.sun.javafx.css.SimpleSelector; 031import com.sun.javafx.css.StyleManager; 032import com.sun.javafx.css.converters.BooleanConverter; 033import com.sun.javafx.css.converters.EnumConverter; 034import com.sun.javafx.css.converters.InsetsConverter; 035import com.sun.javafx.css.converters.PaintConverter; 036import com.sun.javafx.css.converters.SizeConverter; 037import com.sun.javafx.css.converters.StringConverter; 038import com.sun.javafx.css.parser.CSSParser; 039import java.net.MalformedURLException; 040import java.net.URL; 041import java.util.ArrayList; 042import java.util.Collections; 043import java.util.List; 044 045import javafx.beans.property.BooleanProperty; 046import javafx.beans.property.DoubleProperty; 047import javafx.beans.property.ObjectProperty; 048import javafx.beans.property.ReadOnlyObjectProperty; 049import javafx.beans.property.SimpleBooleanProperty; 050import javafx.beans.property.SimpleStringProperty; 051import javafx.beans.property.StringProperty; 052import javafx.geometry.Insets; 053import javafx.geometry.Orientation; 054import javafx.geometry.Pos; 055import javafx.scene.Node; 056import javafx.scene.image.Image; 057import javafx.scene.image.ImageView; 058import javafx.scene.layout.Region; 059import javafx.scene.paint.Color; 060import javafx.scene.paint.Paint; 061import javafx.scene.text.Font; 062import javafx.scene.text.TextAlignment; 063 064import javafx.beans.DefaultProperty; 065import javafx.css.CssMetaData; 066import javafx.css.FontCssMetaData; 067import javafx.css.StyleOrigin; 068import javafx.css.Styleable; 069import javafx.css.StyleableBooleanProperty; 070import javafx.css.StyleableDoubleProperty; 071import javafx.css.StyleableObjectProperty; 072import javafx.css.StyleableProperty; 073 074import javafx.css.StyleableStringProperty; 075 076 077/** 078 * A Labeled {@link Control} is one which has as part of its user interface 079 * a textual content associated with it. For example, a {@link Button} displays 080 * {@code text}, as does a {@link Label}, a {@link Tooltip}, and many 081 * other controls. 082 * <p> 083 * Labeled is also a convenient base class from which to extend when building 084 * new Controls which, as part of their UI, display read-only textual content. 085 * </p> 086 * 087 * <p>Example of how to place a graphic above the text: 088 * <pre><code> 089 * Image image = new Image(getClass().getResourceAsStream("image.png")); 090 * ImageView imageView = new ImageView(); 091 * imageView.setImage(image); 092 * Label label = new Label("text", imageView); 093 * label.setContentDisplay(ContentDisplay.TOP); 094 * </code></pre> 095 * 096 * @see Button 097 * @see Label 098 * @see ToggleButton 099 */ 100@DefaultProperty("text") 101public abstract class Labeled extends Control { 102 103 private final static String DEFAULT_ELLIPSIS_STRING = "..."; 104 105 106 /*************************************************************************** 107 * * 108 * Constructors * 109 * * 110 **************************************************************************/ 111 112 /** 113 * Creates a Label with no text and graphic 114 */ 115 public Labeled() { } 116 117 /** 118 * Creates a Label with text 119 * @param text The text for the label. 120 */ 121 public Labeled(String text) { 122 setText(text); 123 } 124 125 /** 126 * Creates a Label with text and a graphic 127 * @param text The text for the label. 128 * @param graphic The graphic for the label. 129 */ 130 public Labeled(String text, Node graphic) { 131 setText(text); 132 setGraphic(graphic); 133 } 134 135 /*************************************************************************** 136 * * 137 * Properties * 138 * * 139 **************************************************************************/ 140 /** 141 * The text to display in the label. The text may be null. 142 */ 143 public final StringProperty textProperty() { 144 if (text == null) { 145 text = new SimpleStringProperty(this, "text", ""); 146 } 147 return text; 148 } 149 private StringProperty text; 150 public final void setText(String value) { textProperty().setValue(value); } 151 public final String getText() { return text == null ? "" : text.getValue(); } 152 153 /** 154 * Specifies how the text and graphic within the Labeled should be 155 * aligned when there is empty space within the Labeled. 156 */ 157 public final ObjectProperty<Pos> alignmentProperty() { 158 if (alignment == null) { 159 alignment = new StyleableObjectProperty<Pos>(Pos.CENTER_LEFT) { 160 161 @Override public CssMetaData getCssMetaData() { 162 return StyleableProperties.ALIGNMENT; 163 } 164 165 @Override 166 public Object getBean() { 167 return Labeled.this; 168 } 169 170 @Override 171 public String getName() { 172 return "alignment"; 173 } 174 }; 175 } 176 return alignment; 177 } 178 private ObjectProperty<Pos> alignment; 179 public final void setAlignment(Pos value) { alignmentProperty().set(value); } 180 public final Pos getAlignment() { return alignment == null ? Pos.CENTER_LEFT : alignment.get(); } 181 182 183 /** 184 * Specifies the behavior for lines of text <em>when text is multiline</em> 185 * Unlike {@link #contentDisplayProperty} which affects the graphic and text, this setting 186 * only affects multiple lines of text relative to the text bounds. 187 */ 188 public final ObjectProperty<TextAlignment> textAlignmentProperty() { 189 if (textAlignment == null) { 190 textAlignment = new StyleableObjectProperty<TextAlignment>(TextAlignment.LEFT) { 191 192 @Override 193 public CssMetaData getCssMetaData() { 194 return StyleableProperties.TEXT_ALIGNMENT; 195 } 196 197 @Override 198 public Object getBean() { 199 return Labeled.this; 200 } 201 202 @Override 203 public String getName() { 204 return "textAlignment"; 205 } 206 }; 207 } 208 return textAlignment; 209 } 210 private ObjectProperty<TextAlignment> textAlignment; 211 public final void setTextAlignment(TextAlignment value) { textAlignmentProperty().setValue(value); } 212 public final TextAlignment getTextAlignment() { return textAlignment == null ? TextAlignment.LEFT : textAlignment.getValue(); } 213 214 /** 215 * Specifies the behavior to use if the text of the {@code Labeled} 216 * exceeds the available space for rendering the text. 217 */ 218 public final ObjectProperty<OverrunStyle> textOverrunProperty() { 219 if (textOverrun == null) { 220 textOverrun = new StyleableObjectProperty<OverrunStyle>(OverrunStyle.ELLIPSIS) { 221 222 @Override 223 public CssMetaData getCssMetaData() { 224 return StyleableProperties.TEXT_OVERRUN; 225 } 226 227 @Override 228 public Object getBean() { 229 return Labeled.this; 230 } 231 232 @Override 233 public String getName() { 234 return "textOverrun"; 235 } 236 }; 237 } 238 return textOverrun; 239 } 240 private ObjectProperty<OverrunStyle> textOverrun; 241 public final void setTextOverrun(OverrunStyle value) { textOverrunProperty().setValue(value); } 242 public final OverrunStyle getTextOverrun() { return textOverrun == null ? OverrunStyle.ELLIPSIS : textOverrun.getValue(); } 243 244 /** 245 * Specifies the string to display for the ellipsis when text is truncated. 246 * 247 * <table border="0" cellpadding="0" cellspacing="0"><tr><th>Examples</th></tr> 248 * <tr class="altColor"><td align="right">"..."</td> <td>- Default value for most locales</td> 249 * <tr class="rowColor"><td align="right">" . . . "</td> <td></td> 250 * <tr class="altColor"><td align="right">" [...] "</td> <td></td> 251 * <tr class="rowColor"><td align="right">"\u2026"</td> <td>- The Unicode ellipsis character '…'</td> 252 * <tr class="altColor"><td align="right">""</td> <td>- No ellipsis, just display the truncated string</td> 253 * </table> 254 * 255 * <p>Note that not all fonts support all Unicode characters. 256 * 257 * @see <a href="http://en.wikipedia.org/wiki/Ellipsis#Computer_representations">Wikipedia:ellipsis</a> 258 * @since 2.2 259 */ 260 public final StringProperty ellipsisStringProperty() { 261 if (ellipsisString == null) { 262 ellipsisString = new StyleableStringProperty(DEFAULT_ELLIPSIS_STRING) { 263 @Override public Object getBean() { 264 return Labeled.this; 265 } 266 267 @Override public String getName() { 268 return "ellipsisString"; 269 } 270 271 @Override public CssMetaData getCssMetaData() { 272 return StyleableProperties.ELLIPSIS_STRING; 273 } 274 }; 275 } 276 return ellipsisString; 277 } 278 private StringProperty ellipsisString; 279 public final void setEllipsisString(String value) { ellipsisStringProperty().set((value == null) ? "" : value); } 280 public final String getEllipsisString() { return ellipsisString == null ? DEFAULT_ELLIPSIS_STRING : ellipsisString.get(); } 281 282 283 /** 284 * If a run of text exceeds the width of the Labeled, then this variable 285 * indicates whether the text should wrap onto another line. 286 */ 287 public final BooleanProperty wrapTextProperty() { 288 if (wrapText == null) { 289 wrapText = new StyleableBooleanProperty() { 290 291 @Override 292 public CssMetaData getCssMetaData() { 293 return StyleableProperties.WRAP_TEXT; 294 } 295 296 @Override 297 public Object getBean() { 298 return Labeled.this; 299 } 300 301 @Override 302 public String getName() { 303 return "wrapText"; 304 } 305 }; 306 } 307 return wrapText; 308 } 309 private BooleanProperty wrapText; 310 public final void setWrapText(boolean value) { wrapTextProperty().setValue(value); } 311 public final boolean isWrapText() { return wrapText == null ? false : wrapText.getValue(); } 312 313 /** 314 * If wrapText is true, then contentBias will be HORIZONTAL, otherwise it is null. 315 * @return orientation of width/height dependency or null if there is none 316 */ 317 @Override public Orientation getContentBias() { 318 return isWrapText()? Orientation.HORIZONTAL : null; 319 } 320 321 /** 322 * The default font to use for text in the Labeled. If the Label's text is 323 * rich text then this font may or may not be used depending on the font 324 * information embedded in the rich text, but in any case where a default 325 * font is required, this font will be used. 326 */ 327 public final ObjectProperty<Font> fontProperty() { 328 329 if (font == null) { 330 font = new StyleableObjectProperty<Font>(Font.getDefault()) { 331 332 private boolean fontSetByCss = false; 333 334 @Override 335 public void applyStyle(StyleOrigin newOrigin, Font value) { 336 337 // 338 // RT-20727 - if CSS is setting the font, then make sure invalidate doesn't call impl_reapplyCSS 339 // 340 try { 341 // super.applyStyle calls set which might throw if value is bound. 342 // Have to make sure fontSetByCss is reset. 343 fontSetByCss = true; 344 super.applyStyle(newOrigin, value); 345 } catch(Exception e) { 346 throw e; 347 } finally { 348 fontSetByCss = false; 349 } 350 } 351 352 @Override 353 public void set(Font value) { 354 355 final Font oldValue = get(); 356 if (value != null ? !value.equals(oldValue) : oldValue != null) { 357 super.set(value); 358 } 359 360 } 361 362 @Override 363 protected void invalidated() { 364 // RT-20727 - if font is changed by calling setFont, then 365 // css might need to be reapplied since font size affects 366 // calculated values for styles with relative values 367 if(fontSetByCss == false) { 368 Labeled.this.impl_reapplyCSS(); 369 } 370 } 371 372 @Override 373 public CssMetaData getCssMetaData() { 374 return StyleableProperties.FONT; 375 } 376 377 @Override 378 public Object getBean() { 379 return Labeled.this; 380 } 381 382 @Override 383 public String getName() { 384 return "font"; 385 } 386 }; 387 } 388 return font; 389 } 390 private ObjectProperty<Font> font; 391 public final void setFont(Font value) { fontProperty().setValue(value); } 392 public final Font getFont() { return font == null ? Font.getDefault() : font.getValue(); } 393 394 395 /** 396 * An optional icon for the Labeled. This can be positioned relative to the 397 * text by using {@link #setContentDisplay}. The node specified for this 398 * variable cannot appear elsewhere in the scene graph, otherwise 399 * the {@code IllegalArgumentException} is thrown. See the class 400 * description of {@link javafx.scene.Node Node} for more detail. 401 */ 402 public final ObjectProperty<Node> graphicProperty() { 403 if (graphic == null) { 404 graphic = new StyleableObjectProperty<Node>() { 405 406 // The graphic is styleable by css, but it is the 407 // imageUrlProperty that handles the style value. 408 @Override 409 public CssMetaData getCssMetaData() { 410 return StyleableProperties.GRAPHIC; 411 } 412 413 @Override 414 public Object getBean() { 415 return Labeled.this; 416 } 417 418 @Override 419 public String getName() { 420 return "graphic"; 421 } 422 }; 423 } 424 return graphic; 425 } 426 private ObjectProperty<Node> graphic; 427 public final void setGraphic(Node value) { 428 graphicProperty().setValue(value); 429 } 430 public final Node getGraphic() { return graphic == null ? null : graphic.getValue(); } 431 432 private StringProperty imageUrl = null; 433 /** 434 * The imageUrl property is set from CSS and then the graphic property is 435 * set from the invalidated method. This ensures that the same image isn't 436 * reloaded. 437 */ 438 private StringProperty imageUrlProperty() { 439 if (imageUrl == null) { 440 imageUrl = new StyleableStringProperty() { 441 442 @Override 443 public void applyStyle(StyleOrigin origin, String v) { 444 super.applyStyle(origin, v); 445 if (v == null) { 446 ((StyleableProperty)graphicProperty()).applyStyle(origin, null); 447 } else if (v.startsWith(CSSParser.SPECIAL_REGION_URL_PREFIX)) { 448 final Region region = new Region(); 449 final String styleClassOrId = v.substring(CSSParser.SPECIAL_REGION_URL_PREFIX.length()); 450 if (styleClassOrId.length() > 0) { 451 Selector s = Selector.createSelector(styleClassOrId); 452 if (s instanceof SimpleSelector) { 453 SimpleSelector ss = (SimpleSelector)s; 454 region.setId(ss.getId()); 455 region.getStyleClass().addAll(ss.getStyleClasses()); 456 } 457 } 458 ((StyleableProperty)graphicProperty()).applyStyle(origin, region); 459 } else { 460 URL url = null; 461 try { 462 url = new URL(v); 463 } catch (MalformedURLException malf) { 464 // This may be a relative URL, so try resolving it using the application classloader 465 final ClassLoader cl = Thread.currentThread().getContextClassLoader(); 466 url = cl.getResource(v); 467 } 468 if (url != null) { 469 final Image img = StyleManager.getInstance().getCachedImage(url.toExternalForm()); 470 ((StyleableProperty)graphicProperty()).applyStyle(origin, new ImageView(img)); 471 } 472 } 473 } 474 475 @Override 476 public Object getBean() { 477 return Labeled.this; 478 } 479 480 @Override 481 public String getName() { 482 return "imageUrl"; 483 } 484 485 @Override 486 public CssMetaData getCssMetaData() { 487 return StyleableProperties.GRAPHIC; 488 } 489 490 }; 491 } 492 return imageUrl; 493 } 494 495 /** 496 * Whether all text should be underlined. 497 */ 498 public final BooleanProperty underlineProperty() { 499 if (underline == null) { 500 underline = new StyleableBooleanProperty(false) { 501 502 @Override 503 public CssMetaData getCssMetaData() { 504 return StyleableProperties.UNDERLINE; 505 } 506 507 @Override 508 public Object getBean() { 509 return Labeled.this; 510 } 511 512 @Override 513 public String getName() { 514 return "underline"; 515 } 516 }; 517 } 518 return underline; 519 } 520 private BooleanProperty underline; 521 public final void setUnderline(boolean value) { underlineProperty().setValue(value); } 522 public final boolean isUnderline() { return underline == null ? false : underline.getValue(); } 523 524 /** 525 * Specifies the space in pixel between lines. 526 */ 527 public final DoubleProperty lineSpacingProperty() { 528 if (lineSpacing == null) { 529 lineSpacing = new StyleableDoubleProperty(0) { 530 531 @Override 532 public CssMetaData getCssMetaData() { 533 return StyleableProperties.LINE_SPACING; 534 } 535 536 @Override 537 public Object getBean() { 538 return Labeled.this; 539 } 540 541 @Override 542 public String getName() { 543 return "lineSpacing"; 544 } 545 }; 546 } 547 return lineSpacing; 548 } 549 private DoubleProperty lineSpacing; 550 public final void setLineSpacing(double value) { lineSpacingProperty().setValue(value); } 551 public final double getLineSpacing() { return lineSpacing == null ? 0 : lineSpacing.getValue(); } 552 553 /** 554 * Specifies the positioning of the graphic relative to the text. 555 */ 556 public final ObjectProperty<ContentDisplay> contentDisplayProperty() { 557 if (contentDisplay == null) { 558 contentDisplay = new StyleableObjectProperty<ContentDisplay>(ContentDisplay.LEFT) { 559 560 @Override 561 public CssMetaData getCssMetaData() { 562 return StyleableProperties.CONTENT_DISPLAY; 563 } 564 565 @Override 566 public Object getBean() { 567 return Labeled.this; 568 } 569 570 @Override 571 public String getName() { 572 return "contentDisplay"; 573 } 574 }; 575 } 576 return contentDisplay; 577 } 578 private ObjectProperty<ContentDisplay> contentDisplay; 579 public final void setContentDisplay(ContentDisplay value) { contentDisplayProperty().setValue(value); } 580 public final ContentDisplay getContentDisplay() { return contentDisplay == null ? ContentDisplay.LEFT : contentDisplay.getValue(); } 581 582 /** 583 * The padding around the Labeled's text and graphic content. 584 * By default labelPadding is Insets.EMPTY and cannot be set to null. 585 * Subclasses may add nodes outside this padding and inside the Labeled's padding. 586 * 587 * This property can only be set from CSS. 588 */ 589 public final ReadOnlyObjectProperty<Insets> labelPaddingProperty() { 590 return labelPaddingPropertyImpl(); 591 } 592 private ObjectProperty<Insets> labelPaddingPropertyImpl() { 593 if (labelPadding == null) { 594 labelPadding = new StyleableObjectProperty<Insets>(Insets.EMPTY) { 595 private Insets lastValidValue = Insets.EMPTY; 596 597 @Override 598 public void invalidated() { 599 final Insets newValue = get(); 600 if (newValue == null) { 601 set(lastValidValue); 602 throw new NullPointerException("cannot set labelPadding to null"); 603 } 604 lastValidValue = newValue; 605 requestLayout(); 606 } 607 608 @Override 609 public CssMetaData getCssMetaData() { 610 return StyleableProperties.LABEL_PADDING; 611 } 612 613 @Override 614 public Object getBean() { 615 return Labeled.this; 616 } 617 618 @Override 619 public String getName() { 620 return "labelPadding"; 621 } 622 }; 623 } 624 return labelPadding; 625 } 626 private ObjectProperty<Insets> labelPadding; 627 private void setLabelPadding(Insets value) { labelPaddingPropertyImpl().set(value); } 628 public final Insets getLabelPadding() { return labelPadding == null ? Insets.EMPTY : labelPadding.get(); } 629 630 /** 631 * The amount of space between the graphic and text 632 */ 633 public final DoubleProperty graphicTextGapProperty() { 634 if (graphicTextGap == null) { 635 graphicTextGap = new StyleableDoubleProperty(4) { 636 637 @Override 638 public CssMetaData getCssMetaData() { 639 return StyleableProperties.GRAPHIC_TEXT_GAP; 640 } 641 642 @Override 643 public Object getBean() { 644 return Labeled.this; 645 } 646 647 @Override 648 public String getName() { 649 return "graphicTextGap"; 650 } 651 }; 652 } 653 return graphicTextGap; 654 } 655 private DoubleProperty graphicTextGap; 656 public final void setGraphicTextGap(double value) { graphicTextGapProperty().setValue(value); } 657 public final double getGraphicTextGap() { return graphicTextGap == null ? 4 : graphicTextGap.getValue(); } 658 659 660 /** 661 * The {@link Paint} used to fill the text. 662 */ 663 private ObjectProperty<Paint> textFill; // TODO for now change this 664 665 public final void setTextFill(Paint value) { 666 textFillProperty().set(value); 667 } 668 669 public final Paint getTextFill() { 670 return textFill == null ? Color.BLACK : textFill.get(); 671 } 672 673 public final ObjectProperty<Paint> textFillProperty() { 674 if (textFill == null) { 675 textFill = new StyleableObjectProperty<Paint>(Color.BLACK) { 676 677 @Override 678 public CssMetaData getCssMetaData() { 679 return StyleableProperties.TEXT_FILL; 680 } 681 682 @Override 683 public Object getBean() { 684 return Labeled.this; 685 } 686 687 @Override 688 public String getName() { 689 return "textFill"; 690 } 691 }; 692 } 693 return textFill; 694 } 695 696 697 /** 698 * MnemonicParsing property to enable/disable text parsing. 699 * If this is set to true, then the Label text will be 700 * parsed to see if it contains the mnemonic parsing character '_'. 701 * When a mnemonic is detected the key combination will 702 * be determined based on the succeeding character, and the mnemonic 703 * added. 704 * 705 * <p> 706 * The default value for Labeled is false, but it 707 * is enabled by default on some Controls. 708 * </p> 709 */ 710 private BooleanProperty mnemonicParsing; 711 public final void setMnemonicParsing(boolean value) { 712 mnemonicParsingProperty().set(value); 713 } 714 public final boolean isMnemonicParsing() { 715 return mnemonicParsing == null ? false : mnemonicParsing.get(); 716 } 717 public final BooleanProperty mnemonicParsingProperty() { 718 if (mnemonicParsing == null) { 719 mnemonicParsing = new SimpleBooleanProperty(this, "mnemonicParsing"); 720 } 721 return mnemonicParsing; 722 } 723 724 // /** 725 // * This is the symbol that is searched for in the text and used as 726 // * a mnemonic. You can change what symbol is used. Using the symbol 727 // * more than once will cause the symbol to be escaped. Thus, if "_" 728 // * (the default) is used, then the string "H_ello World" will use 729 // * "e" as the mnemonic. If "H__ello World" is used, then no mnemonic 730 // * will be used and the text will be rendered as "H_ello World". 731 // * TODO: Have i18n review this part of the API to confirm proper 732 // * externalization will work as expected 733 // */ 734 735 /*************************************************************************** 736 * * 737 * Stylesheet Handling * 738 * * 739 **************************************************************************/ 740 741 /** 742 * Not everything uses the default value of false for alignment. 743 * This method provides a way to have them return the correct initial value. 744 * @treatAsPrivate implementation detail 745 */ 746 @Deprecated 747 protected Pos impl_cssGetAlignmentInitialValue() { 748 return Pos.CENTER_LEFT; 749 } 750 751 /** 752 * @treatAsPrivate implementation detail 753 */ 754 private static class StyleableProperties { 755 private static final FontCssMetaData<Labeled> FONT = 756 new FontCssMetaData<Labeled>("-fx-font", Font.getDefault()) { 757 758 @Override 759 public boolean isSettable(Labeled n) { 760 return n.font == null || !n.font.isBound(); 761 } 762 763 @Override 764 public StyleableProperty<Font> getStyleableProperty(Labeled n) { 765 return (StyleableProperty)n.fontProperty(); 766 } 767 }; 768 769 private static final CssMetaData<Labeled,Pos> ALIGNMENT = 770 new CssMetaData<Labeled,Pos>("-fx-alignment", 771 new EnumConverter<Pos>(Pos.class), Pos.CENTER_LEFT ) { 772 773 @Override 774 public boolean isSettable(Labeled n) { 775 return n.alignment == null || !n.alignment.isBound(); 776 } 777 778 @Override 779 public StyleableProperty<Pos> getStyleableProperty(Labeled n) { 780 return (StyleableProperty)n.alignmentProperty(); 781 } 782 783 @Override 784 public Pos getInitialValue(Labeled n) { 785 return n.impl_cssGetAlignmentInitialValue(); 786 } 787 }; 788 789 private static final CssMetaData<Labeled,TextAlignment> TEXT_ALIGNMENT = 790 new CssMetaData<Labeled,TextAlignment>("-fx-text-alignment", 791 new EnumConverter<TextAlignment>(TextAlignment.class), 792 TextAlignment.LEFT) { 793 794 @Override 795 public boolean isSettable(Labeled n) { 796 return n.textAlignment == null || !n.textAlignment.isBound(); 797 } 798 799 @Override 800 public StyleableProperty<TextAlignment> getStyleableProperty(Labeled n) { 801 return (StyleableProperty)n.textAlignmentProperty(); 802 } 803 }; 804 805 private static final CssMetaData<Labeled,Paint> TEXT_FILL = 806 new CssMetaData<Labeled,Paint>("-fx-text-fill", 807 PaintConverter.getInstance(), Color.BLACK) { 808 809 @Override 810 public boolean isSettable(Labeled n) { 811 return n.textFill == null || !n.textFill.isBound(); 812 } 813 814 @Override 815 public StyleableProperty<Paint> getStyleableProperty(Labeled n) { 816 return (StyleableProperty)n.textFillProperty(); 817 } 818 }; 819 820 private static final CssMetaData<Labeled,OverrunStyle> TEXT_OVERRUN = 821 new CssMetaData<Labeled,OverrunStyle>("-fx-text-overrun", 822 new EnumConverter<OverrunStyle>(OverrunStyle.class), 823 OverrunStyle.ELLIPSIS) { 824 825 @Override 826 public boolean isSettable(Labeled n) { 827 return n.textOverrun == null || !n.textOverrun.isBound(); 828 } 829 830 @Override 831 public StyleableProperty<OverrunStyle> getStyleableProperty(Labeled n) { 832 return (StyleableProperty)n.textOverrunProperty(); 833 } 834 }; 835 836 private static final CssMetaData<Labeled,String> ELLIPSIS_STRING = 837 new CssMetaData<Labeled,String>("-fx-ellipsis-string", 838 StringConverter.getInstance(), DEFAULT_ELLIPSIS_STRING) { 839 840 @Override public boolean isSettable(Labeled n) { 841 return n.ellipsisString == null || !n.ellipsisString.isBound(); 842 } 843 844 @Override public StyleableProperty<String> getStyleableProperty(Labeled n) { 845 return (StyleableProperty)n.ellipsisStringProperty(); 846 } 847 }; 848 849 private static final CssMetaData<Labeled,Boolean> WRAP_TEXT = 850 new CssMetaData<Labeled,Boolean>("-fx-wrap-text", 851 BooleanConverter.getInstance(), false) { 852 853 @Override 854 public boolean isSettable(Labeled n) { 855 return n.wrapText == null || !n.wrapText.isBound(); 856 } 857 858 @Override 859 public StyleableProperty<Boolean> getStyleableProperty(Labeled n) { 860 return (StyleableProperty)n.wrapTextProperty(); 861 } 862 }; 863 864 private static final CssMetaData<Labeled,String> GRAPHIC = 865 new CssMetaData<Labeled,String>("-fx-graphic", 866 StringConverter.getInstance()) { 867 868 @Override 869 public boolean isSettable(Labeled n) { 870 // Note that we care about the graphic, not imageUrl 871 return n.graphic == null || !n.graphic.isBound(); 872 } 873 874 @Override 875 public StyleableProperty<String> getStyleableProperty(Labeled n) { 876 return (StyleableProperty)n.imageUrlProperty(); 877 } 878 }; 879 880 private static final CssMetaData<Labeled,Boolean> UNDERLINE = 881 new CssMetaData<Labeled,Boolean>("-fx-underline", 882 BooleanConverter.getInstance(), Boolean.FALSE) { 883 884 @Override 885 public boolean isSettable(Labeled n) { 886 return n.underline == null || !n.underline.isBound(); 887 } 888 889 @Override 890 public StyleableProperty<Boolean> getStyleableProperty(Labeled n) { 891 return (StyleableProperty)n.underlineProperty(); 892 } 893 }; 894 895 private static final CssMetaData<Labeled,Number> LINE_SPACING = 896 new CssMetaData<Labeled,Number>("-fx-line-spacing", 897 SizeConverter.getInstance(), 0) { 898 899 @Override 900 public boolean isSettable(Labeled n) { 901 return n.lineSpacing == null || !n.lineSpacing.isBound(); 902 } 903 904 @Override 905 public StyleableProperty<Number> getStyleableProperty(Labeled n) { 906 return (StyleableProperty)n.lineSpacingProperty(); 907 } 908 }; 909 910 private static final CssMetaData<Labeled,ContentDisplay> CONTENT_DISPLAY = 911 new CssMetaData<Labeled,ContentDisplay>("-fx-content-display", 912 new EnumConverter<ContentDisplay>(ContentDisplay.class), 913 ContentDisplay.LEFT) { 914 915 @Override 916 public boolean isSettable(Labeled n) { 917 return n.contentDisplay == null || !n.contentDisplay.isBound(); 918 } 919 920 @Override 921 public StyleableProperty<ContentDisplay> getStyleableProperty(Labeled n) { 922 return (StyleableProperty)n.contentDisplayProperty(); 923 } 924 }; 925 926 private static final CssMetaData<Labeled,Insets> LABEL_PADDING = 927 new CssMetaData<Labeled,Insets>("-fx-label-padding", 928 InsetsConverter.getInstance(), Insets.EMPTY) { 929 930 @Override 931 public boolean isSettable(Labeled n) { 932 return n.labelPadding == null || !n.labelPadding.isBound(); 933 } 934 935 @Override 936 public StyleableProperty<Insets> getStyleableProperty(Labeled n) { 937 return (StyleableProperty)n.labelPaddingPropertyImpl(); 938 } 939 }; 940 941 private static final CssMetaData<Labeled,Number> GRAPHIC_TEXT_GAP = 942 new CssMetaData<Labeled,Number>("-fx-graphic-text-gap", 943 SizeConverter.getInstance(), 4.0) { 944 945 @Override 946 public boolean isSettable(Labeled n) { 947 return n.graphicTextGap == null || !n.graphicTextGap.isBound(); 948 } 949 950 @Override 951 public StyleableProperty<Number> getStyleableProperty(Labeled n) { 952 return (StyleableProperty)n.graphicTextGapProperty(); 953 } 954 }; 955 956 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 957 static { 958 final List<CssMetaData<? extends Styleable, ?>> styleables = 959 new ArrayList<CssMetaData<? extends Styleable, ?>>(Control.getClassCssMetaData()); 960 Collections.addAll(styleables, 961 FONT, 962 ALIGNMENT, 963 TEXT_ALIGNMENT, 964 TEXT_FILL, 965 TEXT_OVERRUN, 966 ELLIPSIS_STRING, 967 WRAP_TEXT, 968 GRAPHIC, 969 UNDERLINE, 970 LINE_SPACING, 971 CONTENT_DISPLAY, 972 LABEL_PADDING, 973 GRAPHIC_TEXT_GAP 974 ); 975 STYLEABLES = Collections.unmodifiableList(styleables); 976 } 977 } 978 979 /** 980 * @return The CssMetaData associated with this class, which may include the 981 * CssMetaData of its super classes. 982 */ 983 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 984 return StyleableProperties.STYLEABLES; 985 } 986 987 /** 988 * {@inheritDoc} 989 */ 990 @Override 991 public List<CssMetaData<? extends Styleable, ?>> getControlCssMetaData() { 992 return getClassCssMetaData(); 993 } 994 995 }