1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.scene.control.skin;
  27 
  28 import static org.junit.Assert.assertEquals;
  29 import static org.junit.Assert.assertNull;
  30 
  31 import java.util.Arrays;
  32 import java.util.Collection;
  33 
  34 import javafx.geometry.BoundingBox;
  35 import javafx.geometry.Bounds;
  36 import javafx.scene.Node;
  37 import javafx.scene.control.ContentDisplay;
  38 import javafx.scene.control.Label;
  39 import javafx.scene.control.SkinBaseAccessor;
  40 import javafx.scene.control.skin.LabelSkin;
  41 import javafx.scene.shape.Rectangle;
  42 import javafx.scene.text.Font;
  43 import javafx.scene.text.Text;
  44 
  45 import org.junit.Before;
  46 import org.junit.Test;
  47 import org.junit.runner.RunWith;
  48 import org.junit.runners.Parameterized;
  49 import org.junit.runners.Parameterized.Parameters;
  50 
  51 /**
  52  */
  53 @RunWith(Parameterized.class)
  54 public class LabelSkinLayoutTest {
  55     private static final double GRAPHIC_WIDTH = 23;
  56     private static final double GRAPHIC_HEIGHT = 32;
  57     private static final double LABEL_WIDTH = 300;
  58     private static final double LABEL_HEIGHT = 300;
  59     
  60     @SuppressWarnings("rawtypes")
  61     @Parameters public static Collection implementations() {
  62         return Arrays.asList(new Object[][] {
  63                 {-10},
  64                 {0},
  65                 {10}
  66 //            { HPos.CENTER, VPos.BOTTOM, -10 },
  67 //            { HPos.CENTER, VPos.BOTTOM, 0 },
  68 //            { HPos.CENTER, VPos.BOTTOM, 10 },
  69 //            { HPos.CENTER, VPos.CENTER, -10 },
  70 //            { HPos.CENTER, VPos.CENTER, 0 },
  71 //            { HPos.CENTER, VPos.CENTER, 10 },
  72 //            { HPos.CENTER, VPos.TOP, -10 },
  73 //            { HPos.CENTER, VPos.TOP, 0 },
  74 //            { HPos.CENTER, VPos.TOP, 10 },
  75 //            { HPos.LEFT, VPos.BOTTOM, -10 },
  76 //            { HPos.LEFT, VPos.BOTTOM, 0 },
  77 //            { HPos.LEFT, VPos.BOTTOM, 10 },
  78 //            { HPos.LEFT, VPos.CENTER, -10 },
  79 //            { HPos.LEFT, VPos.CENTER, 0 },
  80 //            { HPos.LEFT, VPos.CENTER, 10 },
  81 //            { HPos.LEFT, VPos.TOP, -10 },
  82 //            { HPos.LEFT, VPos.TOP, 0 },
  83 //            { HPos.LEFT, VPos.TOP, 10 },
  84 //            { HPos.RIGHT, VPos.BOTTOM, -10 },
  85 //            { HPos.RIGHT, VPos.BOTTOM, 0 },
  86 //            { HPos.RIGHT, VPos.BOTTOM, 10 },
  87 //            { HPos.RIGHT, VPos.CENTER, -10 },
  88 //            { HPos.RIGHT, VPos.CENTER, 0 },
  89 //            { HPos.RIGHT, VPos.CENTER, 10 },
  90 //            { HPos.RIGHT, VPos.TOP, -10 },
  91 //            { HPos.RIGHT, VPos.TOP, 0 },
  92 //            { HPos.RIGHT, VPos.TOP, 10 },
  93         });
  94     }
  95 
  96     private int graphicTextGap = 0;
  97 //    private VPos vpos;
  98 //    private HPos hpos;
  99     private Label label;
 100     private LabelSkin skin;
 101     private Text text;
 102     
 103     public LabelSkinLayoutTest(int graphicTextGap) {
 104 //    public LabelSkinLayoutTest(HPos hpos, VPos vpos, int graphicTextGap) {
 105         this.graphicTextGap = graphicTextGap;
 106 //        this.hpos = hpos;
 107 //        this.vpos = vpos;
 108     }
 109 
 110     // We will parameterize the hpos and vpos to use, but all of the other tests
 111     // are all done manually.
 112     
 113     @Before public void setup() {
 114         label = new Label();
 115         label.resize(LABEL_WIDTH, LABEL_HEIGHT);
 116         label.setGraphicTextGap(graphicTextGap);
 117 //        label.setHpos(hpos);
 118 //        label.setVpos(vpos);
 119         skin = new LabelSkin(label);
 120         label.setSkin(skin);
 121         text = skin.text;
 122     }
 123 
 124     private Bounds getContentBounds() {
 125         Bounds b = null;
 126         for (Node child : SkinBaseAccessor.getChildren(skin)) {
 127             if (child.isManaged()) {
 128                 Bounds childBounds = child.getBoundsInParent();
 129                 if (b == null) {
 130                     b = childBounds;
 131                 } else {
 132                     final double minX = Math.min(b.getMinX(), childBounds.getMinX());
 133                     final double minY = Math.min(b.getMinY(), childBounds.getMinY());
 134                     final double maxX = Math.max(b.getMaxX(), childBounds.getMaxX());
 135                     final double maxY = Math.max(b.getMaxY(), childBounds.getMaxY());
 136                     b = new BoundingBox(minX, minY, maxX - minX, maxY - minY);
 137                 }
 138             }
 139         }
 140         return b;
 141     }
 142     
 143     private Bounds getNormalizedBounds(Bounds contentBounds, Node graphic) {
 144         Bounds b = graphic.getBoundsInParent();
 145         return new BoundingBox(
 146                 b.getMinX() - contentBounds.getMinX(),
 147                 b.getMinY() - contentBounds.getMinY(),
 148                 b.getWidth(),
 149                 b.getHeight());
 150     }
 151     
 152     // Note that in Label, we pixel align so that the text is crisp, so do so here
 153     private void assertCenteredHorizontally(Bounds totalSpace, Bounds b) {
 154         if (b.getWidth() != totalSpace.getWidth()) {
 155             final double expected = Math.round((totalSpace.getWidth() - b.getWidth()) / 2.0);
 156             assertEquals(expected, b.getMinX(), 0.001);
 157         }
 158     }
 159 
 160     // Note that in Label, we pixel align (snap to pixel)
 161     private void assertCenteredVertically(Bounds totalSpace, Bounds b) {
 162         if (b.getHeight() != totalSpace.getHeight()) {
 163             final double expected = Math.round((totalSpace.getHeight() - b.getHeight()) / 2.0);
 164             assertEquals(expected, b.getMinY(), 0.001);
 165         }
 166     }
 167     
 168     private void assertContentAreaPositionedCorrectly(Bounds contentBounds) {
 169 //        switch (label.getVpos()) {
 170 //            //case BASELINE:
 171 //            case CENTER:
 172 //                assertCenteredVertically(label.getBoundsInLocal(), contentBounds);
 173 //                break;
 174 //            case BOTTOM:
 175 //                assertEquals(label.getBoundsInLocal().getHeight(), contentBounds.getMaxY(), 0.001);
 176 //                break;
 177 //            case TOP:
 178 //                assertEquals(0, contentBounds.getMinY(), 0);
 179 //                break;
 180 //            default:
 181 //                System.err.println("Unhandled vpos case for LabelSkinLayoutTest");
 182 //        }
 183     }
 184     
 185     @Test public void graphic_nullText_TOP() {
 186         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 187         label.setGraphic(graphic);
 188         label.setText(null);
 189         label.setContentDisplay(ContentDisplay.TOP);        
 190         label.layout();
 191         
 192         Bounds contentBounds = getContentBounds();
 193         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 194         assertContentAreaPositionedCorrectly(contentBounds);
 195         // Graphic alone makes up the content bounds, so contentBounds and
 196         // graphic bounds should have the same width and height
 197         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 198         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 199     }
 200 
 201     @Test public void graphic_emptyText_TOP() {
 202         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 203         label.setGraphic(graphic);
 204         label.setText("");
 205         label.setContentDisplay(ContentDisplay.TOP);
 206         label.layout();
 207         
 208         Bounds contentBounds = getContentBounds();
 209         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 210         assertContentAreaPositionedCorrectly(contentBounds);
 211         // Graphic alone makes up the content bounds, so contentBounds and
 212         // graphic bounds should have the same width and height
 213         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 214         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 215     }
 216 
 217     @Test public void graphic_Text_TOP() {
 218         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 219         label.setGraphic(graphic);
 220         label.setText("Falcon");
 221         label.setFont(new Font("Amble Condensed", 12));
 222         label.setContentDisplay(ContentDisplay.TOP);
 223         label.layout();
 224         
 225         // There is both a graphic & text node in this case. So we need to
 226         // compare their positions. Since this is TOP, the graphic should
 227         // be above the text by the amount specified in graphic-text-gap
 228         Bounds contentBounds = getContentBounds();
 229         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 230         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 231         assertContentAreaPositionedCorrectly(contentBounds);
 232         final double expected = Math.round(textBounds.getMinY() - (GRAPHIC_HEIGHT + label.getGraphicTextGap()));
 233         assertEquals(expected, graphicBounds.getMinY(), 0);
 234         // And they should both be centered horizontally
 235         assertCenteredHorizontally(contentBounds, graphicBounds);
 236         assertCenteredHorizontally(contentBounds, textBounds);
 237     }
 238 
 239     @Test public void unmanagedGraphic_nullText_TOP() {
 240         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 241         graphic.setManaged(false);
 242         label.setGraphic(graphic);
 243         label.setText(null);
 244         label.setContentDisplay(ContentDisplay.TOP);
 245         label.layout();
 246         
 247         assertNull(getContentBounds());
 248     }
 249 
 250     @Test public void unmanagedGraphic_emptyText_TOP() {
 251         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 252         graphic.setManaged(false);
 253         label.setGraphic(graphic);
 254         label.setText("");
 255         label.setContentDisplay(ContentDisplay.TOP);
 256         label.layout();
 257         
 258         assertNull(getContentBounds());
 259     }
 260 
 261     @Test public void unmanagedGraphic_Text_TOP() {
 262         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 263         graphic.setManaged(false);
 264         label.setGraphic(graphic);
 265         label.setText("Falcon");
 266         label.setContentDisplay(ContentDisplay.TOP);
 267         label.layout();
 268         
 269         Bounds contentBounds = getContentBounds();
 270         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 271         assertContentAreaPositionedCorrectly(contentBounds);
 272         // Text alone makes up the content bounds, so contentBounds and
 273         // text bounds should have the same width and height
 274         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 275         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 276     }
 277 
 278     @Test public void noGraphic_nullText_TOP() {
 279         label.setText(null);
 280         label.setContentDisplay(ContentDisplay.TOP);
 281         label.layout();
 282         
 283         assertNull(getContentBounds());
 284     }
 285 
 286     @Test public void noGraphic_emptyText_TOP() {
 287         label.setText("");
 288         label.setContentDisplay(ContentDisplay.TOP);
 289         label.layout();
 290         
 291         assertNull(getContentBounds());
 292     }
 293 
 294     @Test public void noGraphic_Text_TOP() {
 295         label.setText("Falcon");
 296         label.setContentDisplay(ContentDisplay.TOP);
 297         label.layout();
 298         
 299         Bounds contentBounds = getContentBounds();
 300         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 301         assertContentAreaPositionedCorrectly(contentBounds);
 302         // Text alone makes up the content bounds, so contentBounds and
 303         // text bounds should have the same width and height
 304         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 305         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 306     }
 307 
 308     /** */
 309     @Test public void graphic_nullText_RIGHT() {
 310         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 311         label.setGraphic(graphic);
 312         label.setText(null);
 313         label.setContentDisplay(ContentDisplay.RIGHT);
 314         label.layout();
 315         
 316         Bounds contentBounds = getContentBounds();
 317         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 318         assertContentAreaPositionedCorrectly(contentBounds);
 319         // Graphic alone makes up the content bounds, so contentBounds and
 320         // graphic bounds should have the same width and height
 321         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 322         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 323     }
 324 
 325     @Test public void graphic_emptyText_RIGHT() {
 326         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 327         label.setGraphic(graphic);
 328         label.setText("");
 329         label.setContentDisplay(ContentDisplay.RIGHT);
 330         label.layout();
 331         
 332         Bounds contentBounds = getContentBounds();
 333         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 334         assertContentAreaPositionedCorrectly(contentBounds);
 335         // Graphic alone makes up the content bounds, so contentBounds and
 336         // graphic bounds should have the same width and height
 337         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 338         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 339     }
 340 
 341     @Test public void graphic_Text_RIGHT() {
 342         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 343         label.setGraphic(graphic);
 344         label.setText("Falcon");
 345         label.setContentDisplay(ContentDisplay.RIGHT);
 346         label.layout();
 347         
 348         // There is both a graphic & text node in this case. So we need to
 349         // compare their positions. Since this is RIGHT, the graphic should
 350         // be right of the text by the amount specified in graphic-text-gap
 351         Bounds contentBounds = getContentBounds();
 352         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 353         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 354         assertContentAreaPositionedCorrectly(contentBounds);
 355         final double expected = Math.round(textBounds.getMaxX() + label.getGraphicTextGap());
 356         assertEquals(expected, graphicBounds.getMinX(), 0.001);
 357         // And they should both be centered vertically
 358         assertCenteredVertically(contentBounds, graphicBounds);
 359         assertCenteredVertically(contentBounds, textBounds);
 360     }
 361 
 362     @Test public void unmanagedGraphic_nullText_RIGHT() {
 363         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 364         graphic.setManaged(false);
 365         label.setGraphic(graphic);
 366         label.setText(null);
 367         label.setContentDisplay(ContentDisplay.RIGHT);
 368         label.layout();
 369         
 370         assertNull(getContentBounds());
 371     }
 372 
 373     @Test public void unmanagedGraphic_emptyText_RIGHT() {
 374         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 375         graphic.setManaged(false);
 376         label.setGraphic(graphic);
 377         label.setText("");
 378         label.setContentDisplay(ContentDisplay.RIGHT);
 379         label.layout();
 380         
 381         assertNull(getContentBounds());
 382     }
 383 
 384     @Test public void unmanagedGraphic_Text_RIGHT() {
 385         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 386         graphic.setManaged(false);
 387         label.setGraphic(graphic);
 388         label.setText("Falcon");
 389         label.setContentDisplay(ContentDisplay.RIGHT);
 390         label.layout();
 391         
 392         Bounds contentBounds = getContentBounds();
 393         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 394         assertContentAreaPositionedCorrectly(contentBounds);
 395         // Text alone makes up the content bounds, so contentBounds and
 396         // text bounds should have the same width and height
 397         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 398         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 399     }
 400 
 401     @Test public void noGraphic_nullText_RIGHT() {
 402         label.setText(null);
 403         label.setContentDisplay(ContentDisplay.RIGHT);
 404         label.layout();
 405         
 406         assertNull(getContentBounds());
 407     }
 408 
 409     @Test public void noGraphic_emptyText_RIGHT() {
 410         label.setText("");
 411         label.setContentDisplay(ContentDisplay.RIGHT);
 412         label.layout();
 413         
 414         assertNull(getContentBounds());
 415     }
 416 
 417     @Test public void noGraphic_Text_RIGHT() {
 418         label.setText("Falcon");
 419         label.setContentDisplay(ContentDisplay.RIGHT);
 420         label.layout();
 421         
 422         Bounds contentBounds = getContentBounds();
 423         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 424         assertContentAreaPositionedCorrectly(contentBounds);
 425         // Text alone makes up the content bounds, so contentBounds and
 426         // text bounds should have the same width and height
 427         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 428         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 429     }
 430 
 431     /** */
 432     @Test public void graphic_nullText_BOTTOM() {
 433         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 434         label.setGraphic(graphic);
 435         label.setText(null);
 436         label.setContentDisplay(ContentDisplay.BOTTOM);
 437         label.layout();
 438         
 439         Bounds contentBounds = getContentBounds();
 440         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 441         assertContentAreaPositionedCorrectly(contentBounds);
 442         // Graphic alone makes up the content bounds, so contentBounds and
 443         // graphic bounds should have the same width and height
 444         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 445         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 446     }
 447 
 448     @Test public void graphic_emptyText_BOTTOM() {
 449         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 450         label.setGraphic(graphic);
 451         label.setText("");
 452         label.setContentDisplay(ContentDisplay.BOTTOM);
 453         label.layout();
 454         
 455         Bounds contentBounds = getContentBounds();
 456         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 457         assertContentAreaPositionedCorrectly(contentBounds);
 458         // Graphic alone makes up the content bounds, so contentBounds and
 459         // graphic bounds should have the same width and height
 460         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 461         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 462     }
 463 
 464     @Test public void graphic_Text_BOTTOM() {
 465         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 466         label.setGraphic(graphic);
 467         label.setText("Falcon");
 468         label.setFont(new Font("Amble Condensed", 12));
 469         label.setContentDisplay(ContentDisplay.BOTTOM);
 470         label.layout();
 471         
 472         // There is both a graphic & text node in this case. So we need to
 473         // compare their positions. Since this is BOTTOM, the graphic should
 474         // be below the text by the amount specified in graphic-text-gap
 475         Bounds contentBounds = getContentBounds();
 476         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 477         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 478         assertContentAreaPositionedCorrectly(contentBounds);
 479         final double expected = Math.round(textBounds.getMaxY() + label.getGraphicTextGap());
 480         assertEquals(expected, graphicBounds.getMinY(), 0);
 481         // And they should both be centered horizontally
 482         assertCenteredHorizontally(contentBounds, graphicBounds);
 483         assertCenteredHorizontally(contentBounds, textBounds);
 484     }
 485 
 486     @Test public void unmanagedGraphic_nullText_BOTTOM() {
 487         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 488         graphic.setManaged(false);
 489         label.setGraphic(graphic);
 490         label.setText(null);
 491         label.setContentDisplay(ContentDisplay.BOTTOM);
 492         label.layout();
 493         
 494         assertNull(getContentBounds());
 495     }
 496 
 497     @Test public void unmanagedGraphic_emptyText_BOTTOM() {
 498         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 499         graphic.setManaged(false);
 500         label.setGraphic(graphic);
 501         label.setText("");
 502         label.setContentDisplay(ContentDisplay.BOTTOM);
 503         label.layout();
 504         
 505         assertNull(getContentBounds());
 506     }
 507 
 508     @Test public void unmanagedGraphic_Text_BOTTOM() {
 509         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 510         graphic.setManaged(false);
 511         label.setGraphic(graphic);
 512         label.setText("Falcon");
 513         label.setContentDisplay(ContentDisplay.BOTTOM);
 514         label.layout();
 515         
 516         Bounds contentBounds = getContentBounds();
 517         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 518         assertContentAreaPositionedCorrectly(contentBounds);
 519         // Text alone makes up the content bounds, so contentBounds and
 520         // text bounds should have the same width and height
 521         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 522         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 523     }
 524 
 525     @Test public void noGraphic_nullText_BOTTOM() {
 526         label.setText(null);
 527         label.setContentDisplay(ContentDisplay.BOTTOM);
 528         label.layout();
 529         
 530         assertNull(getContentBounds());
 531     }
 532 
 533     @Test public void noGraphic_emptyText_BOTTOM() {
 534         label.setText("");
 535         label.setContentDisplay(ContentDisplay.BOTTOM);
 536         label.layout();
 537         
 538         assertNull(getContentBounds());
 539     }
 540 
 541     @Test public void noGraphic_Text_BOTTOM() {
 542         label.setText("Falcon");
 543         label.setContentDisplay(ContentDisplay.BOTTOM);
 544         label.layout();
 545         
 546         Bounds contentBounds = getContentBounds();
 547         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 548         assertContentAreaPositionedCorrectly(contentBounds);
 549         // Text alone makes up the content bounds, so contentBounds and
 550         // text bounds should have the same width and height
 551         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 552         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 553     }
 554 
 555     /** */
 556     @Test public void graphic_nullText_LEFT() {
 557         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 558         label.setGraphic(graphic);
 559         label.setText(null);
 560         label.setContentDisplay(ContentDisplay.LEFT);
 561         label.layout();
 562         
 563         Bounds contentBounds = getContentBounds();
 564         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 565         assertContentAreaPositionedCorrectly(contentBounds);
 566         // Graphic alone makes up the content bounds, so contentBounds and
 567         // graphic bounds should have the same width and height
 568         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 569         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 570     }
 571 
 572     @Test public void graphic_emptyText_LEFT() {
 573         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 574         label.setGraphic(graphic);
 575         label.setText("");
 576         label.setContentDisplay(ContentDisplay.LEFT);
 577         label.layout();
 578         
 579         Bounds contentBounds = getContentBounds();
 580         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 581         assertContentAreaPositionedCorrectly(contentBounds);
 582         // Graphic alone makes up the content bounds, so contentBounds and
 583         // graphic bounds should have the same width and height
 584         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 585         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 586     }
 587 
 588     @Test public void graphic_Text_LEFT() {
 589         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 590         label.setGraphic(graphic);
 591         label.setText("Falcon");
 592         label.setContentDisplay(ContentDisplay.LEFT);
 593         label.layout();
 594         
 595         // There is both a graphic & text node in this case. So we need to
 596         // compare their positions. Since this is LEFT, the graphic should
 597         // be left of the text by the amount specified in graphic-text-gap
 598         Bounds contentBounds = getContentBounds();
 599         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 600         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 601         assertContentAreaPositionedCorrectly(contentBounds);
 602         final double expected = Math.round(graphicBounds.getMaxX() + label.getGraphicTextGap());
 603         assertEquals(expected, textBounds.getMinX(), 0.001);
 604         // And they should both be centered vertically
 605         assertCenteredVertically(contentBounds, graphicBounds);
 606         assertCenteredVertically(contentBounds, textBounds);
 607     }
 608 
 609     @Test public void unmanagedGraphic_nullText_LEFT() {
 610         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 611         graphic.setManaged(false);
 612         label.setGraphic(graphic);
 613         label.setText(null);
 614         label.setContentDisplay(ContentDisplay.LEFT);
 615         label.layout();
 616         
 617         assertNull(getContentBounds());
 618     }
 619 
 620     @Test public void unmanagedGraphic_emptyText_LEFT() {
 621         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 622         graphic.setManaged(false);
 623         label.setGraphic(graphic);
 624         label.setText("");
 625         label.setContentDisplay(ContentDisplay.LEFT);
 626         label.layout();
 627         
 628         assertNull(getContentBounds());
 629     }
 630 
 631     @Test public void unmanagedGraphic_Text_LEFT() {
 632         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 633         graphic.setManaged(false);
 634         label.setGraphic(graphic);
 635         label.setText("Falcon");
 636         label.setContentDisplay(ContentDisplay.LEFT);
 637         label.layout();
 638         
 639         Bounds contentBounds = getContentBounds();
 640         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 641         assertContentAreaPositionedCorrectly(contentBounds);
 642         // Text alone makes up the content bounds, so contentBounds and
 643         // text bounds should have the same width and height
 644         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 645         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 646     }
 647 
 648     @Test public void noGraphic_nullText_LEFT() {
 649         label.setText(null);
 650         label.setContentDisplay(ContentDisplay.LEFT);
 651         label.layout();
 652         
 653         assertNull(getContentBounds());
 654     }
 655 
 656     @Test public void noGraphic_emptyText_LEFT() {
 657         label.setText("");
 658         label.setContentDisplay(ContentDisplay.LEFT);
 659         label.layout();
 660         
 661         assertNull(getContentBounds());
 662     }
 663 
 664     @Test public void noGraphic_Text_LEFT() {
 665         label.setText("Falcon");
 666         label.setContentDisplay(ContentDisplay.LEFT);
 667         label.layout();
 668         
 669         Bounds contentBounds = getContentBounds();
 670         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 671         assertContentAreaPositionedCorrectly(contentBounds);
 672         // Text alone makes up the content bounds, so contentBounds and
 673         // text bounds should have the same width and height
 674         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 675         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 676     }
 677 
 678     /** */
 679     @Test public void graphic_nullText_CENTER() {
 680         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 681         label.setGraphic(graphic);
 682         label.setText(null);
 683         label.setContentDisplay(ContentDisplay.CENTER);
 684         label.layout();
 685         
 686         Bounds contentBounds = getContentBounds();
 687         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 688         assertContentAreaPositionedCorrectly(contentBounds);
 689         // Graphic alone makes up the content bounds, so contentBounds and
 690         // graphic bounds should have the same width and height
 691         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 692         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 693     }
 694 
 695     @Test public void graphic_emptyText_CENTER() {
 696         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 697         label.setGraphic(graphic);
 698         label.setText("");
 699         label.setContentDisplay(ContentDisplay.CENTER);
 700         label.layout();
 701         
 702         Bounds contentBounds = getContentBounds();
 703         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 704         assertContentAreaPositionedCorrectly(contentBounds);
 705         // Graphic alone makes up the content bounds, so contentBounds and
 706         // graphic bounds should have the same width and height
 707         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 708         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 709     }
 710 
 711     @Test public void graphic_Text_CENTER() {
 712         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 713         label.setGraphic(graphic);
 714         label.setText("Falcon");
 715         label.setFont(new Font("Amble Condensed", 12));
 716         label.setContentDisplay(ContentDisplay.CENTER);
 717         label.layout();
 718         
 719         // There is both a graphic & text node in this case. So we need to
 720         // compare their positions. Since this is CENTER, the graphic and
 721         // text should overlap each other and be directly centered
 722         Bounds contentBounds = getContentBounds();
 723         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 724         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 725         assertContentAreaPositionedCorrectly(contentBounds);
 726         // And they should both be centered vertically
 727         assertCenteredVertically(contentBounds, graphicBounds);
 728         assertCenteredVertically(contentBounds, textBounds);
 729         assertCenteredHorizontally(contentBounds, graphicBounds);
 730         assertCenteredHorizontally(contentBounds, textBounds);
 731     }
 732 
 733     @Test public void unmanagedGraphic_nullText_CENTER() {
 734         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 735         graphic.setManaged(false);
 736         label.setGraphic(graphic);
 737         label.setText(null);
 738         label.setContentDisplay(ContentDisplay.CENTER);
 739         label.layout();
 740         
 741         assertNull(getContentBounds());
 742     }
 743 
 744     @Test public void unmanagedGraphic_emptyText_CENTER() {
 745         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 746         graphic.setManaged(false);
 747         label.setGraphic(graphic);
 748         label.setText("");
 749         label.setContentDisplay(ContentDisplay.CENTER);
 750         label.layout();
 751         
 752         assertNull(getContentBounds());
 753     }
 754 
 755     @Test public void unmanagedGraphic_Text_CENTER() {
 756         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 757         graphic.setManaged(false);
 758         label.setGraphic(graphic);
 759         label.setText("Falcon");
 760         label.setContentDisplay(ContentDisplay.CENTER);
 761         label.layout();
 762         
 763         Bounds contentBounds = getContentBounds();
 764         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 765         assertContentAreaPositionedCorrectly(contentBounds);
 766         // Text alone makes up the content bounds, so contentBounds and
 767         // text bounds should have the same width and height
 768         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 769         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 770     }
 771 
 772     @Test public void noGraphic_nullText_CENTER() {
 773         label.setText(null);
 774         label.setContentDisplay(ContentDisplay.CENTER);
 775         label.layout();
 776         
 777         assertNull(getContentBounds());
 778     }
 779 
 780     @Test public void noGraphic_emptyText_CENTER() {
 781         label.setText("");
 782         label.setContentDisplay(ContentDisplay.CENTER);
 783         label.layout();
 784         
 785         assertNull(getContentBounds());
 786     }
 787 
 788     @Test public void noGraphic_Text_CENTER() {
 789         label.setText("Falcon");
 790         label.setContentDisplay(ContentDisplay.CENTER);
 791         label.layout();
 792         
 793         Bounds contentBounds = getContentBounds();
 794         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 795         assertContentAreaPositionedCorrectly(contentBounds);
 796         // Text alone makes up the content bounds, so contentBounds and
 797         // text bounds should have the same width and height
 798         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 799         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 800     }
 801 
 802     /** */
 803     @Test public void graphic_nullText_GRAPHIC_ONLY() {
 804         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 805         label.setGraphic(graphic);
 806         label.setText(null);
 807         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 808         label.layout();
 809         
 810         Bounds contentBounds = getContentBounds();
 811         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 812         assertContentAreaPositionedCorrectly(contentBounds);
 813         // Graphic alone makes up the content bounds, so contentBounds and
 814         // graphic bounds should have the same width and height
 815         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 816         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 817     }
 818 
 819     @Test public void graphic_emptyText_GRAPHIC_ONLY() {
 820         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 821         label.setGraphic(graphic);
 822         label.setText("");
 823         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 824         label.layout();
 825         
 826         Bounds contentBounds = getContentBounds();
 827         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 828         assertContentAreaPositionedCorrectly(contentBounds);
 829         // Graphic alone makes up the content bounds, so contentBounds and
 830         // graphic bounds should have the same width and height
 831         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 832         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 833     }
 834 
 835     @Test public void graphic_Text_GRAPHIC_ONLY() {
 836         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 837         label.setGraphic(graphic);
 838         label.setText("Falcon");
 839         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 840         label.layout();
 841         
 842         Bounds contentBounds = getContentBounds();
 843         Bounds graphicBounds = getNormalizedBounds(contentBounds, graphic);
 844         assertContentAreaPositionedCorrectly(contentBounds);
 845         // Graphic alone makes up the content bounds, so contentBounds and
 846         // graphic bounds should have the same width and height
 847         assertEquals(contentBounds.getWidth(), graphicBounds.getWidth(), 0);
 848         assertEquals(contentBounds.getHeight(), graphicBounds.getHeight(), 0);
 849     }
 850 
 851     @Test public void unmanagedGraphic_nullText_GRAPHIC_ONLY() {
 852         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 853         graphic.setManaged(false);
 854         label.setGraphic(graphic);
 855         label.setText(null);
 856         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 857         label.layout();
 858         
 859         assertNull(getContentBounds());
 860     }
 861 
 862     @Test public void unmanagedGraphic_emptyText_GRAPHIC_ONLY() {
 863         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 864         graphic.setManaged(false);
 865         label.setGraphic(graphic);
 866         label.setText("");
 867         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 868         label.layout();
 869         
 870         assertNull(getContentBounds());
 871     }
 872 
 873     @Test public void unmanagedGraphic_Text_GRAPHIC_ONLY() {
 874         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 875         graphic.setManaged(false);
 876         label.setGraphic(graphic);
 877         label.setText("Falcon");
 878         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 879         label.layout();
 880         
 881         assertNull(getContentBounds());
 882     }
 883 
 884     @Test public void noGraphic_nullText_GRAPHIC_ONLY() {
 885         label.setText(null);
 886         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 887         label.layout();
 888         
 889         assertNull(getContentBounds());
 890     }
 891 
 892     @Test public void noGraphic_emptyText_GRAPHIC_ONLY() {
 893         label.setText("");
 894         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 895         label.layout();
 896         
 897         assertNull(getContentBounds());
 898     }
 899 
 900     @Test public void noGraphic_Text_GRAPHIC_ONLY() {
 901         label.setText("Falcon");
 902         label.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
 903         label.layout();
 904         
 905         assertNull(getContentBounds());
 906     }
 907 
 908     /** */
 909     @Test public void graphic_nullText_TEXT_ONLY() {
 910         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 911         label.setGraphic(graphic);
 912         label.setText(null);
 913         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 914         label.layout();
 915         
 916         assertNull(getContentBounds());
 917     }
 918 
 919     @Test public void graphic_emptyText_TEXT_ONLY() {
 920         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 921         label.setGraphic(graphic);
 922         label.setText("");
 923         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 924         label.layout();
 925         
 926         assertNull(getContentBounds());
 927     }
 928 
 929     @Test public void graphic_Text_TEXT_ONLY() {
 930         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 931         label.setGraphic(graphic);
 932         label.setText("Falcon");
 933         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 934         label.layout();
 935         
 936         Bounds contentBounds = getContentBounds();
 937         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 938         assertContentAreaPositionedCorrectly(contentBounds);
 939         // Text alone makes up the content bounds, so contentBounds and
 940         // text bounds should have the same width and height
 941         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 942         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 943     }
 944 
 945     @Test public void unmanagedGraphic_nullText_TEXT_ONLY() {
 946         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 947         graphic.setManaged(false);
 948         label.setGraphic(graphic);
 949         label.setText(null);
 950         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 951         label.layout();
 952         
 953         assertNull(getContentBounds());
 954     }
 955 
 956     @Test public void unmanagedGraphic_emptyText_TEXT_ONLY() {
 957         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 958         graphic.setManaged(false);
 959         label.setGraphic(graphic);
 960         label.setText("");
 961         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 962         label.layout();
 963         
 964         assertNull(getContentBounds());
 965     }
 966 
 967     @Test public void unmanagedGraphic_Text_TEXT_ONLY() {
 968         Rectangle graphic = new Rectangle(GRAPHIC_WIDTH, GRAPHIC_HEIGHT);
 969         graphic.setManaged(false);
 970         label.setGraphic(graphic);
 971         label.setText("Falcon");
 972         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 973         label.layout();
 974         
 975         Bounds contentBounds = getContentBounds();
 976         Bounds textBounds = getNormalizedBounds(contentBounds, text);
 977         assertContentAreaPositionedCorrectly(contentBounds);
 978         // Text alone makes up the content bounds, so contentBounds and
 979         // text bounds should have the same width and height
 980         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
 981         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
 982     }
 983 
 984     @Test public void noGraphic_nullText_TEXT_ONLY() {
 985         label.setText(null);
 986         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 987         label.layout();
 988         
 989         assertNull(getContentBounds());
 990     }
 991 
 992     @Test public void noGraphic_emptyText_TEXT_ONLY() {
 993         label.setText("");
 994         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
 995         label.layout();
 996         
 997         assertNull(getContentBounds());
 998     }
 999 
1000     @Test public void noGraphic_Text_TEXT_ONLY() {
1001         label.setText("Falcon");
1002         label.setContentDisplay(ContentDisplay.TEXT_ONLY);
1003         label.layout();
1004         
1005         Bounds contentBounds = getContentBounds();
1006         Bounds textBounds = getNormalizedBounds(contentBounds, text);
1007         assertContentAreaPositionedCorrectly(contentBounds);
1008         // Text alone makes up the content bounds, so contentBounds and
1009         // text bounds should have the same width and height
1010         assertEquals(contentBounds.getWidth(), textBounds.getWidth(), 0);
1011         assertEquals(contentBounds.getHeight(), textBounds.getHeight(), 0);
1012     }
1013 }