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

Print this page




 241         control.getItems().addListener((ListChangeListener<Node>) c -> {
 242             while (c.next()) {
 243                 for (Node n: c.getRemoved()) {
 244                     box.getChildren().remove(n);
 245                 }
 246                 box.getChildren().addAll(c.getAddedSubList());
 247             }
 248             needsUpdate = true;
 249             getSkinnable().requestLayout();
 250         });
 251     }
 252 
 253 
 254 
 255     /***************************************************************************
 256      *                                                                         *
 257      * Properties                                                              *
 258      *                                                                         *
 259      **************************************************************************/
 260 








 261     // --- spacing
 262     private DoubleProperty spacing;
 263     private final void setSpacing(double value) {
 264         spacingProperty().set(snapSpace(value));
 265     }
 266 
 267     private final double getSpacing() {
 268         return spacing == null ? 0.0 : snapSpace(spacing.get());
 269     }
 270 
 271     private final DoubleProperty spacingProperty() {
 272         if (spacing == null) {
 273             spacing = new StyleableDoubleProperty() {
 274 
 275                 @Override
 276                 protected void invalidated() {
 277                     final double value = get();
 278                     if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 279                         ((VBox)box).setSpacing(value);
 280                     } else {
 281                         ((HBox)box).setSpacing(value);
 282                     }
 283                 }
 284 
 285                 @Override
 286                 public Object getBean() {
 287                     return ToolBarSkin.this;
 288                 }


 349     /***************************************************************************
 350      *                                                                         *
 351      * Public API                                                              *
 352      *                                                                         *
 353      **************************************************************************/
 354 
 355     /** {@inheritDoc} */
 356     @Override public void dispose() {
 357         super.dispose();
 358 
 359         if (behavior != null) {
 360             behavior.dispose();
 361         }
 362     }
 363 
 364     /** {@inheritDoc} */
 365     @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
 366         final ToolBar toolbar = getSkinnable();
 367         return toolbar.getOrientation() == Orientation.VERTICAL ?
 368             computePrefWidth(-1, topInset, rightInset, bottomInset, leftInset) :
 369             snapSize(overflowMenu.prefWidth(-1)) + leftInset + rightInset;
 370     }
 371 
 372     /** {@inheritDoc} */
 373     @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
 374         final ToolBar toolbar = getSkinnable();
 375         return toolbar.getOrientation() == Orientation.VERTICAL?
 376             snapSize(overflowMenu.prefHeight(-1)) + topInset + bottomInset :
 377             computePrefHeight(-1, topInset, rightInset, bottomInset, leftInset);
 378     }
 379 
 380     /** {@inheritDoc} */
 381     @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
 382         double prefWidth = 0;
 383         final ToolBar toolbar = getSkinnable();
 384 
 385         if (toolbar.getOrientation() == Orientation.HORIZONTAL) {
 386             for (Node node : toolbar.getItems()) {
 387                 if (!node.isManaged()) continue;
 388                 prefWidth += snapSize(node.prefWidth(-1)) + getSpacing();
 389             }
 390             prefWidth -= getSpacing();
 391         } else {
 392             for (Node node : toolbar.getItems()) {
 393                 if (!node.isManaged()) continue;
 394                 prefWidth = Math.max(prefWidth, snapSize(node.prefWidth(-1)));
 395             }
 396             if (toolbar.getItems().size() > 0) {
 397                 savedPrefWidth = prefWidth;
 398             } else {
 399                 prefWidth = savedPrefWidth;
 400             }
 401         }
 402         return leftInset + prefWidth + rightInset;
 403     }
 404 
 405     /** {@inheritDoc} */
 406     @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
 407         double prefHeight = 0;
 408         final ToolBar toolbar = getSkinnable();
 409 
 410         if(toolbar.getOrientation() == Orientation.VERTICAL) {
 411             for (Node node: toolbar.getItems()) {
 412                 if (!node.isManaged()) continue;
 413                 prefHeight += snapSize(node.prefHeight(-1)) + getSpacing();
 414             }
 415             prefHeight -= getSpacing();
 416         } else {
 417             for (Node node : toolbar.getItems()) {
 418                 if (!node.isManaged()) continue;
 419                 prefHeight = Math.max(prefHeight, snapSize(node.prefHeight(-1)));
 420             }
 421             if (toolbar.getItems().size() > 0) {
 422                 savedPrefHeight = prefHeight;
 423             } else {
 424                 prefHeight = savedPrefHeight;
 425             }
 426         }
 427         return topInset + prefHeight + bottomInset;
 428     }
 429 
 430     /** {@inheritDoc} */
 431     @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
 432         return getSkinnable().getOrientation() == Orientation.VERTICAL ?
 433                 snapSize(getSkinnable().prefWidth(-1)) : Double.MAX_VALUE;
 434     }
 435 
 436     /** {@inheritDoc} */
 437     @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
 438         return getSkinnable().getOrientation() == Orientation.VERTICAL ?
 439                 Double.MAX_VALUE : snapSize(getSkinnable().prefHeight(-1));
 440     }
 441 
 442     /** {@inheritDoc} */
 443     @Override protected void layoutChildren(final double x,final double y,
 444             final double w, final double h) {
 445 //        super.layoutChildren();
 446         final ToolBar toolbar = getSkinnable();
 447 
 448         if (toolbar.getOrientation() == Orientation.VERTICAL) {
 449             if (snapSize(toolbar.getHeight()) != previousHeight || needsUpdate) {
 450                 ((VBox)box).setSpacing(getSpacing());
 451                 ((VBox)box).setAlignment(getBoxAlignment());
 452                 previousHeight = snapSize(toolbar.getHeight());
 453                 addNodesToToolBar();
 454             }
 455         } else {
 456             if (snapSize(toolbar.getWidth()) != previousWidth || needsUpdate) {
 457                 ((HBox)box).setSpacing(getSpacing());
 458                 ((HBox)box).setAlignment(getBoxAlignment());
 459                 previousWidth = snapSize(toolbar.getWidth());
 460                 addNodesToToolBar();
 461             }
 462         }
 463         needsUpdate = false;
 464 
 465         double toolbarWidth = w;
 466         double toolbarHeight = h;
 467 
 468         if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 469             toolbarHeight -= (overflow ? snapSize(overflowMenu.prefHeight(-1)) : 0);
 470         } else {
 471             toolbarWidth -= (overflow ? snapSize(overflowMenu.prefWidth(-1)) : 0);
 472         }
 473 
 474         box.resize(toolbarWidth, toolbarHeight);
 475         positionInArea(box, x, y,
 476                 toolbarWidth, toolbarHeight, /*baseline ignored*/0, HPos.CENTER, VPos.CENTER);
 477 
 478         // If popup menu is not null show the overflowControl
 479         if (overflow) {
 480             double overflowMenuWidth = snapSize(overflowMenu.prefWidth(-1));
 481             double overflowMenuHeight = snapSize(overflowMenu.prefHeight(-1));
 482             double overflowX = x;
 483             double overflowY = x;
 484             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 485                 // This is to prevent the overflow menu from moving when there
 486                 // are no items in the toolbar.
 487                 if (toolbarWidth == 0) {
 488                     toolbarWidth = savedPrefWidth;
 489                 }
 490                 HPos pos = ((VBox)box).getAlignment().getHpos();
 491                 if (HPos.LEFT.equals(pos)) {
 492                     overflowX = x + Math.abs((toolbarWidth - overflowMenuWidth)/2);
 493                 } else if (HPos.RIGHT.equals(pos)) {
 494                     overflowX = (snapSize(toolbar.getWidth()) - snappedRightInset() - toolbarWidth) +
 495                         Math.abs((toolbarWidth - overflowMenuWidth)/2);
 496                 } else {
 497                     overflowX = x +
 498                         Math.abs((snapSize(toolbar.getWidth()) - (x) +
 499                         snappedRightInset() - overflowMenuWidth)/2);
 500                 }
 501                 overflowY = snapSize(toolbar.getHeight()) - overflowMenuHeight - y;
 502             } else {
 503                 // This is to prevent the overflow menu from moving when there
 504                 // are no items in the toolbar.
 505                 if (toolbarHeight == 0) {
 506                     toolbarHeight = savedPrefHeight;
 507                 }
 508                 VPos pos = ((HBox)box).getAlignment().getVpos();
 509                 if (VPos.TOP.equals(pos)) {
 510                     overflowY = y +
 511                         Math.abs((toolbarHeight - overflowMenuHeight)/2);
 512                 } else if (VPos.BOTTOM.equals(pos)) {
 513                     overflowY = (snapSize(toolbar.getHeight()) - snappedBottomInset() - toolbarHeight) +
 514                         Math.abs((toolbarHeight - overflowMenuHeight)/2);
 515                 } else {
 516                     overflowY = y + Math.abs((toolbarHeight - overflowMenuHeight)/2);
 517                 }
 518                overflowX = snapSize(toolbar.getWidth()) - overflowMenuWidth - snappedRightInset();
 519             }
 520             overflowMenu.resize(overflowMenuWidth, overflowMenuHeight);
 521             positionInArea(overflowMenu, overflowX, overflowY, overflowMenuWidth, overflowMenuHeight, /*baseline ignored*/0,
 522                     HPos.CENTER, VPos.CENTER);
 523         }
 524     }
 525 
 526 
 527 
 528     /***************************************************************************
 529      *                                                                         *
 530      * Private implementation                                                  *
 531      *                                                                         *
 532      **************************************************************************/
 533 
 534     private void initialize() {
 535         if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 536             box = new VBox();
 537         } else {
 538             box = new HBox();


 542         overflowMenu = new ToolBarOverflowMenu(overflowMenuItems);
 543         overflowMenu.setVisible(false);
 544         overflowMenu.setManaged(false);
 545 
 546         getChildren().clear();
 547         getChildren().add(box);
 548         getChildren().add(overflowMenu);
 549 
 550         previousWidth = 0;
 551         previousHeight = 0;
 552         savedPrefWidth = 0;
 553         savedPrefHeight = 0;
 554         needsUpdate = true;
 555         getSkinnable().requestLayout();
 556     }
 557 
 558     private void addNodesToToolBar() {
 559         final ToolBar toolbar = getSkinnable();
 560         double length = 0;
 561         if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 562             length = snapSize(toolbar.getHeight()) - snappedTopInset() - snappedBottomInset() + getSpacing();
 563         } else {
 564             length = snapSize(toolbar.getWidth()) - snappedLeftInset() - snappedRightInset() + getSpacing();
 565         }
 566 
 567         // Is there overflow ?
 568         double x = 0;
 569         boolean hasOverflow = false;
 570         for (Node node : getSkinnable().getItems()) {
 571             if (!node.isManaged()) continue;
 572 
 573             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 574                 x += snapSize(node.prefHeight(-1)) + getSpacing();
 575             } else {
 576                 x += snapSize(node.prefWidth(-1)) + getSpacing();
 577             }
 578             if (x > length) {
 579                 hasOverflow = true;
 580                 break;
 581             }
 582         }
 583 
 584         if (hasOverflow) {
 585             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 586                 length -= snapSize(overflowMenu.prefHeight(-1));
 587             } else {
 588                 length -= snapSize(overflowMenu.prefWidth(-1));
 589             }
 590             length -= getSpacing();
 591         }
 592 
 593         // Determine which node goes to the toolbar and which goes to the overflow.
 594         x = 0;
 595         overflowMenuItems.clear();
 596         box.getChildren().clear();
 597         for (Node node : getSkinnable().getItems()) {
 598             node.getStyleClass().remove("menu-item");
 599             node.getStyleClass().remove("custom-menu-item");
 600 
 601             if (node.isManaged()) {
 602                 if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 603                     x += snapSize(node.prefHeight(-1)) + getSpacing();
 604                 } else {
 605                     x += snapSize(node.prefWidth(-1)) + getSpacing();
 606                 }
 607             }
 608 
 609             if (x <= length) {
 610                 box.getChildren().add(node);
 611             } else {
 612                 if (node.isFocused()) {
 613                     if (!box.getChildren().isEmpty()) {
 614                         Node last = engine.selectLast();
 615                         if (last != null) {
 616                             last.requestFocus();
 617                         }
 618                     } else {
 619                         overflowMenu.requestFocus();
 620                     }
 621                 }
 622                 if (node instanceof Separator) {
 623                     overflowMenuItems.add(new SeparatorMenuItem());
 624                 } else {
 625                     CustomMenuItem customMenuItem = new CustomMenuItem(node);




 241         control.getItems().addListener((ListChangeListener<Node>) c -> {
 242             while (c.next()) {
 243                 for (Node n: c.getRemoved()) {
 244                     box.getChildren().remove(n);
 245                 }
 246                 box.getChildren().addAll(c.getAddedSubList());
 247             }
 248             needsUpdate = true;
 249             getSkinnable().requestLayout();
 250         });
 251     }
 252 
 253 
 254 
 255     /***************************************************************************
 256      *                                                                         *
 257      * Properties                                                              *
 258      *                                                                         *
 259      **************************************************************************/
 260 
 261     private double snapSpacing(double value) {
 262         if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 263             return snapSpaceY(value);
 264         } else {
 265             return snapSpaceX(value);
 266         }
 267     }
 268 
 269     // --- spacing
 270     private DoubleProperty spacing;
 271     private final void setSpacing(double value) {
 272         spacingProperty().set(snapSpacing(value));
 273     }
 274 
 275     private final double getSpacing() {
 276         return spacing == null ? 0.0 : snapSpacing(spacing.get());
 277     }
 278 
 279     private final DoubleProperty spacingProperty() {
 280         if (spacing == null) {
 281             spacing = new StyleableDoubleProperty() {
 282 
 283                 @Override
 284                 protected void invalidated() {
 285                     final double value = get();
 286                     if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 287                         ((VBox)box).setSpacing(value);
 288                     } else {
 289                         ((HBox)box).setSpacing(value);
 290                     }
 291                 }
 292 
 293                 @Override
 294                 public Object getBean() {
 295                     return ToolBarSkin.this;
 296                 }


 357     /***************************************************************************
 358      *                                                                         *
 359      * Public API                                                              *
 360      *                                                                         *
 361      **************************************************************************/
 362 
 363     /** {@inheritDoc} */
 364     @Override public void dispose() {
 365         super.dispose();
 366 
 367         if (behavior != null) {
 368             behavior.dispose();
 369         }
 370     }
 371 
 372     /** {@inheritDoc} */
 373     @Override protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
 374         final ToolBar toolbar = getSkinnable();
 375         return toolbar.getOrientation() == Orientation.VERTICAL ?
 376             computePrefWidth(-1, topInset, rightInset, bottomInset, leftInset) :
 377             snapSizeX(overflowMenu.prefWidth(-1)) + leftInset + rightInset;
 378     }
 379 
 380     /** {@inheritDoc} */
 381     @Override protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
 382         final ToolBar toolbar = getSkinnable();
 383         return toolbar.getOrientation() == Orientation.VERTICAL?
 384             snapSizeY(overflowMenu.prefHeight(-1)) + topInset + bottomInset :
 385             computePrefHeight(-1, topInset, rightInset, bottomInset, leftInset);
 386     }
 387 
 388     /** {@inheritDoc} */
 389     @Override protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
 390         double prefWidth = 0;
 391         final ToolBar toolbar = getSkinnable();
 392 
 393         if (toolbar.getOrientation() == Orientation.HORIZONTAL) {
 394             for (Node node : toolbar.getItems()) {
 395                 if (!node.isManaged()) continue;
 396                 prefWidth += snapSizeX(node.prefWidth(-1)) + getSpacing();
 397             }
 398             prefWidth -= getSpacing();
 399         } else {
 400             for (Node node : toolbar.getItems()) {
 401                 if (!node.isManaged()) continue;
 402                 prefWidth = Math.max(prefWidth, snapSizeX(node.prefWidth(-1)));
 403             }
 404             if (toolbar.getItems().size() > 0) {
 405                 savedPrefWidth = prefWidth;
 406             } else {
 407                 prefWidth = savedPrefWidth;
 408             }
 409         }
 410         return leftInset + prefWidth + rightInset;
 411     }
 412 
 413     /** {@inheritDoc} */
 414     @Override protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
 415         double prefHeight = 0;
 416         final ToolBar toolbar = getSkinnable();
 417 
 418         if(toolbar.getOrientation() == Orientation.VERTICAL) {
 419             for (Node node: toolbar.getItems()) {
 420                 if (!node.isManaged()) continue;
 421                 prefHeight += snapSizeY(node.prefHeight(-1)) + getSpacing();
 422             }
 423             prefHeight -= getSpacing();
 424         } else {
 425             for (Node node : toolbar.getItems()) {
 426                 if (!node.isManaged()) continue;
 427                 prefHeight = Math.max(prefHeight, snapSizeY(node.prefHeight(-1)));
 428             }
 429             if (toolbar.getItems().size() > 0) {
 430                 savedPrefHeight = prefHeight;
 431             } else {
 432                 prefHeight = savedPrefHeight;
 433             }
 434         }
 435         return topInset + prefHeight + bottomInset;
 436     }
 437 
 438     /** {@inheritDoc} */
 439     @Override protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) {
 440         return getSkinnable().getOrientation() == Orientation.VERTICAL ?
 441                 snapSizeX(getSkinnable().prefWidth(-1)) : Double.MAX_VALUE;
 442     }
 443 
 444     /** {@inheritDoc} */
 445     @Override protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) {
 446         return getSkinnable().getOrientation() == Orientation.VERTICAL ?
 447                 Double.MAX_VALUE : snapSizeY(getSkinnable().prefHeight(-1));
 448     }
 449 
 450     /** {@inheritDoc} */
 451     @Override protected void layoutChildren(final double x,final double y,
 452             final double w, final double h) {
 453 //        super.layoutChildren();
 454         final ToolBar toolbar = getSkinnable();
 455 
 456         if (toolbar.getOrientation() == Orientation.VERTICAL) {
 457             if (snapSizeY(toolbar.getHeight()) != previousHeight || needsUpdate) {
 458                 ((VBox)box).setSpacing(getSpacing());
 459                 ((VBox)box).setAlignment(getBoxAlignment());
 460                 previousHeight = snapSizeY(toolbar.getHeight());
 461                 addNodesToToolBar();
 462             }
 463         } else {
 464             if (snapSizeX(toolbar.getWidth()) != previousWidth || needsUpdate) {
 465                 ((HBox)box).setSpacing(getSpacing());
 466                 ((HBox)box).setAlignment(getBoxAlignment());
 467                 previousWidth = snapSizeX(toolbar.getWidth());
 468                 addNodesToToolBar();
 469             }
 470         }
 471         needsUpdate = false;
 472 
 473         double toolbarWidth = w;
 474         double toolbarHeight = h;
 475 
 476         if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 477             toolbarHeight -= (overflow ? snapSizeY(overflowMenu.prefHeight(-1)) : 0);
 478         } else {
 479             toolbarWidth -= (overflow ? snapSizeX(overflowMenu.prefWidth(-1)) : 0);
 480         }
 481 
 482         box.resize(toolbarWidth, toolbarHeight);
 483         positionInArea(box, x, y,
 484                 toolbarWidth, toolbarHeight, /*baseline ignored*/0, HPos.CENTER, VPos.CENTER);
 485 
 486         // If popup menu is not null show the overflowControl
 487         if (overflow) {
 488             double overflowMenuWidth = snapSizeX(overflowMenu.prefWidth(-1));
 489             double overflowMenuHeight = snapSizeY(overflowMenu.prefHeight(-1));
 490             double overflowX = x;
 491             double overflowY = x;
 492             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 493                 // This is to prevent the overflow menu from moving when there
 494                 // are no items in the toolbar.
 495                 if (toolbarWidth == 0) {
 496                     toolbarWidth = savedPrefWidth;
 497                 }
 498                 HPos pos = ((VBox)box).getAlignment().getHpos();
 499                 if (HPos.LEFT.equals(pos)) {
 500                     overflowX = x + Math.abs((toolbarWidth - overflowMenuWidth)/2);
 501                 } else if (HPos.RIGHT.equals(pos)) {
 502                     overflowX = (snapSizeX(toolbar.getWidth()) - snappedRightInset() - toolbarWidth) +
 503                         Math.abs((toolbarWidth - overflowMenuWidth)/2);
 504                 } else {
 505                     overflowX = x +
 506                         Math.abs((snapSizeX(toolbar.getWidth()) - (x) +
 507                         snappedRightInset() - overflowMenuWidth)/2);
 508                 }
 509                 overflowY = snapSizeY(toolbar.getHeight()) - overflowMenuHeight - y;
 510             } else {
 511                 // This is to prevent the overflow menu from moving when there
 512                 // are no items in the toolbar.
 513                 if (toolbarHeight == 0) {
 514                     toolbarHeight = savedPrefHeight;
 515                 }
 516                 VPos pos = ((HBox)box).getAlignment().getVpos();
 517                 if (VPos.TOP.equals(pos)) {
 518                     overflowY = y +
 519                         Math.abs((toolbarHeight - overflowMenuHeight)/2);
 520                 } else if (VPos.BOTTOM.equals(pos)) {
 521                     overflowY = (snapSizeY(toolbar.getHeight()) - snappedBottomInset() - toolbarHeight) +
 522                         Math.abs((toolbarHeight - overflowMenuHeight)/2);
 523                 } else {
 524                     overflowY = y + Math.abs((toolbarHeight - overflowMenuHeight)/2);
 525                 }
 526                overflowX = snapSizeX(toolbar.getWidth()) - overflowMenuWidth - snappedRightInset();
 527             }
 528             overflowMenu.resize(overflowMenuWidth, overflowMenuHeight);
 529             positionInArea(overflowMenu, overflowX, overflowY, overflowMenuWidth, overflowMenuHeight, /*baseline ignored*/0,
 530                     HPos.CENTER, VPos.CENTER);
 531         }
 532     }
 533 
 534 
 535 
 536     /***************************************************************************
 537      *                                                                         *
 538      * Private implementation                                                  *
 539      *                                                                         *
 540      **************************************************************************/
 541 
 542     private void initialize() {
 543         if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 544             box = new VBox();
 545         } else {
 546             box = new HBox();


 550         overflowMenu = new ToolBarOverflowMenu(overflowMenuItems);
 551         overflowMenu.setVisible(false);
 552         overflowMenu.setManaged(false);
 553 
 554         getChildren().clear();
 555         getChildren().add(box);
 556         getChildren().add(overflowMenu);
 557 
 558         previousWidth = 0;
 559         previousHeight = 0;
 560         savedPrefWidth = 0;
 561         savedPrefHeight = 0;
 562         needsUpdate = true;
 563         getSkinnable().requestLayout();
 564     }
 565 
 566     private void addNodesToToolBar() {
 567         final ToolBar toolbar = getSkinnable();
 568         double length = 0;
 569         if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 570             length = snapSizeY(toolbar.getHeight()) - snappedTopInset() - snappedBottomInset() + getSpacing();
 571         } else {
 572             length = snapSizeX(toolbar.getWidth()) - snappedLeftInset() - snappedRightInset() + getSpacing();
 573         }
 574 
 575         // Is there overflow ?
 576         double x = 0;
 577         boolean hasOverflow = false;
 578         for (Node node : getSkinnable().getItems()) {
 579             if (!node.isManaged()) continue;
 580 
 581             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 582                 x += snapSizeY(node.prefHeight(-1)) + getSpacing();
 583             } else {
 584                 x += snapSizeX(node.prefWidth(-1)) + getSpacing();
 585             }
 586             if (x > length) {
 587                 hasOverflow = true;
 588                 break;
 589             }
 590         }
 591 
 592         if (hasOverflow) {
 593             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 594                 length -= snapSizeY(overflowMenu.prefHeight(-1));
 595             } else {
 596                 length -= snapSizeX(overflowMenu.prefWidth(-1));
 597             }
 598             length -= getSpacing();
 599         }
 600 
 601         // Determine which node goes to the toolbar and which goes to the overflow.
 602         x = 0;
 603         overflowMenuItems.clear();
 604         box.getChildren().clear();
 605         for (Node node : getSkinnable().getItems()) {
 606             node.getStyleClass().remove("menu-item");
 607             node.getStyleClass().remove("custom-menu-item");
 608 
 609             if (node.isManaged()) {
 610                 if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
 611                     x += snapSizeY(node.prefHeight(-1)) + getSpacing();
 612                 } else {
 613                     x += snapSizeX(node.prefWidth(-1)) + getSpacing();
 614                 }
 615             }
 616 
 617             if (x <= length) {
 618                 box.getChildren().add(node);
 619             } else {
 620                 if (node.isFocused()) {
 621                     if (!box.getChildren().isEmpty()) {
 622                         Node last = engine.selectLast();
 623                         if (last != null) {
 624                             last.requestFocus();
 625                         }
 626                     } else {
 627                         overflowMenu.requestFocus();
 628                     }
 629                 }
 630                 if (node instanceof Separator) {
 631                     overflowMenuItems.add(new SeparatorMenuItem());
 632                 } else {
 633                     CustomMenuItem customMenuItem = new CustomMenuItem(node);