]> source.dussan.org Git - vaadin-framework.git/commitdiff
Fix Grid height calculation when HeightMode.ROW (#20104, #20074)
authoradam <adam@vaadin.com>
Mon, 8 Aug 2016 12:25:10 +0000 (15:25 +0300)
committerHenri Sara <hesara@vaadin.com>
Thu, 11 Aug 2016 10:26:27 +0000 (13:26 +0300)
When Grid is inside of a Tab (Tabsheet or Accordion) and
height mode is set to HeightMode.ROW, layout happens
before row height is known. To fix that, an event is fired
and a handler starts a layout after everything is calculated.

Change-Id: Idc8de795956b387ec69adf1871cb7f557914d998

client/src/main/java/com/vaadin/client/connectors/GridConnector.java
client/src/main/java/com/vaadin/client/widget/escalator/events/RowHeightChangedEvent.java [new file with mode: 0644]
client/src/main/java/com/vaadin/client/widget/escalator/events/RowHeightChangedHandler.java [new file with mode: 0644]
client/src/main/java/com/vaadin/client/widgets/Escalator.java
client/src/main/java/com/vaadin/client/widgets/Grid.java
uitest/src/main/java/com/vaadin/tests/components/grid/GridRowHeightChange.java [new file with mode: 0644]
uitest/src/test/java/com/vaadin/tests/components/grid/GridRowHeightChangeTest.java [new file with mode: 0644]

index f53d9c9d044ae342e747b0d2eb6a48f203731bf8..550cf1517c64bf7c48bd022d25c9ec39bbbd88bb 100644 (file)
@@ -52,6 +52,8 @@ import com.vaadin.client.ui.AbstractComponentConnector;
 import com.vaadin.client.ui.AbstractHasComponentsConnector;
 import com.vaadin.client.ui.ConnectorFocusAndBlurHandler;
 import com.vaadin.client.ui.SimpleManagedLayout;
+import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent;
+import com.vaadin.client.widget.escalator.events.RowHeightChangedHandler;
 import com.vaadin.client.widget.grid.CellReference;
 import com.vaadin.client.widget.grid.CellStyleGenerator;
 import com.vaadin.client.widget.grid.EditorHandler;
@@ -797,6 +799,16 @@ public class GridConnector extends AbstractHasComponentsConnector implements
         getWidget().setDetailsGenerator(customDetailsGenerator);
         getLayoutManager().registerDependency(this, getWidget().getElement());
 
+        // Handling row height changes
+        getWidget().addRowHeightChangedHandler(new RowHeightChangedHandler() {
+            @Override
+            public void onRowHeightChanged(RowHeightChangedEvent event) {
+                getLayoutManager()
+                        .setNeedsMeasureRecursively(GridConnector.this);
+                getLayoutManager().layoutNow();
+            }
+        });
+
         layout();
     }
 
diff --git a/client/src/main/java/com/vaadin/client/widget/escalator/events/RowHeightChangedEvent.java b/client/src/main/java/com/vaadin/client/widget/escalator/events/RowHeightChangedEvent.java
new file mode 100644 (file)
index 0000000..1c4a875
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.widget.escalator.events;
+
+import com.google.gwt.event.shared.GwtEvent;
+
+/**
+ * Event fired when the row height changed in the Escalator's header, body or
+ * footer.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public class RowHeightChangedEvent extends GwtEvent<RowHeightChangedHandler> {
+
+    /**
+     * Handler type.
+     */
+    public final static Type<RowHeightChangedHandler> TYPE = new Type<RowHeightChangedHandler>();
+
+    public static final Type<RowHeightChangedHandler> getType() {
+        return TYPE;
+    }
+
+    @Override
+    public Type<RowHeightChangedHandler> getAssociatedType() {
+        return TYPE;
+    }
+
+    @Override
+    protected void dispatch(RowHeightChangedHandler handler) {
+        handler.onRowHeightChanged(this);
+    }
+
+}
diff --git a/client/src/main/java/com/vaadin/client/widget/escalator/events/RowHeightChangedHandler.java b/client/src/main/java/com/vaadin/client/widget/escalator/events/RowHeightChangedHandler.java
new file mode 100644 (file)
index 0000000..8ad243a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.vaadin.client.widget.escalator.events;
+
+import com.google.gwt.event.shared.EventHandler;
+
+/**
+ * Event handler for a row height changed event.
+ *
+ * @since
+ * @author Vaadin Ltd
+ */
+public interface RowHeightChangedHandler extends EventHandler {
+
+    /**
+     * A row height changed event, fired by Escalator when the header, body or
+     * footer row height has changed.
+     *
+     * @param event Row height changed event
+     */
+    public void onRowHeightChanged(RowHeightChangedEvent event);
+}
index 2005881b404ec19590cee3d21c456bee9f718e9b..52f981fe6362427a69751d759700e02ceb8a6cc9 100644 (file)
@@ -85,6 +85,7 @@ import com.vaadin.client.widget.escalator.ScrollbarBundle.HorizontalScrollbarBun
 import com.vaadin.client.widget.escalator.ScrollbarBundle.VerticalScrollbarBundle;
 import com.vaadin.client.widget.escalator.Spacer;
 import com.vaadin.client.widget.escalator.SpacerUpdater;
