changeset 11143:aea5c65b89db 12+7

8152395: [ToolBar] Overflow button of ToolBar doesn't appear when the size of the items increases Reviewed-by: aghaisas, kcr Contributed-by: diegocirujano@gmail.com
author aghaisas
date Fri, 04 Jan 2019 15:28:40 +0530
parents a34aad4d1110
children 514452cfcc50
files modules/javafx.controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java modules/javafx.controls/src/test/java/test/javafx/scene/control/ToolbarTest.java
diffstat 2 files changed, 131 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java	Thu Jan 03 12:19:50 2019 -0800
+++ b/modules/javafx.controls/src/main/java/javafx/scene/control/skin/ToolBarSkin.java	Fri Jan 04 15:28:40 2019 +0530
@@ -453,12 +453,15 @@
 //        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 @@
                 ((HBox)box).setAlignment(getBoxAlignment());
                 previousWidth = snapSizeX(toolbar.getWidth());
                 addNodesToToolBar();
+            } else {
+                correctOverflow(toolbarLength);
             }
         }
+
         needsUpdate = false;
 
         double toolbarWidth = w;
@@ -531,8 +537,6 @@
         }
     }
 
-
-
     /***************************************************************************
      *                                                                         *
      * Private implementation                                                  *
@@ -563,32 +567,14 @@
         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();
+    private void correctOverflow(double length) {
+        boolean overflowed = isOverflowed(length);
+        if (overflowed != overflow) {
+            organizeOverflow(length, overflow);
         }
+    }
 
-        // 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 organizeOverflow(double length, boolean hasOverflow) {
         if (hasOverflow) {
             if (getSkinnable().getOrientation() == Orientation.VERTICAL) {
                 length -= snapSizeY(overflowMenu.prefHeight(-1));
@@ -599,7 +585,8 @@
         }
 
         // 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 @@
         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;
+    }
 
     /***************************************************************************
      *                                                                         *
--- a/modules/javafx.controls/src/test/java/test/javafx/scene/control/ToolbarTest.java	Thu Jan 03 12:19:50 2019 -0800
+++ b/modules/javafx.controls/src/test/java/test/javafx/scene/control/ToolbarTest.java	Fri Jan 04 15:28:40 2019 +0530
@@ -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 @@
         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());
+    }
 }