modules/graphics/src/main/java/javafx/scene/layout/VBox.java

Print this page




 370                         break;
 371                     }
 372                 }
 373             }
 374             biasDirty = false;
 375         }
 376         return bias;
 377     }
 378 
 379     @Override protected double computeMinWidth(double height) {
 380         Insets insets = getInsets();
 381         List<Node>managed = getManagedChildren();
 382         double contentWidth = 0;
 383         if (height != -1 && getContentBias() != null) {
 384             double prefHeights[][] = getAreaHeights(managed, -1, false);
 385             adjustAreaHeights(managed, prefHeights, height, -1);
 386             contentWidth = computeMaxMinAreaWidth(managed, marginAccessor, prefHeights[0], false);
 387         } else {
 388             contentWidth = computeMaxMinAreaWidth(managed, marginAccessor);
 389         }
 390         return snapSpace(insets.getLeft()) + contentWidth + snapSpace(insets.getRight());
 391     }
 392 
 393     @Override protected double computeMinHeight(double width) {
 394         Insets insets = getInsets();
 395         return snapSpace(insets.getTop()) +
 396                computeContentHeight(getManagedChildren(), width, true) +
 397                snapSpace(insets.getBottom());
 398     }
 399 
 400     @Override protected double computePrefWidth(double height) {
 401         Insets insets = getInsets();
 402         List<Node>managed = getManagedChildren();
 403         double contentWidth = 0;
 404         if (height != -1 && getContentBias() != null) {
 405             double prefHeights[][] = getAreaHeights(managed, -1, false);
 406             adjustAreaHeights(managed, prefHeights, height, -1);
 407             contentWidth = computeMaxPrefAreaWidth(managed, marginAccessor, prefHeights[0], false);
 408         } else {
 409             contentWidth = computeMaxPrefAreaWidth(managed, marginAccessor);
 410         }
 411         return snapSpace(insets.getLeft()) + contentWidth + snapSpace(insets.getRight());
 412     }
 413 
 414     @Override protected double computePrefHeight(double width) {
 415         Insets insets = getInsets();
 416         double d = snapSpace(insets.getTop()) +
 417                computeContentHeight(getManagedChildren(), width, false) +
 418                snapSpace(insets.getBottom());
 419         return d;
 420     }
 421 
 422 
 423     private double[][] getAreaHeights(List<Node>managed, double width, boolean minimum) {
 424         // width could be -1
 425         double[][] temp = getTempArray(managed.size());
 426         final double insideWidth = width == -1? -1 : width -
 427                                      snapSpace(getInsets().getLeft()) - snapSpace(getInsets().getRight());
 428         final boolean isFillWidth = isFillWidth();
 429         for (int i = 0, size = managed.size(); i < size; i++) {
 430             Node child = managed.get(i);
 431             Insets margin = getMargin(child);
 432             if (minimum) {
 433                 if (insideWidth != -1 && isFillWidth) {
 434                     temp[0][i] = computeChildMinAreaHeight(child, -1, margin, insideWidth);
 435                 } else {
 436                     temp[0][i] = computeChildMinAreaHeight(child, -1, margin, -1);
 437                 }
 438             } else {
 439                 if (insideWidth != -1 && isFillWidth) {
 440                     temp[0][i] = computeChildPrefAreaHeight(child, -1, margin, insideWidth);
 441                 } else {
 442                     temp[0][i] = computeChildPrefAreaHeight(child, -1, margin, -1);
 443                 }
 444             }
 445         }
 446         return temp;
 447     }
 448 
 449     private double adjustAreaHeights(List<Node>managed, double areaHeights[][], double height, double width) {
 450         Insets insets = getInsets();
 451         double left = snapSpace(insets.getLeft());
 452         double right = snapSpace(insets.getRight());
 453 
 454         double contentHeight = sum(areaHeights[0], managed.size()) + (managed.size()-1)*snapSpace(getSpacing());
 455         double extraHeight = height -
 456                 snapSpace(insets.getTop()) - snapSpace(insets.getBottom()) - contentHeight;
 457 
 458         if (extraHeight != 0) {
 459             final double refWidth = isFillWidth()&& width != -1? width - left - right : -1;
 460             double remaining = growOrShrinkAreaHeights(managed, areaHeights, Priority.ALWAYS, extraHeight, refWidth);
 461             remaining = growOrShrinkAreaHeights(managed, areaHeights, Priority.SOMETIMES, remaining, refWidth);
 462             contentHeight += (extraHeight - remaining);
 463         }
 464 
 465         return contentHeight;
 466     }
 467 
 468     private double growOrShrinkAreaHeights(List<Node>managed, double areaHeights[][], Priority priority, double extraHeight, double width) {
 469         final boolean shrinking = extraHeight < 0;
 470         int adjustingNumber = 0;
 471 
 472         double[] usedHeights = areaHeights[0];
 473         double[] temp = areaHeights[1];
 474 
 475         if (shrinking) {
 476             adjustingNumber = managed.size();
 477             for (int i = 0, size = managed.size(); i < size; i++) {
 478                 final Node child = managed.get(i);
 479                 temp[i] = computeChildMinAreaHeight(child, -1, getMargin(child), width);
 480             }
 481         } else {
 482             for (int i = 0, size = managed.size(); i < size; i++) {
 483             final Node child = managed.get(i);
 484             if (getVgrow(child) == priority) {
 485                 temp[i] = computeChildMaxAreaHeight(child, -1, getMargin(child), width);
 486                 adjustingNumber++;
 487             } else {
 488                 temp[i] = -1;
 489             }
 490         }
 491         }
 492 
 493         double available = extraHeight; // will be negative in shrinking case
 494         outer: while (Math.abs(available) > 1 && adjustingNumber > 0) {
 495             final double portion = snapPortion(available / adjustingNumber); // negative in shrinking case
 496             for (int i = 0, size = managed.size(); i < size; i++) {
 497                 if (temp[i] == -1) {
 498                     continue;
 499                 }
 500                 final double limit = temp[i] - usedHeights[i]; // negative in shrinking case
 501                 final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
 502                 usedHeights[i] += change;
 503                 available -= change;
 504                 if (Math.abs(available) < 1) {
 505                     break outer;
 506                 }
 507                 if (Math.abs(change) < Math.abs(portion)) {
 508                     temp[i] = -1;
 509                     adjustingNumber--;
 510                 }
 511             }
 512         }
 513 
 514         return available; // might be negative in shrinking case
 515     }
 516 
 517     private double computeContentHeight(List<Node> managedChildren, double width, boolean minimum) {
 518         return sum(getAreaHeights(managedChildren, width, minimum)[0], managedChildren.size())
 519                 + (managedChildren.size()-1)*snapSpace(getSpacing());
 520     }
 521 
 522     private static double sum(double[] array, int size) {
 523         int i = 0;
 524         double res = 0;
 525         while (i != size) {
 526             res += array[i++];
 527         }
 528         return res;
 529     }
 530 
 531     @Override public void requestLayout() {
 532         if (performingLayout) {
 533             return;
 534         }
 535         biasDirty = true;
 536         bias = null;
 537         super.requestLayout();
 538     }
 539 
 540     @Override protected void layoutChildren() {
 541         performingLayout = true;
 542         List<Node> managed = getManagedChildren();
 543         Insets insets = getInsets();
 544         double width = getWidth();
 545         double height = getHeight();
 546         double top = snapSpace(insets.getTop());
 547         double left = snapSpace(insets.getLeft());
 548         double bottom = snapSpace(insets.getBottom());
 549         double right = snapSpace(insets.getRight());
 550         double space = snapSpace(getSpacing());
 551         HPos hpos = getAlignmentInternal().getHpos();
 552         VPos vpos = getAlignmentInternal().getVpos();
 553         boolean isFillWidth = isFillWidth();
 554 
 555         double[][] actualAreaHeights = getAreaHeights(managed, width, false);
 556         double contentWidth = width - left - right;
 557         double contentHeight = adjustAreaHeights(managed, actualAreaHeights, height, width);
 558 
 559         double x = left;
 560         double y = top + computeYOffset(height - top - bottom, contentHeight, vpos);
 561 
 562         for (int i = 0, size = managed.size(); i < size; i++) {
 563             Node child = managed.get(i);
 564             layoutInArea(child, x, y, contentWidth, actualAreaHeights[0][i],
 565                        /* baseline shouldn't matter */actualAreaHeights[0][i],
 566                        getMargin(child), isFillWidth, true,
 567                        hpos, vpos);
 568             y += actualAreaHeights[0][i] + space;
 569         }
 570         performingLayout = false;




 370                         break;
 371                     }
 372                 }
 373             }
 374             biasDirty = false;
 375         }
 376         return bias;
 377     }
 378 
 379     @Override protected double computeMinWidth(double height) {
 380         Insets insets = getInsets();
 381         List<Node>managed = getManagedChildren();
 382         double contentWidth = 0;
 383         if (height != -1 && getContentBias() != null) {
 384             double prefHeights[][] = getAreaHeights(managed, -1, false);
 385             adjustAreaHeights(managed, prefHeights, height, -1);
 386             contentWidth = computeMaxMinAreaWidth(managed, marginAccessor, prefHeights[0], false);
 387         } else {
 388             contentWidth = computeMaxMinAreaWidth(managed, marginAccessor);
 389         }
 390         return snapSpaceX(insets.getLeft()) + contentWidth + snapSpaceX(insets.getRight());
 391     }
 392 
 393     @Override protected double computeMinHeight(double width) {
 394         Insets insets = getInsets();
 395         return snapSpaceY(insets.getTop()) +
 396                computeContentHeight(getManagedChildren(), width, true) +
 397                snapSpaceY(insets.getBottom());
 398     }
 399 
 400     @Override protected double computePrefWidth(double height) {
 401         Insets insets = getInsets();
 402         List<Node>managed = getManagedChildren();
 403         double contentWidth = 0;
 404         if (height != -1 && getContentBias() != null) {
 405             double prefHeights[][] = getAreaHeights(managed, -1, false);
 406             adjustAreaHeights(managed, prefHeights, height, -1);
 407             contentWidth = computeMaxPrefAreaWidth(managed, marginAccessor, prefHeights[0], false);
 408         } else {
 409             contentWidth = computeMaxPrefAreaWidth(managed, marginAccessor);
 410         }
 411         return snapSpaceX(insets.getLeft()) + contentWidth + snapSpaceX(insets.getRight());
 412     }
 413 
 414     @Override protected double computePrefHeight(double width) {
 415         Insets insets = getInsets();
 416         double d = snapSpaceY(insets.getTop()) +
 417                computeContentHeight(getManagedChildren(), width, false) +
 418                snapSpaceY(insets.getBottom());
 419         return d;
 420     }
 421 
 422 
 423     private double[][] getAreaHeights(List<Node>managed, double width, boolean minimum) {
 424         // width could be -1
 425         double[][] temp = getTempArray(managed.size());
 426         final double insideWidth = width == -1? -1 : width -
 427                                      snapSpaceX(getInsets().getLeft()) - snapSpaceX(getInsets().getRight());
 428         final boolean isFillWidth = isFillWidth();
 429         for (int i = 0, size = managed.size(); i < size; i++) {
 430             Node child = managed.get(i);
 431             Insets margin = getMargin(child);
 432             if (minimum) {
 433                 if (insideWidth != -1 && isFillWidth) {
 434                     temp[0][i] = computeChildMinAreaHeight(child, -1, margin, insideWidth);
 435                 } else {
 436                     temp[0][i] = computeChildMinAreaHeight(child, -1, margin, -1);
 437                 }
 438             } else {
 439                 if (insideWidth != -1 && isFillWidth) {
 440                     temp[0][i] = computeChildPrefAreaHeight(child, -1, margin, insideWidth);
 441                 } else {
 442                     temp[0][i] = computeChildPrefAreaHeight(child, -1, margin, -1);
 443                 }
 444             }
 445         }
 446         return temp;
 447     }
 448 
 449     private double adjustAreaHeights(List<Node>managed, double areaHeights[][], double height, double width) {
 450         Insets insets = getInsets();
 451         double left = snapSpaceX(insets.getLeft());
 452         double right = snapSpaceX(insets.getRight());
 453 
 454         double contentHeight = sum(areaHeights[0], managed.size()) + (managed.size()-1)*snapSpaceY(getSpacing());
 455         double extraHeight = height -
 456                 snapSpaceY(insets.getTop()) - snapSpaceY(insets.getBottom()) - contentHeight;
 457 
 458         if (extraHeight != 0) {
 459             final double refWidth = isFillWidth()&& width != -1? width - left - right : -1;
 460             double remaining = growOrShrinkAreaHeights(managed, areaHeights, Priority.ALWAYS, extraHeight, refWidth);
 461             remaining = growOrShrinkAreaHeights(managed, areaHeights, Priority.SOMETIMES, remaining, refWidth);
 462             contentHeight += (extraHeight - remaining);
 463         }
 464 
 465         return contentHeight;
 466     }
 467 
 468     private double growOrShrinkAreaHeights(List<Node>managed, double areaHeights[][], Priority priority, double extraHeight, double width) {
 469         final boolean shrinking = extraHeight < 0;
 470         int adjustingNumber = 0;
 471 
 472         double[] usedHeights = areaHeights[0];
 473         double[] temp = areaHeights[1];
 474 
 475         if (shrinking) {
 476             adjustingNumber = managed.size();
 477             for (int i = 0, size = managed.size(); i < size; i++) {
 478                 final Node child = managed.get(i);
 479                 temp[i] = computeChildMinAreaHeight(child, -1, getMargin(child), width);
 480             }
 481         } else {
 482             for (int i = 0, size = managed.size(); i < size; i++) {
 483             final Node child = managed.get(i);
 484             if (getVgrow(child) == priority) {
 485                 temp[i] = computeChildMaxAreaHeight(child, -1, getMargin(child), width);
 486                 adjustingNumber++;
 487             } else {
 488                 temp[i] = -1;
 489             }
 490         }
 491         }
 492 
 493         double available = extraHeight; // will be negative in shrinking case
 494         outer: while (Math.abs(available) > 1 && adjustingNumber > 0) {
 495             final double portion = snapPortionY(available / adjustingNumber); // negative in shrinking case
 496             for (int i = 0, size = managed.size(); i < size; i++) {
 497                 if (temp[i] == -1) {
 498                     continue;
 499                 }
 500                 final double limit = temp[i] - usedHeights[i]; // negative in shrinking case
 501                 final double change = Math.abs(limit) <= Math.abs(portion)? limit : portion;
 502                 usedHeights[i] += change;
 503                 available -= change;
 504                 if (Math.abs(available) < 1) {
 505                     break outer;
 506                 }
 507                 if (Math.abs(change) < Math.abs(portion)) {
 508                     temp[i] = -1;
 509                     adjustingNumber--;
 510                 }
 511             }
 512         }
 513 
 514         return available; // might be negative in shrinking case
 515     }
 516 
 517     private double computeContentHeight(List<Node> managedChildren, double width, boolean minimum) {
 518         return sum(getAreaHeights(managedChildren, width, minimum)[0], managedChildren.size())
 519                 + (managedChildren.size()-1)*snapSpaceY(getSpacing());
 520     }
 521 
 522     private static double sum(double[] array, int size) {
 523         int i = 0;
 524         double res = 0;
 525         while (i != size) {
 526             res += array[i++];
 527         }
 528         return res;
 529     }
 530 
 531     @Override public void requestLayout() {
 532         if (performingLayout) {
 533             return;
 534         }
 535         biasDirty = true;
 536         bias = null;
 537         super.requestLayout();
 538     }
 539 
 540     @Override protected void layoutChildren() {
 541         performingLayout = true;
 542         List<Node> managed = getManagedChildren();
 543         Insets insets = getInsets();
 544         double width = getWidth();
 545         double height = getHeight();
 546         double top = snapSpaceY(insets.getTop());
 547         double left = snapSpaceX(insets.getLeft());
 548         double bottom = snapSpaceY(insets.getBottom());
 549         double right = snapSpaceX(insets.getRight());
 550         double space = snapSpaceY(getSpacing());
 551         HPos hpos = getAlignmentInternal().getHpos();
 552         VPos vpos = getAlignmentInternal().getVpos();
 553         boolean isFillWidth = isFillWidth();
 554 
 555         double[][] actualAreaHeights = getAreaHeights(managed, width, false);
 556         double contentWidth = width - left - right;
 557         double contentHeight = adjustAreaHeights(managed, actualAreaHeights, height, width);
 558 
 559         double x = left;
 560         double y = top + computeYOffset(height - top - bottom, contentHeight, vpos);
 561 
 562         for (int i = 0, size = managed.size(); i < size; i++) {
 563             Node child = managed.get(i);
 564             layoutInArea(child, x, y, contentWidth, actualAreaHeights[0][i],
 565                        /* baseline shouldn't matter */actualAreaHeights[0][i],
 566                        getMargin(child), isFillWidth, true,
 567                        hpos, vpos);
 568             y += actualAreaHeights[0][i] + space;
 569         }
 570         performingLayout = false;