diff --git a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java index b97e140f17..6ec6d0ad9b 100644 --- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java +++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java @@ -453,12 +453,15 @@ public CssMetaData getCssMetaData() { // super.layoutChildren(); final ToolBar toolbar = getSkinnable(); + double toolbarLength = getToolbarLength(toolbar); if (toolbar.getOrientation() == Orientation.VERTICAL) { if (snapSizeY(toolbar.getHeight()) != previousHeight || needsUpdate) { ((VBox)box).setSpacing(getSpacing()); ((VBox)box).setAlignment(getBoxAlignment()); previousHeight = snapSizeY(toolbar.getHeight()); addNodesToToolBar(); + } else { + correctOverflow(toolbarLength); } } else { if (snapSizeX(toolbar.getWidth()) != previousWidth || needsUpdate) { @@ -466,8 +469,11 @@ public CssMetaData getCssMetaData() { ((HBox)box).setAlignment(getBoxAlignment()); previousWidth = snapSizeX(toolbar.getWidth()); addNodesToToolBar(); + } else { + correctOverflow(toolbarLength); } } + needsUpdate = false; double toolbarWidth = w; @@ -531,8 +537,6 @@ public CssMetaData getCssMetaData() { } } - - /*************************************************************************** * * * Private implementation * @@ -563,32 +567,14 @@ private void initialize() { getSkinnable().requestLayout(); } - private void addNodesToToolBar() { - final ToolBar toolbar = getSkinnable(); - double length = 0; - if (getSkinnable().getOrientation() == Orientation.VERTICAL) { - length = snapSizeY(toolbar.getHeight()) - snappedTopInset() - snappedBottomInset() + getSpacing(); - } else { - length = snapSizeX(toolbar.getWidth()) - snappedLeftInset() - snappedRightInset() + getSpacing(); - } - - // Is there overflow ? - double x = 0; - boolean hasOverflow = false; - for (Node node : getSkinnable().getItems()) { - if (!node.isManaged()) continue; - - if (getSkinnable().getOrientation() == Orientation.VERTICAL) { - x += snapSizeY(node.prefHeight(-1)) + getSpacing(); - } else { - x += snapSizeX(node.prefWidth(-1)) + getSpacing(); - } - if (x > length) { - hasOverflow = true; - break; - } + private void correctOverflow(double length) { + boolean overflowed = isOverflowed(length); + if (overflowed != overflow) { + organizeOverflow(length, overflow); } + } + private void organizeOverflow(double length, boolean hasOverflow) { if (hasOverflow) { if (getSkinnable().getOrientation() == Orientation.VERTICAL) { length -= snapSizeY(overflowMenu.prefHeight(-1)); @@ -599,7 +585,8 @@ private void addNodesToToolBar() { } // Determine which node goes to the toolbar and which goes to the overflow. - x = 0; + + double x = 0; overflowMenuItems.clear(); box.getChildren().clear(); for (Node node : getSkinnable().getItems()) { @@ -687,7 +674,43 @@ private void addNodesToToolBar() { overflowMenu.setManaged(overflow); } + private void addNodesToToolBar() { + final ToolBar toolbar = getSkinnable(); + double toolbarLength = getToolbarLength(toolbar); + + // Is there overflow ? + boolean hasOverflow = isOverflowed(toolbarLength); + + organizeOverflow(toolbarLength, hasOverflow); + } + private double getToolbarLength(ToolBar toolbar) { + double length; + if (getSkinnable().getOrientation() == Orientation.VERTICAL) { + length = snapSizeY(toolbar.getHeight()) - snappedTopInset() - snappedBottomInset() + getSpacing(); + } else { + length = snapSizeX(toolbar.getWidth()) - snappedLeftInset() - snappedRightInset() + getSpacing(); + } + return length; + } + + private boolean isOverflowed(double length) { + double x = 0; + boolean hasOverflow = false; + for (Node node : getSkinnable().getItems()) { + if (!node.isManaged()) continue; + if (getSkinnable().getOrientation() == Orientation.VERTICAL) { + x += snapSizeY(node.prefHeight(-1)) + getSpacing(); + } else { + x += snapSizeX(node.prefWidth(-1)) + getSpacing(); + } + if (x > length) { + hasOverflow = true; + break; + } + } + return hasOverflow; + } /*************************************************************************** * * diff --git a/modules/javafx.controls/src/test/java/test/javafx/scene/control/ToolbarTest.java b/modules/javafx.controls/src/test/java/test/javafx/scene/control/ToolbarTest.java index 16a3484e2a..a45293d52d 100644 --- a/modules/javafx.controls/src/test/java/test/javafx/scene/control/ToolbarTest.java +++ b/modules/javafx.controls/src/test/java/test/javafx/scene/control/ToolbarTest.java @@ -27,6 +27,10 @@ import javafx.css.CssMetaData; import static test.com.sun.javafx.scene.control.infrastructure.ControlTestUtils.*; + +import javafx.scene.AccessibleAttribute; +import javafx.scene.layout.Region; +import javafx.scene.layout.StackPane; import test.com.sun.javafx.scene.control.infrastructure.KeyEventFirer; import test.com.sun.javafx.pgstub.StubToolkit; import javafx.scene.control.skin.ToolBarSkin; @@ -58,10 +62,17 @@ public class ToolbarTest { private ToolBar toolBar;//Empty private ToolBar toolBarWithItems;//Items + private Toolkit tk; + private StackPane root; + private Node node1; private Node node2; + private static final double TOOLBAR_SIZE = 300.0; + private static final double EXPANDED_CHILDREN_SIZE = 250.0; + private static final double ORIGINAL_CHILDREN_SIZE = 100.0; + @Before public void setup() { tk = (StubToolkit)Toolkit.getToolkit();//This step is not needed (Just to make sure StubToolkit is loaded into VM) toolBar = new ToolBar(); @@ -221,4 +232,74 @@ public class ToolbarTest { tk.firePulse(); assertTrue(btn5.isFocused()); } + + @Test public void overflowShownInHorizontalAfterChildrenReziseTest() { + initializeToolBar(); + + toolBar.setOrientation(Orientation.HORIZONTAL); + + testOverflowVisibility(); + } + + @Test public void overflowShownInVerticalAfterChildrenReziseTest() { + initializeToolBar(); + + toolBar.setOrientation(Orientation.VERTICAL); + + testOverflowVisibility(); + } + + private void initializeToolBar() { + root = new StackPane(toolBar); + root.setPrefSize(400, 400); + + Scene scene = new Scene(root); + Stage stage = new Stage(); + stage.setScene(scene); + + toolBar.getItems().addAll(node1, node2); + setFixSize(toolBar, TOOLBAR_SIZE); + } + + private void testOverflowVisibility() { + setFixSize(node1, ORIGINAL_CHILDREN_SIZE); + setFixSize(node2, ORIGINAL_CHILDREN_SIZE); + + assertOverflowNotShown(); + + setFixSize(node1, EXPANDED_CHILDREN_SIZE); + + assertOverflowShown(); + + setFixSize(node1, ORIGINAL_CHILDREN_SIZE); + + assertOverflowNotShown(); + } + + private void setFixSize(Node node, double size) { + if (node instanceof Region) { + ((Region) node).setMinSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE); + ((Region) node).setMaxSize(Pane.USE_PREF_SIZE, Pane.USE_PREF_SIZE); + ((Region) node).setPrefSize(size, size); + } else if (node instanceof Rectangle) { + ((Rectangle) node).setHeight(size); + ((Rectangle) node).setWidth(size); + } + + root.applyCss(); + root.autosize(); + root.layout(); + } + + private void assertOverflowNotShown() { + Pane pane = (Pane) toolBar.queryAccessibleAttribute(AccessibleAttribute.OVERFLOW_BUTTON); + assertNotNull(pane); + assertFalse(pane.isVisible()); + } + + private void assertOverflowShown() { + Pane pane = (Pane) toolBar.queryAccessibleAttribute(AccessibleAttribute.OVERFLOW_BUTTON); + assertNotNull(pane); + assertTrue(pane.isVisible()); + } }