summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2015-07-12 20:11:41 +0300
committerMika Murtojarvi <mika@vaadin.com>2015-09-15 10:51:02 +0300
commit18cf80534a98651510f2b743d215083206aea53a (patch)
treede9332299aef1f23b447c7f96940ae5faa8d6bbb
parentefdc36027dec55e8b1084c7ea94ccb843b8a7c99 (diff)
downloadvaadin-framework-18cf80534a98651510f2b743d215083206aea53a.tar.gz
vaadin-framework-18cf80534a98651510f2b743d215083206aea53a.zip
Backport fix for #16992 to Vaadin 7.5.
Change-Id: I4899aac895f061cffffaccc5b0e33f92bada28b0
-rw-r--r--client/src/com/vaadin/client/ApplicationConnection.java19
-rw-r--r--client/src/com/vaadin/client/LayoutManager.java21
-rw-r--r--client/src/com/vaadin/client/ui/layout/LayoutDependencyTree.java27
-rw-r--r--uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayout.java117
-rw-r--r--uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayoutTest.java48
-rw-r--r--uitest/src/com/vaadin/tests/customelements/CustomProgressBarElement.java56
6 files changed, 277 insertions, 11 deletions
diff --git a/client/src/com/vaadin/client/ApplicationConnection.java b/client/src/com/vaadin/client/ApplicationConnection.java
index 5547b02895..24cfdf62b9 100644
--- a/client/src/com/vaadin/client/ApplicationConnection.java
+++ b/client/src/com/vaadin/client/ApplicationConnection.java
@@ -63,7 +63,6 @@ import com.google.gwt.user.client.Window.ClosingHandler;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.ApplicationConfiguration.ErrorMessage;
-import com.vaadin.client.ApplicationConnection.ApplicationStoppedEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadEvent;
import com.vaadin.client.ResourceLoader.ResourceLoadListener;
import com.vaadin.client.communication.HasJavaScriptConnectorHelper;
@@ -1693,18 +1692,20 @@ public class ApplicationConnection implements HasHandlers {
updatingState = false;
- if (!onlyNoLayoutUpdates) {
- Profiler.enter("Layout processing");
- try {
- LayoutManager layoutManager = getLayoutManager();
+ Profiler.enter("Layout processing");
+ try {
+ LayoutManager layoutManager = getLayoutManager();
+ if (!onlyNoLayoutUpdates) {
layoutManager.setEverythingNeedsMeasure();
+ }
+ if (layoutManager.isLayoutNeeded()) {
layoutManager.layoutNow();
- } catch (final Throwable e) {
- getLogger().log(Level.SEVERE,
- "Error processing layouts", e);
}
- Profiler.leave("Layout processing");
+ } catch (final Throwable e) {
+ getLogger()
+ .log(Level.SEVERE, "Error processing layouts", e);
}
+ Profiler.leave("Layout processing");
if (ApplicationConfiguration.isDebugMode()) {
Profiler.enter("Dumping state changes to the console");
diff --git a/client/src/com/vaadin/client/LayoutManager.java b/client/src/com/vaadin/client/LayoutManager.java
index 102e618f5e..2d10d0c082 100644
--- a/client/src/com/vaadin/client/LayoutManager.java
+++ b/client/src/com/vaadin/client/LayoutManager.java
@@ -1800,4 +1800,25 @@ public class LayoutManager {
return Logger.getLogger(LayoutManager.class.getName());
}
+ /**
+ * Checks if there is something waiting for a layout to take place.
+ *
+ * @since 7.5.6
+ * @return true if there are connectors waiting for measurement or layout,
+ * false otherwise
+ */
+ public boolean isLayoutNeeded() {
+ if (!needsHorizontalLayout.isEmpty() || !needsVerticalLayout.isEmpty()) {
+ return true;
+ }
+ if (!needsMeasure.isEmpty()) {
+ return true;
+ }
+
+ if (everythingNeedsMeasure) {
+ return true;
+ }
+
+ return false;
+ }
}
diff --git a/client/src/com/vaadin/client/ui/layout/LayoutDependencyTree.java b/client/src/com/vaadin/client/ui/layout/LayoutDependencyTree.java
index 07bb6688e3..a4c5668948 100644
--- a/client/src/com/vaadin/client/ui/layout/LayoutDependencyTree.java
+++ b/client/src/com/vaadin/client/ui/layout/LayoutDependencyTree.java
@@ -17,6 +17,7 @@ package com.vaadin.client.ui.layout;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.logging.Logger;
import com.google.gwt.core.client.JsArrayString;
import com.vaadin.client.ApplicationConnection;
@@ -500,6 +501,12 @@ public class LayoutDependencyTree {
if (connector == null) {
connector = (ComponentConnector) ConnectorMap.get(connection)
.getConnector(connectorId);
+ if (connector == null) {
+ getLogger().warning(
+ "No connector found for id " + connectorId
+ + " while creating LayoutDependency");
+ return null;
+ }
}
dependency = new LayoutDependency(connector, direction);
dependencies.put(connectorId, dependency);
@@ -531,7 +538,12 @@ public class LayoutDependencyTree {
public void setNeedsHorizontalLayout(String connectorId, boolean needsLayout) {
LayoutDependency dependency = getDependency(connectorId, HORIZONTAL);
- dependency.setNeedsLayout(needsLayout);
+ if (dependency != null) {
+ dependency.setNeedsLayout(needsLayout);
+ } else {
+ getLogger().warning(
+ "No dependency found in setNeedsHorizontalLayout");
+ }
}
/**
@@ -549,7 +561,13 @@ public class LayoutDependencyTree {
public void setNeedsVerticalLayout(String connectorId, boolean needsLayout) {
LayoutDependency dependency = getDependency(connectorId, VERTICAL);
- dependency.setNeedsLayout(needsLayout);
+ if (dependency != null) {
+ dependency.setNeedsLayout(needsLayout);
+ } else {
+ getLogger()
+ .warning("No dependency found in setNeedsVerticalLayout");
+ }
+
}
public void markAsHorizontallyLayouted(ManagedLayout layout) {
@@ -736,4 +754,9 @@ public class LayoutDependencyTree {
}
return dependency.scrollingBoundary;
}
+
+ private static Logger getLogger() {
+ return Logger.getLogger(LayoutDependencyTree.class.getName());
+ }
+
}
diff --git a/uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayout.java b/uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayout.java
new file mode 100644
index 0000000000..9f63970f85
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayout.java
@@ -0,0 +1,117 @@
+package com.vaadin.tests.components;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import com.vaadin.annotations.Theme;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.GridLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.ProgressBar;
+import com.vaadin.ui.UI;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+
+@SuppressWarnings("serial")
+@Theme("valo")
+public class NoLayoutUpdateWhichNeedsLayout extends UI {
+
+ private ProgressBar progressBar;
+ private Window w;
+
+ @Override
+ protected void init(VaadinRequest request) {
+ final VerticalLayout layout = new VerticalLayout();
+ layout.setMargin(true);
+ setContent(layout);
+
+ setPollInterval(1000);
+
+ Button button = new Button(
+ "1. Execute scheduled task and show progress in a window");
+ button.setId("openWindow");
+ button.addClickListener(new Button.ClickListener() {
+
+ private Window w2;
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ GridLayout glo = new GridLayout();
+ progressBar = new ProgressBar();
+ progressBar.setIndeterminate(false);
+ progressBar.setId("progress");
+ glo.addComponent(progressBar);
+
+ w2 = new Window("test");
+ w2.setWidth("600px");
+ w2.setHeight("200px");
+ w2.setContent(glo);
+ w2.center();
+ Button closeB = new Button(
+ "2. Click to close after the progress is updated");
+ closeB.setId("closeWindow");
+ closeB.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ w2.close();
+ w2 = null;
+ }
+ });
+ glo.addComponent(closeB);
+ addWindow(w2);
+
+ scheduleTask();
+ }
+ });
+
+ Button openWin = new Button("3. Finally, Click to open a new Window");
+ openWin.addClickListener(new ClickListener() {
+ @Override
+ public void buttonClick(ClickEvent event) {
+ w = new Window("test");
+ w.setWidth("300px");
+ w.setHeight("300px");
+ w.setContent(new VerticalLayout(new Label(
+ "simple test label component")));
+ w.center();
+ getUI().addWindow(w);
+ }
+ });
+
+ Button stopPolling = new Button("Stop polling", new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ setPollInterval(-1);
+ }
+ });
+ layout.addComponents(button, openWin, stopPolling);
+ }
+
+ protected void scheduleTask() {
+ Thread t = new Thread() {
+
+ @Override
+ public void run() {
+ getUI().access(new Runnable() {
+ @Override
+ public void run() {
+ updateProgresBar(50);
+ }
+ });
+ }
+ };
+ ScheduledExecutorService worker = Executors
+ .newSingleThreadScheduledExecutor();
+ worker.schedule(t, 2, TimeUnit.SECONDS);
+ }
+
+ public void updateProgresBar(int pc) {
+ progressBar.setValue((float) (pc / 100.0));
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayoutTest.java b/uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayoutTest.java
new file mode 100644
index 0000000000..bc12919ccd
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/NoLayoutUpdateWhichNeedsLayoutTest.java
@@ -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.tests.components;
+
+import org.junit.Test;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.ui.ExpectedCondition;
+
+import com.vaadin.testbench.elements.ButtonElement;
+import com.vaadin.tests.customelements.CustomProgressBarElement;
+import com.vaadin.tests.tb3.SingleBrowserTest;
+
+public class NoLayoutUpdateWhichNeedsLayoutTest extends SingleBrowserTest {
+
+ @Test
+ public void layoutRunForNoLayoutUpdate() {
+ openTestURL("debug");
+ ButtonElement open = $(ButtonElement.class).id("openWindow");
+ open.click();
+ final CustomProgressBarElement progress = $(
+ CustomProgressBarElement.class).first();
+ waitUntil(new ExpectedCondition<Boolean>() {
+ @Override
+ public Boolean apply(WebDriver input) {
+ double p = progress.getValue();
+ return Math.abs(p - 0.5) < 0.01;
+ }
+ });
+
+ ButtonElement close = $(ButtonElement.class).id("closeWindow");
+ close.click();
+
+ assertNoErrorNotifications();
+ }
+}
diff --git a/uitest/src/com/vaadin/tests/customelements/CustomProgressBarElement.java b/uitest/src/com/vaadin/tests/customelements/CustomProgressBarElement.java
new file mode 100644
index 0000000000..663f398bba
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/customelements/CustomProgressBarElement.java
@@ -0,0 +1,56 @@
+/*
+ * 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.tests.customelements;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.testbench.elements.ProgressBarElement;
+import com.vaadin.testbench.elementsbase.ServerClass;
+
+@ServerClass("com.vaadin.ui.ProgressBar")
+public class CustomProgressBarElement extends ProgressBarElement {
+
+ public double getValue() {
+ WebElement indicator = findElement(By
+ .className("v-progressbar-indicator"));
+ String width = getStyleAttribute(indicator, "width");
+ if (!width.endsWith("%")) {
+ return 0;
+ }
+
+ return Double.parseDouble(width.replace("%", "")) / 100.0;
+ }
+
+ /**
+ * @since 7.5.6
+ * @param indicator
+ * @param string
+ * @return
+ */
+ private String getStyleAttribute(WebElement element, String styleName) {
+ String style = element.getAttribute("style");
+ String[] styles = style.split(";");
+ for (String s : styles) {
+ if (s.startsWith(styleName + ":")) {
+ return s.substring(styleName.length() + 1).trim();
+ }
+ }
+
+ return null;
+ }
+
+} \ No newline at end of file