+import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent;
 import com.vaadin.client.widget.grid.events.ScrollEvent;
 import com.vaadin.client.widget.grid.events.ScrollHandler;
 import com.vaadin.client.widgets.Escalator.JsniUtil.TouchHandlerBundle;
@@ -1895,6 +1896,19 @@ public class Escalator extends Widget implements RequiresResize,
             });
         }
 
+        private void fireRowHeightChangedEventFinally() {
+            if (!rowHeightChangedEventFired) {
+                rowHeightChangedEventFired = true;
+                Scheduler.get().scheduleFinally(new ScheduledCommand() {
+                    @Override
+                    public void execute() {
+                        fireEvent(new RowHeightChangedEvent());
+                        rowHeightChangedEventFired = false;
+                    }
+                });
+            }
+        }
+
         public void autodetectRowHeightNow() {
             if (!isAttached()) {
                 // Run again when attached
@@ -1902,6 +1916,8 @@ public class Escalator extends Widget implements RequiresResize,
                 return;
             }
 
+            final double oldRowHeight = defaultRowHeight;
+
             final Element detectionTr = DOM.createTR();
             detectionTr.setClassName(getStylePrimaryName() + "-row");
 
@@ -1920,6 +1936,10 @@ public class Escalator extends Widget implements RequiresResize,
                 reapplyDefaultRowHeights();
                 applyHeightByRows();
             }
+
+            if (oldRowHeight != defaultRowHeight) {
+                fireRowHeightChangedEventFinally();
+            }
         }
 
         @Override
@@ -5432,6 +5452,11 @@ public class Escalator extends Widget implements RequiresResize,
     private final BodyRowContainerImpl body = new BodyRowContainerImpl(bodyElem);
     private final FooterRowContainer footer = new FooterRowContainer(footElem);
 
+    /**
+     * Flag for keeping track of {@link RowHeightChangedEvent}s
+     */
+    private boolean rowHeightChangedEventFired = false;
+
     private final Scroller scroller = new Scroller();
 
     private final ColumnConfigurationImpl columnConfiguration = new ColumnConfigurationImpl();
@@ -6731,4 +6756,4 @@ public class Escalator extends Widget implements RequiresResize,
     double getMinCellWidth(int colIndex) {
         return columnConfiguration.getMinCellWidth(colIndex);
     }
-}
+}
\ No newline at end of file
index de0706a8d21e39350600fbe6da51cb47e88d54ae..7e5838be400557f3e1732099b3d9da0baa61a0d9 100644 (file)
@@ -104,6 +104,8 @@ import com.vaadin.client.widget.escalator.RowVisibilityChangeHandler;
 import com.vaadin.client.widget.escalator.ScrollbarBundle.Direction;
 import com.vaadin.client.widget.escalator.Spacer;
 import com.vaadin.client.widget.escalator.SpacerUpdater;
+import com.vaadin.client.widget.escalator.events.RowHeightChangedEvent;
+import com.vaadin.client.widget.escalator.events.RowHeightChangedHandler;
 import com.vaadin.client.widget.grid.AutoScroller;
 import com.vaadin.client.widget.grid.AutoScroller.AutoScrollerCallback;
 import com.vaadin.client.widget.grid.AutoScroller.ScrollAxis;
