Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2011, 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.layout; 027 028import java.util.ArrayList; 029import java.util.Collections; 030import java.util.List; 031import javafx.beans.property.BooleanProperty; 032import javafx.beans.property.DoubleProperty; 033import javafx.beans.property.ObjectProperty; 034import javafx.css.CssMetaData; 035import javafx.css.StyleableBooleanProperty; 036import javafx.css.StyleableDoubleProperty; 037import javafx.css.StyleableObjectProperty; 038import javafx.css.StyleableProperty; 039import javafx.geometry.Insets; 040import javafx.geometry.Orientation; 041import javafx.geometry.Pos; 042import javafx.geometry.VPos; 043import javafx.scene.Node; 044import com.sun.javafx.css.converters.BooleanConverter; 045import com.sun.javafx.css.converters.EnumConverter; 046import com.sun.javafx.css.converters.SizeConverter; 047import javafx.css.Styleable; 048import javafx.geometry.HPos; 049 050 051 052/** 053 * HBox lays out its children in a single horizontal row. 054 * If the hbox has a border and/or padding set, then the contents will be layed 055 * out within those insets. 056 * <p> 057 * HBox example: 058 * <pre><code> 059 * HBox hbox = new HBox(8); // spacing = 8 060 * hbox.getChildren().addAll(new Label("Name:), new TextBox()); 061 * </code></pre> 062 * 063 * HBox will resize children (if resizable) to their preferred widths and uses its 064 * fillHeight property to determine whether to resize their heights to 065 * fill its own height or keep their heights to their preferred (fillHeight defaults to true). 066 * The alignment of the content is controlled by the alignment property, 067 * which defaults to Pos.TOP_LEFT. 068 * <p> 069 * If an hbox is resized larger than its preferred width, by default it will keep 070 * children to their preferred widths, leaving the extra space unused. If an 071 * application wishes to have one or more children be allocated that extra space 072 * it may optionally set an hgrow constraint on the child. See "Optional Layout 073 * Constraints" for details. 074 * <p> 075 * HBox lays out each managed child regardless of the child's 076 * visible property value; unmanaged children are ignored.</p> 077 * 078 * <h4>Resizable Range</h4> 079 * 080 * An hbox's parent will resize the hbox within the hbox's resizable range 081 * during layout. By default the hbox computes this range based on its content 082 * as outlined in the table below. 083 * <table border="1"> 084 * <tr><td></td><th>width</th><th>height</th></tr> 085 * <tr><th>minimum</th> 086 * <td>left/right insets plus the sum of each child's min width plus spacing between each child.</td> 087 * <td>top/bottom insets plus the largest of the children's min heights.</td></tr> 088 * <tr><th>preferred</th> 089 * <td>left/right insets plus the sum of each child's pref width plus spacing between each child.</td> 090 * <td>top/bottom insets plus the largest of the children's pref heights.</td></tr> 091 * <tr><th>maximum</th> 092 * <td>Double.MAX_VALUE</td><td>Double.MAX_VALUE</td></tr> 093 * </table> 094 * <p> 095 * An hbox's unbounded maximum width and height are an indication to the parent that 096 * it may be resized beyond its preferred size to fill whatever space is assigned 097 * to it. 098 * <p> 099 * HBox provides properties for setting the size range directly. These 100 * properties default to the sentinel value USE_COMPUTED_SIZE, however the 101 * application may set them to other values as needed: 102 * <pre><code> 103 * <b>hbox.setPrefWidth(400);</b> 104 * </code></pre> 105 * Applications may restore the computed values by setting these properties back 106 * to USE_COMPUTED_SIZE. 107 * <p> 108 * HBox does not clip its content by default, so it is possible that childrens' 109 * bounds may extend outside its own bounds if a child's min size prevents it from 110 * being fit within the hbox.</p> 111 * 112 * <h4>Optional Layout Constraints</h4> 113 * 114 * An application may set constraints on individual children to customize HBox's layout. 115 * For each constraint, HBox provides a static method for setting it on the child. 116 * <p> 117 * <table border="1"> 118 * <tr><th>Constraint</th><th>Type</th><th>Description</th></tr> 119 * <tr><td>hgrow</td><td>javafx.scene.layout.Priority</td><td>The horizontal grow priority for the child.</td></tr> 120 * <tr><td>margin</td><td>javafx.geometry.Insets</td><td>Margin space around the outside of the child.</td></tr> 121 * </table> 122 * <p> 123 * For example, if an hbox needs the TextField to be allocated all extra space: 124 * <pre><code> 125 * HBox hbox = new HBox(); 126 * TextField field = new TextField(); 127 * <b>HBox.setHgrow(field, Priority.ALWAYS);</b> 128 * hbox.getChildren().addAll(new Label("Search:"), field, new Button("Go")); 129 * </code></pre> 130 * 131 * If more than one child has the same grow priority set, then the hbox will 132 * allocate equal amounts of space to each. HBox will only grow a child up to 133 * its maximum width, so if the child has a max width other than Double.MAX_VALUE, 134 * the application may need to override the max to allow it to grow. 135 * For example: 136 * <pre><code> 137 * HBox hbox = new HBox(); 138 * Button button1 = new Button("Add"); 139 * Button button2 = new Button("Remove"); 140 * <b>HBox.setHgrow(button1, Priority.ALWAYS); 141 * HBox.setHgrow(button2, Priority.ALWAYS); 142 * button1.setMaxWidth(Double.MAX_VALUE); 143 * button2.setMaxWidth(Double.MAX_VALUE);</b> 144 * hbox.getChildren().addAll(button1, button2); 145 * </code></pre> 146 */ 147public class HBox extends Pane { 148 149 private boolean biasDirty = true; 150 private boolean performingLayout = false; 151 private Orientation bias; 152 153 /******************************************************************** 154 * BEGIN static methods 155 ********************************************************************/ 156 private static final String MARGIN_CONSTRAINT = "hbox-margin"; 157 private static final String HGROW_CONSTRAINT = "hbox-hgrow"; 158 159 /** 160 * Sets the horizontal grow priority for the child when contained by an hbox. 161 * If set, the hbox will use the priority to allocate additional space if the 162 * hbox is resized larger than it's preferred width. 163 * If multiple hbox children have the same horizontal grow priority, then the 164 * extra space will be split evening between them. 165 * If no horizontal grow priority is set on a child, the hbox will never 166 * allocate it additional horizontal space if available. 167 * Setting the value to null will remove the constraint. 168 * @param child the child of an hbox 169 * @param value the horizontal grow priority for the child 170 */ 171 public static void setHgrow(Node child, Priority value) { 172 setConstraint(child, HGROW_CONSTRAINT, value); 173 } 174 175 /** 176 * Returns the child's hgrow constraint if set. 177 * @param child the child node of an hbox 178 * @return the horizontal grow priority for the child or null if no priority was set 179 */ 180 public static Priority getHgrow(Node child) { 181 return (Priority)getConstraint(child, HGROW_CONSTRAINT); 182 } 183 184 /** 185 * Sets the margin for the child when contained by an hbox. 186 * If set, the hbox will layout the child with the margin space around it. 187 * Setting the value to null will remove the constraint. 188 * @param child the child mode of the hbox 189 * @param value the margin of space around the child 190 */ 191 public static void setMargin(Node child, Insets value) { 192 setConstraint(child, MARGIN_CONSTRAINT, value); 193 } 194 195 /** 196 * Returns the child's margin constraint if set. 197 * @param child the child node of an hbox 198 * @return the margin for the child or null if no margin was set 199 */ 200 public static Insets getMargin(Node child) { 201 return (Insets)getConstraint(child, MARGIN_CONSTRAINT); 202 } 203 204 /** 205 * Removes all hbox constraints from the child node. 206 * @param child the child node 207 */ 208 public static void clearConstraints(Node child) { 209 setHgrow(child, null); 210 setMargin(child, null); 211 } 212 213 /******************************************************************** 214 * END static methods 215 ********************************************************************/ 216 217 /** 218 * Creates an HBox layout with spacing = 0. 219 */ 220 public HBox() { 221 super(); 222 } 223 224 /** 225 * Creates an HBox layout with the specified spacing between children. 226 * @param spacing the amount of horizontal space between each child 227 */ 228 public HBox(double spacing) { 229 this(); 230 setSpacing(spacing); 231 } 232 233 /** 234 * Creates an HBox layout with spacing = 0. 235 * @param children The initial set of children for this pane. 236 */ 237 public HBox(Node... children) { 238 super(); 239 getChildren().addAll(children); 240 } 241 242 /** 243 * Creates an HBox layout with the specified spacing between children. 244 * @param spacing the amount of horizontal space between each child 245 * @param children The initial set of children for this pane. 246 */ 247 public HBox(double spacing, Node... children) { 248 this(); 249 setSpacing(spacing); 250 getChildren().addAll(children); 251 } 252 253 /** 254 * The amount of horizontal space between each child in the hbox. 255 */ 256 public final DoubleProperty spacingProperty() { 257 if (spacing == null) { 258 spacing = new StyleableDoubleProperty() { 259 @Override 260 public void invalidated() { 261 requestLayout(); 262 } 263 264 @Override 265 public CssMetaData getCssMetaData () { 266 return StyleableProperties.SPACING; 267 } 268 269 @Override 270 public Object getBean() { 271 return HBox.this; 272 } 273 274 @Override 275 public String getName() { 276 return "spacing"; 277 } 278 }; 279 } 280 return spacing; 281 } 282 283 private DoubleProperty spacing; 284 public final void setSpacing(double value) { spacingProperty().set(value); } 285 public final double getSpacing() { return spacing == null ? 0 : spacing.get(); } 286 287 /** 288 * The overall alignment of children within the hbox's width and height. 289 * If the vertical alignment value is BASELINE, then children will always be 290 * resized to their preferred heights and the fillHeight property will be 291 * ignored. 292 */ 293 public final ObjectProperty<Pos> alignmentProperty() { 294 if (alignment == null) { 295 alignment = new StyleableObjectProperty<Pos>(Pos.TOP_LEFT) { 296 @Override 297 public void invalidated() { 298 requestLayout(); 299 } 300 301 @Override 302 public CssMetaData<HBox, Pos> getCssMetaData() { 303 return StyleableProperties.ALIGNMENT; 304 } 305 306 @Override 307 public Object getBean() { 308 return HBox.this; 309 } 310 311 @Override 312 public String getName() { 313 return "alignment"; 314 } 315 }; 316 } 317 return alignment; 318 } 319 320 private ObjectProperty<Pos> alignment; 321 public final void setAlignment(Pos value) { alignmentProperty().set(value); } 322 public final Pos getAlignment() { return alignment == null ? Pos.TOP_LEFT : alignment.get(); } 323 private Pos getAlignmentInternal() { 324 Pos localPos = getAlignment(); 325 return localPos == null ? Pos.TOP_LEFT : localPos; 326 } 327 328 /** 329 * Whether or not resizable children will be resized to fill the full height of the hbox 330 * or be kept to their preferred height and aligned according to the <code>alignment</code> 331 * vpos value. Note that if the hbox vertical alignment is set to BASELINE, then this 332 * property will be ignored and children will be resized to their preferred heights. 333 */ 334 public final BooleanProperty fillHeightProperty() { 335 if (fillHeight == null) { 336 fillHeight = new StyleableBooleanProperty(true) { 337 @Override 338 public void invalidated() { 339 requestLayout(); 340 } 341 342 @Override 343 public CssMetaData<HBox, Boolean> getCssMetaData() { 344 return StyleableProperties.FILL_HEIGHT; 345 } 346 347 @Override 348 public Object getBean() { 349 return HBox.this; 350 } 351 352 @Override 353 public String getName() { 354 return "fillHeight"; 355 } 356 }; 357 } 358 return fillHeight; 359 } 360 361 private BooleanProperty fillHeight; 362 public final void setFillHeight(boolean value) { fillHeightProperty().set(value); } 363 public final boolean isFillHeight() { return fillHeight == null ? true : fillHeight.get(); } 364 365 private boolean shouldFillHeight() { 366 return isFillHeight() && getAlignmentInternal().getVpos() != VPos.BASELINE; 367 } 368 369 /** 370 * 371 * @return null unless one of its children has a content bias. 372 */ 373 @Override public Orientation getContentBias() { 374 if (biasDirty) { 375 final List<Node> children = getChildren(); 376 for (Node child : children) { 377 Orientation contentBias = child.getContentBias(); 378 if (child.isManaged() && contentBias != null) { 379 bias = contentBias; 380 break; 381 } 382 } 383 biasDirty = false; 384 } 385 return bias; 386 } 387 388 @Override protected double computeMinWidth(double height) { 389 Insets insets = getInsets(); 390 return snapSpace(insets.getLeft()) + 391 computeContentWidth(getAreaWidths(getManagedChildren(), height, true)) + 392 snapSpace(insets.getRight()); 393 } 394 395 @Override protected double computeMinHeight(double width) { 396 Insets insets = getInsets(); 397 List<Node>managed = getManagedChildren(); 398 double contentHeight = 0; 399 if (getContentBias() == Orientation.HORIZONTAL) { 400 // if width is different than preferred, then child widths may grow or shrink, 401 // altering the height of any child with a horizontal contentBias. 402 double prefWidths[] = getAreaWidths(managed, -1, false); 403 adjustAreaWidths(managed, prefWidths, width, -1); 404 contentHeight = computeMaxMinAreaHeight(managed, getMargins(managed), prefWidths, getAlignmentInternal().getVpos()); 405 } else { 406 contentHeight = computeMaxMinAreaHeight(managed, getMargins(managed), getAlignmentInternal().getVpos()); 407 } 408 return snapSpace(insets.getTop()) + 409 contentHeight + 410 snapSpace(insets.getBottom()); 411 } 412 413 @Override protected double computePrefWidth(double height) { 414 Insets insets = getInsets(); 415 return snapSpace(insets.getLeft()) + 416 computeContentWidth(getAreaWidths(getManagedChildren(), height, false)) + 417 snapSpace(insets.getRight()); 418 } 419 420 @Override protected double computePrefHeight(double width) { 421 Insets insets = getInsets(); 422 List<Node>managed = getManagedChildren(); 423 double contentHeight = 0; 424 if (getContentBias() == Orientation.HORIZONTAL) { 425 // if width is different than preferred, then child widths may grow or shrink, 426 // altering the height of any child with a horizontal contentBias. 427 double prefWidths[] = getAreaWidths(managed, -1, false); 428 adjustAreaWidths(managed, prefWidths, width, -1); 429 contentHeight = computeMaxPrefAreaHeight(managed, getMargins(managed), prefWidths, getAlignmentInternal().getVpos()); 430 } else { 431 contentHeight = computeMaxPrefAreaHeight(managed, getMargins(managed), getAlignmentInternal().getVpos()); 432 } 433 return snapSpace(insets.getTop()) + 434 contentHeight + 435 snapSpace(insets.getBottom()); 436 } 437 438 private Insets[] getMargins(List<Node>managed) { 439 Insets margins[] = new Insets[managed.size()]; 440 for(int i = 0; i < margins.length; i++) { 441 margins[i] = getMargin(managed.get(i)); 442 } 443 return margins; 444 } 445 446 private double[] getAreaWidths(List<Node>managed, double height, boolean minimum) { 447 // height could be -1 448 double[] prefAreaWidths = new double [managed.size()]; 449 final double insideHeight = height == -1? -1 : height - 450 snapSpace(getInsets().getTop()) - snapSpace(getInsets().getBottom()); 451 for (int i = 0, size = managed.size(); i < size; i++) { 452 Node child = managed.get(i); 453 Insets margin = getMargin(child); 454 prefAreaWidths[i] = minimum? 455 computeChildMinAreaWidth(child, margin, 456 shouldFillHeight()? insideHeight : child.minHeight(-1)) : 457 computeChildPrefAreaWidth(child, margin, 458 shouldFillHeight()? insideHeight : child.prefHeight(-1)); 459 } 460 return prefAreaWidths; 461 } 462 463 private double adjustAreaWidths(List<Node>managed, double areaWidths[], double width, double height) { 464 Insets insets = getInsets(); 465 double top = snapSpace(insets.getTop()); 466 double bottom = snapSpace(insets.getBottom()); 467 468 double contentWidth = computeContentWidth(areaWidths); 469 double extraWidth = (width == -1? prefWidth(-1) : width) - 470 snapSpace(insets.getLeft()) - snapSpace(insets.getRight()) - contentWidth; 471 472 if (extraWidth != 0) { 473 double remaining = growOrShrinkAreaWidths(managed, areaWidths, Priority.ALWAYS, extraWidth, 474 shouldFillHeight() && height != -1? height - top - bottom : -1); 475 remaining = growOrShrinkAreaWidths(managed, areaWidths, Priority.SOMETIMES, remaining, 476 shouldFillHeight() && height != -1? height - top - bottom : -1); 477 contentWidth += (extraWidth - remaining); 478 } 479 return contentWidth; 480 } 481 482 private double growOrShrinkAreaWidths(List<Node>managed, double areaWidths[], Priority priority, double extraWidth, double height) { 483 final boolean shrinking = extraWidth < 0; 484 List<Node> adjustList = new ArrayList<Node>(); 485 List<Node> adjusting = new ArrayList<Node>(); 486 487 for (int i = 0, size = managed.size(); i < size; i++) { 488 final Node child = managed.get(i); 489 if (shrinking || getHgrow(child) == priority) { 490 adjustList.add(child); 491 adjusting.add(child); 492 } 493 } 494 495 double[] areaLimitWidths = new double[adjustList.size()]; 496 for (int i = 0, size = adjustList.size(); i < size; i++) { 497 final Node child = adjustList.get(i); 498 final Insets margin = getMargin(child); 499 areaLimitWidths[i] = shrinking? 500 computeChildMinAreaWidth(child, margin, height) : computeChildMaxAreaWidth(child, margin, height); 501 } 502 503 double available = extraWidth; // will be negative in shrinking case 504 while (Math.abs(available) > 1.0 && adjusting.size() > 0) { 505 Node[] adjusted = new Node[adjustList.size()]; 506 final double portion = available / adjusting.size(); // negative in shrinking case 507 for (int i = 0, size = adjusting.size(); i < size; i++) { 508 final Node child = adjusting.get(i); 509 final int childIndex = managed.indexOf(child); 510 final double limit = areaLimitWidths[adjustList.indexOf(child)] - areaWidths[childIndex]; // negative in shrinking case 511 final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion; 512 areaWidths[childIndex] += change; 513 //if (node.id.startsWith("debug.")) println("{if (shrinking) "shrink" else "grow"}: {node.id} portion({portion})=available({available})/({sizeof adjusting}) change={change}"); 514 available -= change; 515 if (Math.abs(change) < Math.abs(portion)) { 516 adjusted[i] = child; 517 } 518 } 519 for (int i = 0; i < adjusted.length; i++) { 520 Node node = adjusted[i]; 521 if (node != null) { 522 adjusting.remove(node); 523 } 524 } 525 } 526 for (int i = 0; i < areaWidths.length; i++) { 527 areaWidths[i] = snapSpace(areaWidths[i]); 528 } 529 return available; // might be negative in shrinking case 530 } 531 532 private double computeContentWidth(double[] widths) { 533 double total = 0; 534 for (double w : widths) { 535 total += w; 536 } 537 return total + (widths.length-1)*snapSpace(getSpacing()); 538 } 539 540 private double[] actualAreaWidths; 541 542 @Override public void requestLayout() { 543 if (performingLayout) { 544 return; 545 } 546 biasDirty = true; 547 bias = null; 548 super.requestLayout(); 549 } 550 551 @Override protected void layoutChildren() { 552 performingLayout = true; 553 List<Node> managed = getManagedChildren(); 554 Insets insets = getInsets(); 555 Pos align = getAlignmentInternal(); 556 HPos alignHpos = align.getHpos(); 557 VPos alignVpos = align.getVpos(); 558 double width = getWidth(); 559 double height = getHeight(); 560 double top = snapSpace(insets.getTop()); 561 double left = snapSpace(insets.getLeft()); 562 double bottom = snapSpace(insets.getBottom()); 563 double right = snapSpace(insets.getRight()); 564 double space = snapSpace(getSpacing()); 565 boolean shouldFillHeight = shouldFillHeight(); 566 567 actualAreaWidths = getAreaWidths(managed, height, false); 568 double contentWidth = adjustAreaWidths(managed, actualAreaWidths, width, height); 569 double contentHeight = height - top - bottom; 570 571 double x = snapSpace(insets.getLeft()) + computeXOffset(width - left - right, contentWidth, align.getHpos()); 572 double y = snapSpace(insets.getTop()); 573 double baselineOffset = alignVpos == VPos.BASELINE ? getMaxBaselineOffset(managed) 574 : height/2; 575 576 for (int i = 0, size = managed.size(); i < size; i++) { 577 Node child = managed.get(i); 578 Insets margin = getMargin(child); 579 layoutInArea(child, x, y, actualAreaWidths[i], contentHeight, 580 baselineOffset, margin, true, shouldFillHeight, 581 alignHpos, alignVpos); 582 x += actualAreaWidths[i] + space; 583 } 584 performingLayout = false; 585 } 586 587 588 /*************************************************************************** 589 * * 590 * Stylesheet Handling * 591 * * 592 **************************************************************************/ 593 594 /** 595 * Super-lazy instantiation pattern from Bill Pugh. 596 * @treatAsPrivate implementation detail 597 */ 598 private static class StyleableProperties { 599 600 private static final CssMetaData<HBox,Pos> ALIGNMENT = 601 new CssMetaData<HBox,Pos>("-fx-alignment", 602 new EnumConverter<Pos>(Pos.class), 603 Pos.TOP_LEFT) { 604 605 @Override 606 public boolean isSettable(HBox node) { 607 return node.alignment == null || !node.alignment.isBound(); 608 } 609 610 @Override 611 public StyleableProperty<Pos> getStyleableProperty(HBox node) { 612 return (StyleableProperty<Pos>)node.alignmentProperty(); 613 } 614 615 }; 616 617 private static final CssMetaData<HBox,Boolean> FILL_HEIGHT = 618 new CssMetaData<HBox,Boolean>("-fx-fill-height", 619 BooleanConverter.getInstance(), Boolean.TRUE) { 620 621 @Override 622 public boolean isSettable(HBox node) { 623 return node.fillHeight == null || 624 !node.fillHeight.isBound(); 625 } 626 627 @Override 628 public StyleableProperty<Boolean> getStyleableProperty(HBox node) { 629 return (StyleableProperty<Boolean>)node.fillHeightProperty(); 630 } 631 632 }; 633 634 private static final CssMetaData<HBox,Number> SPACING = 635 new CssMetaData<HBox,Number>("-fx-spacing", 636 SizeConverter.getInstance(), 0.0){ 637 638 @Override 639 public boolean isSettable(HBox node) { 640 return node.spacing == null || !node.spacing.isBound(); 641 } 642 643 @Override 644 public StyleableProperty<Number> getStyleableProperty(HBox node) { 645 return (StyleableProperty<Number>)node.spacingProperty(); 646 } 647 648 }; 649 650 private static final List<CssMetaData<? extends Styleable, ?>> STYLEABLES; 651 static { 652 final List<CssMetaData<? extends Styleable, ?>> styleables = 653 new ArrayList<CssMetaData<? extends Styleable, ?>>(Pane.getClassCssMetaData()); 654 styleables.add(FILL_HEIGHT); 655 styleables.add(ALIGNMENT); 656 styleables.add(SPACING); 657 STYLEABLES = Collections.unmodifiableList(styleables); 658 } 659 } 660 661 /** 662 * @return The CssMetaData associated with this class, which may include the 663 * CssMetaData of its super classes. 664 */ 665 public static List<CssMetaData<? extends Styleable, ?>> getClassCssMetaData() { 666 return StyleableProperties.STYLEABLES; 667 } 668 669 /** 670 * {@inheritDoc} 671 * 672 */ 673 674 675 @Override 676 public List<CssMetaData<? extends Styleable, ?>> getCssMetaData() { 677 return getClassCssMetaData(); 678 } 679 680}