modules/javafx.controls/src/main/java/javafx/scene/control/skin/LabeledSkinBase.java

Print this page




 486                 } else {
 487                     graphicWidth  = Utils.boundedSize(w, graphic.minWidth(-1), graphic.maxWidth(-1));
 488                     graphicHeight = Utils.boundedSize(h, graphic.minHeight(-1), graphic.maxHeight(-1));
 489                 }
 490                 graphic.resize(graphicWidth, graphicHeight);
 491             } else {
 492                 graphicWidth = graphic.getLayoutBounds().getWidth();
 493                 graphicHeight = graphic.getLayoutBounds().getHeight();
 494             }
 495         } else {
 496             graphic.autosize(); // We have to do this before getting metrics
 497             graphicWidth = graphic.getLayoutBounds().getWidth();
 498             graphicHeight = graphic.getLayoutBounds().getHeight();
 499         }
 500 
 501         if (ignoreText) {
 502             textWidth  = textHeight = 0;
 503             text.setText("");
 504         } else {
 505             updateDisplayedText(w, h); // Have to do this just in case it needs to be recomputed
 506             textWidth  = snapSize(Math.min(text.getLayoutBounds().getWidth(),  wrapWidth));
 507             textHeight = snapSize(Math.min(text.getLayoutBounds().getHeight(), wrapHeight));
 508         }
 509 
 510         final double gap = (ignoreText || ignoreGraphic) ? 0 : labeled.getGraphicTextGap();
 511 
 512         // Figure out the contentWidth and contentHeight. This is the width
 513         // and height of the Labeled and Graphic together, not the available
 514         // content area (which would be a different calculation).
 515         double contentWidth = Math.max(graphicWidth, textWidth);
 516         double contentHeight = Math.max(graphicHeight, textHeight);
 517         if (contentDisplay == ContentDisplay.TOP || contentDisplay == ContentDisplay.BOTTOM) {
 518             contentHeight = graphicHeight + gap + textHeight;
 519         } else if (contentDisplay == ContentDisplay.LEFT || contentDisplay == ContentDisplay.RIGHT) {
 520             contentWidth = graphicWidth + gap + textWidth;
 521         }
 522 
 523         // Now we want to compute the x/y location to place the content at.
 524 
 525         // Compute the contentX position based on hpos and the space available
 526         double contentX;
 527         if (hpos == HPos.LEFT) {


 561         // Now to position the graphic and text. At this point I know the
 562         // contentX and contentY locations (including the padding and whatnot
 563         // that was defined on the Labeled). I also know the content width and
 564         // height. So now I just need to lay out the graphic and text within
 565         // that content x/y/w/h area.
 566         if ((!ignoreGraphic || !ignoreText) && !text.isManaged()) {
 567             text.setManaged(true);
 568         }
 569 
 570         if (ignoreGraphic && ignoreText) {
 571             // There might be a text node as a child, or a graphic node as
 572             // a child. However we don't have to do anything for the graphic
 573             // node because the only way it can be a child and still have
 574             // ignoreGraphic true is if it is unmanaged. Text however might
 575             // be a child but still not matter, in which case we will just
 576             // stop managing it (although really I wish it just wasn't here
 577             // all all in that case)
 578             if (text.isManaged()) {
 579                 text.setManaged(false);
 580             }
 581             text.relocate(snapPosition(contentX), snapPosition(contentY));
 582         } else if (ignoreGraphic) {
 583             // Since I only have to position the text, it goes at the
 584             // contentX/contentY location. Note that positionNode will
 585             // adjust the text based on the text's minX/minY so no need to
 586             // worry about that here
 587             text.relocate(snapPosition(contentX), snapPosition(contentY));
 588             if (containsMnemonic) {
 589                 mnemonic_underscore.setEndX(mnemonicWidth-2.0);
 590                 mnemonic_underscore.relocate(contentX+preMnemonicWidth, contentY+mnemonicHeight-1);
 591             }
 592 
 593         } else if (ignoreText) {
 594             // there isn't text to display, so we need to position it
 595             // such that it doesn't affect the content area (although when
 596             // there is a graphic, the text isn't even in the scene)
 597             text.relocate(snapPosition(contentX), snapPosition(contentY));
 598             graphic.relocate(snapPosition(contentX), snapPosition(contentY));
 599             if (containsMnemonic) {
 600                 mnemonic_underscore.setEndX(mnemonicWidth);
 601                 mnemonic_underscore.setStrokeWidth(mnemonicHeight/10.0);
 602                 mnemonic_underscore.relocate(contentX+preMnemonicWidth, contentY+mnemonicHeight-1);
 603 
 604             }
 605         } else {
 606             // There is both text and a graphic, so I need to position them
 607             // relative to each other
 608             double graphicX = 0;
 609             double graphicY = 0;
 610             double textX = 0;
 611             double textY = 0;
 612 
 613             if (contentDisplay == ContentDisplay.TOP) {
 614                 graphicX = contentX + ((contentWidth - graphicWidth) / 2.0);
 615                 textX = contentX + ((contentWidth - textWidth) / 2.0);
 616                 // The graphic is above the text, so it is positioned at
 617                 // graphicY and the text below it.
 618                 graphicY = contentY;


 625                 textY = contentY + ((contentHeight - textHeight) / 2.0);
 626             } else if (contentDisplay == ContentDisplay.BOTTOM) {
 627                 graphicX = contentX + ((contentWidth - graphicWidth) / 2.0);
 628                 textX = contentX + ((contentWidth - textWidth) / 2.0);
 629                 // The graphic is below the text
 630                 textY = contentY;
 631                 graphicY = textY + textHeight + gap;
 632             } else if (contentDisplay == ContentDisplay.LEFT) {
 633                 // The graphic is to the left of the text, so the graphicX is
 634                 // simply the contentX and the textX is to the right of it.
 635                 graphicX = contentX;
 636                 textX = graphicX + graphicWidth + gap;
 637                 graphicY = contentY + ((contentHeight - graphicHeight) / 2.0);
 638                 textY = contentY + ((contentHeight - textHeight) / 2.0);
 639             } else if (contentDisplay == ContentDisplay.CENTER) {
 640                 graphicX = contentX + ((contentWidth - graphicWidth) / 2.0);
 641                 textX = contentX + ((contentWidth - textWidth) / 2.0);
 642                 graphicY = contentY + ((contentHeight - graphicHeight) / 2.0);
 643                 textY = contentY + ((contentHeight - textHeight) / 2.0);
 644             }
 645             text.relocate(snapPosition(textX), snapPosition(textY));
 646             if (containsMnemonic) {
 647                 mnemonic_underscore.setEndX(mnemonicWidth);
 648                 mnemonic_underscore.setStrokeWidth(mnemonicHeight/10.0);
 649                 mnemonic_underscore.relocate(snapPosition(textX+preMnemonicWidth), snapPosition(textY+mnemonicHeight-1));
 650             }
 651             graphic.relocate(snapPosition(graphicX), snapPosition(graphicY));
 652         }
 653 
 654         /**
 655          * check if the label text overflows it's bounds.
 656          * If there's an overflow, and no text clip then
 657          * we'll clip it.
 658          * If there is no overflow, and the label text has a
 659          * clip, then remove it.
 660          */
 661         if ((text != null) &&
 662                 ((text.getLayoutBounds().getHeight() > wrapHeight) ||
 663                         (text.getLayoutBounds().getWidth() > wrapWidth))) {
 664 
 665             if (textClip == null) {
 666                 textClip = new Rectangle();
 667             }
 668 
 669             if (labeled.getEffectiveNodeOrientation() == NodeOrientation.LEFT_TO_RIGHT) {
 670                 textClip.setX(text.getLayoutBounds().getMinX());
 671             } else {


 805         double s = labeled.getLineSpacing();
 806         final double textHeight = Utils.computeTextHeight(font, str, 0, s, text.getBoundsType());
 807 
 808         double h = textHeight;
 809 
 810         // Now we want to add on the graphic if necessary!
 811         if (!isIgnoreGraphic()) {
 812             final Node graphic = labeled.getGraphic();
 813             if (labeled.getContentDisplay() == ContentDisplay.TOP
 814                     || labeled.getContentDisplay() == ContentDisplay.BOTTOM) {
 815                 h = graphic.minHeight(width) + labeled.getGraphicTextGap() + textHeight;
 816             } else {
 817                 h = Math.max(textHeight, graphic.minHeight(width));
 818             }
 819         }
 820 
 821         return topInset + h + bottomInset + topLabelPadding() - bottomLabelPadding();
 822     }
 823 
 824     double topLabelPadding() {
 825         return snapSize(getSkinnable().getLabelPadding().getTop());
 826     }
 827 
 828     double bottomLabelPadding() {
 829         return snapSize(getSkinnable().getLabelPadding().getBottom());
 830     }
 831 
 832     double leftLabelPadding() {
 833         return snapSize(getSkinnable().getLabelPadding().getLeft());
 834     }
 835 
 836     double rightLabelPadding() {
 837         return snapSize(getSkinnable().getLabelPadding().getRight());
 838     }
 839 
 840 
 841     /**
 842      * Called whenever some state has changed that affects the text metrics.
 843      * Changes here will involve invalidating the display text so the next
 844      * call to updateDisplayedText computes a new value, and call requestLayout.
 845      */
 846     private void textMetricsChanged() {
 847         invalidText = true;
 848         getSkinnable().requestLayout();
 849     }
 850 
 851     /*
 852     ** The Label is a mnemonic, and it's target node
 853     ** has changed, but it's label hasn't so just
 854     ** swap them over, and tidy up.
 855     */
 856     void mnemonicTargetChanged() {
 857         if (containsMnemonic == true) {




 486                 } else {
 487                     graphicWidth  = Utils.boundedSize(w, graphic.minWidth(-1), graphic.maxWidth(-1));
 488                     graphicHeight = Utils.boundedSize(h, graphic.minHeight(-1), graphic.maxHeight(-1));
 489                 }
 490                 graphic.resize(graphicWidth, graphicHeight);
 491             } else {
 492                 graphicWidth = graphic.getLayoutBounds().getWidth();
 493                 graphicHeight = graphic.getLayoutBounds().getHeight();
 494             }
 495         } else {
 496             graphic.autosize(); // We have to do this before getting metrics
 497             graphicWidth = graphic.getLayoutBounds().getWidth();
 498             graphicHeight = graphic.getLayoutBounds().getHeight();
 499         }
 500 
 501         if (ignoreText) {
 502             textWidth  = textHeight = 0;
 503             text.setText("");
 504         } else {
 505             updateDisplayedText(w, h); // Have to do this just in case it needs to be recomputed
 506             textWidth  = snapSizeX(Math.min(text.getLayoutBounds().getWidth(),  wrapWidth));
 507             textHeight = snapSizeY(Math.min(text.getLayoutBounds().getHeight(), wrapHeight));
 508         }
 509 
 510         final double gap = (ignoreText || ignoreGraphic) ? 0 : labeled.getGraphicTextGap();
 511 
 512         // Figure out the contentWidth and contentHeight. This is the width
 513         // and height of the Labeled and Graphic together, not the available
 514         // content area (which would be a different calculation).
 515         double contentWidth = Math.max(graphicWidth, textWidth);
 516         double contentHeight = Math.max(graphicHeight, textHeight);
 517         if (contentDisplay == ContentDisplay.TOP || contentDisplay == ContentDisplay.BOTTOM) {
 518             contentHeight = graphicHeight + gap + textHeight;
 519         } else if (contentDisplay == ContentDisplay.LEFT || contentDisplay == ContentDisplay.RIGHT) {
 520             contentWidth = graphicWidth + gap + textWidth;
 521         }
 522 
 523         // Now we want to compute the x/y location to place the content at.
 524 
 525         // Compute the contentX position based on hpos and the space available
 526         double contentX;
 527         if (hpos == HPos.LEFT) {


 561         // Now to position the graphic and text. At this point I know the
 562         // contentX and contentY locations (including the padding and whatnot
 563         // that was defined on the Labeled). I also know the content width and
 564         // height. So now I just need to lay out the graphic and text within
 565         // that content x/y/w/h area.
 566         if ((!ignoreGraphic || !ignoreText) && !text.isManaged()) {
 567             text.setManaged(true);
 568         }
 569 
 570         if (ignoreGraphic && ignoreText) {
 571             // There might be a text node as a child, or a graphic node as
 572             // a child. However we don't have to do anything for the graphic
 573             // node because the only way it can be a child and still have
 574             // ignoreGraphic true is if it is unmanaged. Text however might
 575             // be a child but still not matter, in which case we will just
 576             // stop managing it (although really I wish it just wasn't here
 577             // all all in that case)
 578             if (text.isManaged()) {
 579                 text.setManaged(false);
 580             }
 581             text.relocate(snapPositionX(contentX), snapPositionY(contentY));
 582         } else if (ignoreGraphic) {
 583             // Since I only have to position the text, it goes at the
 584             // contentX/contentY location. Note that positionNode will
 585             // adjust the text based on the text's minX/minY so no need to
 586             // worry about that here
 587             text.relocate(snapPositionX(contentX), snapPositionY(contentY));
 588             if (containsMnemonic) {
 589                 mnemonic_underscore.setEndX(mnemonicWidth-2.0);
 590                 mnemonic_underscore.relocate(contentX+preMnemonicWidth, contentY+mnemonicHeight-1);
 591             }
 592 
 593         } else if (ignoreText) {
 594             // there isn't text to display, so we need to position it
 595             // such that it doesn't affect the content area (although when
 596             // there is a graphic, the text isn't even in the scene)
 597             text.relocate(snapPositionX(contentX), snapPositionY(contentY));
 598             graphic.relocate(snapPositionX(contentX), snapPositionY(contentY));
 599             if (containsMnemonic) {
 600                 mnemonic_underscore.setEndX(mnemonicWidth);
 601                 mnemonic_underscore.setStrokeWidth(mnemonicHeight/10.0);
 602                 mnemonic_underscore.relocate(contentX+preMnemonicWidth, contentY+mnemonicHeight-1);
 603 
 604             }
 605         } else {
 606             // There is both text and a graphic, so I need to position them
 607             // relative to each other
 608             double graphicX = 0;
 609             double graphicY = 0;
 610             double textX = 0;
 611             double textY = 0;
 612 
 613             if (contentDisplay == ContentDisplay.TOP) {
 614                 graphicX = contentX + ((contentWidth - graphicWidth) / 2.0);
 615                 textX = contentX + ((contentWidth - textWidth) / 2.0);
 616                 // The graphic is above the text, so it is positioned at
 617                 // graphicY and the text below it.
 618                 graphicY = contentY;


 625                 textY = contentY + ((contentHeight - textHeight) / 2.0);
 626             } else if (contentDisplay == ContentDisplay.BOTTOM) {
 627                 graphicX = contentX + ((contentWidth - graphicWidth) / 2.0);
 628                 textX = contentX + ((contentWidth - textWidth) / 2.0);
 629                 // The graphic is below the text
 630                 textY = contentY;
 631                 graphicY = textY + textHeight + gap;
 632             } else if (contentDisplay == ContentDisplay.LEFT) {
 633                 // The graphic is to the left of the text, so the graphicX is
 634                 // simply the contentX and the textX is to the right of it.
 635                 graphicX = contentX;
 636                 textX = graphicX + graphicWidth + gap;
 637                 graphicY = contentY + ((contentHeight - graphicHeight) / 2.0);
 638                 textY = contentY + ((contentHeight - textHeight) / 2.0);
 639             } else if (contentDisplay == ContentDisplay.CENTER) {
 640                 graphicX = contentX + ((contentWidth - graphicWidth) / 2.0);
 641                 textX = contentX + ((contentWidth - textWidth) / 2.0);
 642                 graphicY = contentY + ((contentHeight - graphicHeight) / 2.0);
 643                 textY = contentY + ((contentHeight - textHeight) / 2.0);
 644             }
 645             text.relocate(snapPositionX(textX), snapPositionY(textY));
 646             if (containsMnemonic) {
 647                 mnemonic_underscore.setEndX(mnemonicWidth);
 648                 mnemonic_underscore.setStrokeWidth(mnemonicHeight/10.0);
 649                 mnemonic_underscore.relocate(snapPositionX(textX+preMnemonicWidth), snapPositionY(textY+mnemonicHeight-1));
 650             }
 651             graphic.relocate(snapPositionX(graphicX), snapPositionY(graphicY));
 652         }
 653 
 654         /**
 655          * check if the label text overflows it's bounds.
 656          * If there's an overflow, and no text clip then
 657          * we'll clip it.
 658          * If there is no overflow, and the label text has a
 659          * clip, then remove it.
 660          */
 661         if ((text != null) &&
 662                 ((text.getLayoutBounds().getHeight() > wrapHeight) ||
 663                         (text.getLayoutBounds().getWidth() > wrapWidth))) {
 664 
 665             if (textClip == null) {
 666                 textClip = new Rectangle();
 667             }
 668 
 669             if (labeled.getEffectiveNodeOrientation() == NodeOrientation.LEFT_TO_RIGHT) {
 670                 textClip.setX(text.getLayoutBounds().getMinX());
 671             } else {


 805         double s = labeled.getLineSpacing();
 806         final double textHeight = Utils.computeTextHeight(font, str, 0, s, text.getBoundsType());
 807 
 808         double h = textHeight;
 809 
 810         // Now we want to add on the graphic if necessary!
 811         if (!isIgnoreGraphic()) {
 812             final Node graphic = labeled.getGraphic();
 813             if (labeled.getContentDisplay() == ContentDisplay.TOP
 814                     || labeled.getContentDisplay() == ContentDisplay.BOTTOM) {
 815                 h = graphic.minHeight(width) + labeled.getGraphicTextGap() + textHeight;
 816             } else {
 817                 h = Math.max(textHeight, graphic.minHeight(width));
 818             }
 819         }
 820 
 821         return topInset + h + bottomInset + topLabelPadding() - bottomLabelPadding();
 822     }
 823 
 824     double topLabelPadding() {
 825         return snapSizeY(getSkinnable().getLabelPadding().getTop());
 826     }
 827 
 828     double bottomLabelPadding() {
 829         return snapSizeY(getSkinnable().getLabelPadding().getBottom());
 830     }
 831 
 832     double leftLabelPadding() {
 833         return snapSizeX(getSkinnable().getLabelPadding().getLeft());
 834     }
 835 
 836     double rightLabelPadding() {
 837         return snapSizeX(getSkinnable().getLabelPadding().getRight());
 838     }
 839 
 840 
 841     /**
 842      * Called whenever some state has changed that affects the text metrics.
 843      * Changes here will involve invalidating the display text so the next
 844      * call to updateDisplayedText computes a new value, and call requestLayout.
 845      */
 846     private void textMetricsChanged() {
 847         invalidText = true;
 848         getSkinnable().requestLayout();
 849     }
 850 
 851     /*
 852     ** The Label is a mnemonic, and it's target node
 853     ** has changed, but it's label hasn't so just
 854     ** swap them over, and tidy up.
 855     */
 856     void mnemonicTargetChanged() {
 857         if (containsMnemonic == true) {