@@ -8146,6 +8148,11 @@ public class Grid<T> extends ResizeComposite implements
         return addHandler(handler, GridEnabledEvent.TYPE);
     }
 
+    public HandlerRegistration addRowHeightChangedHandler(
+            RowHeightChangedHandler handler) {
+        return escalator.addHandler(handler, RowHeightChangedEvent.TYPE);
+    }
+
     /**
      * Apply sorting to data source.
      */
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridRowHeightChange.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridRowHeightChange.java
new file mode 100644 (file)
index 0000000..3cb735d
--- /dev/null
@@ -0,0 +1,73 @@
+package com.vaadin.tests.components.grid;
+
+import com.vaadin.data.Property;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.grid.HeightMode;
+import com.vaadin.tests.components.AbstractTestUI;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.NativeSelect;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.VerticalLayout;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class GridRowHeightChange extends AbstractTestUI {
+
+    private final List<String> themes = Arrays
+            .asList("valo", "reindeer", "runo", "chameleon", "base");
+
+    @Override
+    protected void setup(VaadinRequest request) {
+        Grid grid = new Grid();
+
+        // create column and fill rows
+        grid.addColumn("Header");
+        for (int i = 1; i <= 10; i++) {
+            grid.addRow("row_" + i);
+        }
+
+        // set height mode and height
+        grid.setHeightMode(HeightMode.ROW);
+        grid.setHeightByRows(10);
+
+        // create a tabsheet with one tab and place grid inside
+        VerticalLayout tab = new VerticalLayout();
+        TabSheet tabSheet = new TabSheet();
+        tabSheet.setWidthUndefined();
+        tabSheet.addTab(tab, "Tab");
+        tab.addComponent(grid);
+
+        // Theme selector
+        NativeSelect themeSelector = new NativeSelect("Theme selector", themes);
+        themeSelector.select("reindeer");
+        themeSelector.setNullSelectionAllowed(false);
+        themeSelector
+                .addValueChangeListener(new Property.ValueChangeListener() {
+                    @Override
+                    public void valueChange(Property.ValueChangeEvent event) {
+                        setTheme((String) event.getProperty().getValue());
+                    }
+                });
+
+        VerticalLayout layout = new VerticalLayout();
+        layout.setSpacing(true);
+        layout.setSizeUndefined();
+
+        layout.addComponent(themeSelector);
+        layout.addComponent(tabSheet);
+
+        addComponent(layout);
+    }
+
+    @Override
+    protected String getTestDescription() {
+        return "Test if Grid's height is adjusted when HeightMode.ROW and row height is recalculated.<br>"
+                + "When loading is complete, all 10 rows should be visible with all themes.";
+    }
+
+    @Override
+    protected Integer getTicketNumber() {
+        return 20104;
+    }
+}
diff --git a/uitest/src/test/java/com/vaadin/tests/components/grid/GridRowHeightChangeTest.java b/uitest/src/test/java/com/vaadin/tests/components/grid/GridRowHeightChangeTest.java
new file mode 100644 (file)
index 0000000..1e1cab5
--- /dev/null
@@ -0,0 +1,42 @@
+package com.vaadin.tests.components.grid;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.elements.GridElement;
+import com.vaadin.testbench.elements.NativeSelectElement;
+import com.vaadin.tests.tb3.MultiBrowserTest;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class GridRowHeightChangeTest extends MultiBrowserTest {
+
+    private final List<String> themes = Arrays
+            .asList("valo", "reindeer", "runo", "chameleon", "base");
+
+    @Override
+    public void setup() throws Exception {
+        super.setup();
+        openTestURL();
+    }
+
+    @Test
+    public void changeThemeAndMeasureGridHeight() {
+        for (String theme : themes) {
+            // select theme
+            $(NativeSelectElement.class).first().selectByText(theme);
+
+            GridElement grid = $(GridElement.class).first();
+
+            int gridHeight = grid.getSize().getHeight();
+            int tabsheetHeight = findElements(
+                    By.className("v-tabsheet-content"))
+                    .get(0).getSize().getHeight();
+
+            assertEquals("Grid's visible height should be equal to Grid height",
+                    gridHeight, tabsheetHeight, 1);
+        }
+    }
+}