public void onStateChanged(StateChangeEvent stateChangeEvent) {
super.onStateChanged(stateChangeEvent);
+ // Ensure the template is initialized even if there are no children
+ // (#9725)
+ updateHtmlTemplate();
+
// Evaluate scripts
VCustomLayout.eval(getWidget().scripts);
getWidget().scripts = null;
@Override
public void onConnectorHierarchyChange(ConnectorHierarchyChangeEvent event) {
- // Must do this once here so the HTML has been set up before we start
- // adding child widgets.
-
+ // Must call here in addition to onStateChanged because
+ // onConnectorHierarchyChange is invoked before onStateChanged
updateHtmlTemplate();
-
// For all contained widgets
for (ComponentConnector child : getChildComponents()) {
String location = getState().childLocations.get(child);
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head profile="http://selenium-ide.openqa.org/profiles/test-case"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="selenium.base" href="" /><title>com.vaadin.tests.components.accordion.AccordionInactiveTabSize</title></head><body><table cellpadding="1" cellspacing="1" border="1"><thead><tr><td rowspan="1" colspan="3">com.vaadin.tests.components.accordion.AccordionInactiveTabSize</td></tr></thead><tbody><tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.components.customcomponent.CustomLayoutUsingTemplate?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>initial</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentscustomcomponentCustomLayoutUsingTemplate::/VVerticalLayout[0]/VVerticalLayout[0]/VCustomLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>with-text-field</td>
-</tr>
-</tbody></table></body></html>
\ No newline at end of file
+++ /dev/null
-package com.vaadin.tests.components.customcomponent;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import com.vaadin.tests.components.TestBase;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.ui.Button.ClickListener;
-import com.vaadin.ui.CustomLayout;
-import com.vaadin.ui.Label;
-import com.vaadin.ui.TextField;
-
-public class CustomLayoutUsingTemplate extends TestBase implements
- ClickListener {
-
- CustomLayout layout;
-
- @Override
- protected void setup() {
- String thisPackage = CustomLayoutUsingTemplate.class.getName().replace(
- '.', '/');
- thisPackage = thisPackage.replaceAll(
- CustomLayoutUsingTemplate.class.getSimpleName() + "$", "");
- String template = thisPackage + "template.htm";
- InputStream is = getClass().getClassLoader().getResourceAsStream(
- template);
- try {
- layout = new CustomLayout(is);
- layout.addComponent(new Button(
- "Click to add a TextField to second location", this),
- "location1");
- addComponent(layout);
- } catch (IOException e) {
- addComponent(new Label(e.getMessage()));
- e.printStackTrace();
- } finally {
- try {
- is.close();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
-
- @Override
- protected String getDescription() {
- return "Test for using a CustomLayout with a template read from an input stream and passed through the state";
- }
-
- @Override
- protected Integer getTicketNumber() {
- return null;
- }
-
- @Override
- public void buttonClick(ClickEvent event) {
- layout.addComponent(new TextField("A text field!"), "location2");
- }
-}
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head profile="http://selenium-ide.openqa.org/profiles/test-case"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="selenium.base" href="" /><title>com.vaadin.tests.components.accordion.AccordionInactiveTabSize</title></head><body><table cellpadding="1" cellspacing="1" border="1"><thead><tr><td rowspan="1" colspan="3">com.vaadin.tests.components.accordion.AccordionInactiveTabSize</td></tr></thead><tbody><tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.components.customcomponent.CustomLayoutUsingTheme?restartApplication</td>
- <td></td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>initial</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentscustomcomponentCustomLayoutUsingTheme::/VVerticalLayout[0]/VVerticalLayout[0]/VCustomLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>label</td>
-</tr>
-<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestscomponentscustomcomponentCustomLayoutUsingTheme::/VVerticalLayout[0]/VVerticalLayout[0]/VCustomLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>
- <td></td>
-</tr>
-<tr>
- <td>screenCapture</td>
- <td></td>
- <td>button</td>
-</tr>
-</tbody></table></body></html>
\ No newline at end of file
+++ /dev/null
-package com.vaadin.tests.components.customcomponent;
-
-import com.vaadin.tests.components.TestBase;
-import com.vaadin.tests.util.LoremIpsum;
-import com.vaadin.ui.Button;
-import com.vaadin.ui.Button.ClickEvent;
-import com.vaadin.ui.Button.ClickListener;
-import com.vaadin.ui.CustomLayout;
-import com.vaadin.ui.Label;
-import com.vaadin.ui.NativeButton;
-import com.vaadin.ui.TextField;
-import com.vaadin.ui.VerticalLayout;
-
-public class CustomLayoutUsingTheme extends TestBase implements ClickListener {
-
- private CustomLayout layout;
-
- @Override
- protected void setup() {
- setTheme("tests-tickets");
- layout = new CustomLayout("Ticket1775");
- addComponent(layout);
- layout.addComponent(new TextField("Username"), "loginUser");
- layout.addComponent(new TextField("Password"), "loginPassword");
- layout.addComponent(new Button("Login"), "loginButton");
- layout.setWidth(null);
-
- VerticalLayout menu = new VerticalLayout();
- menu.addComponent(new Button("Set body to label", new ClickListener() {
-
- @Override
- public void buttonClick(ClickEvent event) {
- layout.addComponent(new Label(LoremIpsum.get(200)), "body");
- }
- }));
- menu.addComponent(new Button("Set body to huge NativeButton",
- new ClickListener() {
-
- @Override
- public void buttonClick(ClickEvent event) {
- layout.addComponent(new NativeButton(
- "This is it, the body!"), "body");
- }
- }));
- layout.addComponent(menu, "menu");
- }
-
- @Override
- protected String getDescription() {
- return "Test for using a CustomLayout with a template read from an input stream and passed through the state";
- }
-
- @Override
- protected Integer getTicketNumber() {
- return null;
- }
-
- @Override
- public void buttonClick(ClickEvent event) {
- layout.addComponent(new TextField("A text field!"), "location2");
- }
-
-}
+++ /dev/null
-<b>Contents</b>
-<div location="location1">This is where the first component goes</div>
-<div style="width: 500px; border: 1 px solid blue; margin: 10px;" location="location2">This is where the second component goes</div>
-<b>End of template</b>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head profile="http://selenium-ide.openqa.org/profiles/test-case">
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+<link rel="selenium.base" href="http://localhost:8070/" />
+<title>CustomLayoutUsingTemplate</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">CustomLayoutUsingTemplate</td></tr>
+</thead><tbody>
+<tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.customlayout.CustomLayoutUsingTemplate?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>initial</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentscustomlayoutCustomLayoutUsingTemplate::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentscustomlayoutCustomLayoutUsingTemplate::/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VVerticalLayout[0]/VOrderedLayout$Slot[1]/VCustomLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>with-text-field</td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
--- /dev/null
+package com.vaadin.tests.components.customlayout;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CustomLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TextField;
+
+public class CustomLayoutUsingTemplate extends TestBase implements
+ ClickListener {
+
+ CustomLayout layout;
+ Button button1 = new Button("Add Button to first location", this);
+ Button button2 = new Button("Add TextField to second location", this);
+
+ @Override
+ protected void setup() {
+ String thisPackage = CustomLayoutUsingTemplate.class.getName().replace(
+ '.', '/');
+ thisPackage = thisPackage.replaceAll(
+ CustomLayoutUsingTemplate.class.getSimpleName() + "$", "");
+ String template = thisPackage + "template.htm";
+ InputStream is = getClass().getClassLoader().getResourceAsStream(
+ template);
+
+ addComponent(button1);
+
+ try {
+ layout = new CustomLayout(is);
+ addComponent(layout);
+ } catch (IOException e) {
+ addComponent(new Label(e.getMessage()));
+ e.printStackTrace();
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Test for using a CustomLayout with a template read from an input stream and passed through the state";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return null;
+ }
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ if (event.getButton() == button1) {
+ layout.addComponent(button2, "location1");
+ } else {
+ layout.addComponent(new TextField("A text field!"), "location2");
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head profile="http://selenium-ide.openqa.org/profiles/test-case"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><link rel="selenium.base" href="" /><title>com.vaadin.tests.components.accordion.AccordionInactiveTabSize</title></head><body><table cellpadding="1" cellspacing="1" border="1"><thead><tr><td rowspan="1" colspan="3">com.vaadin.tests.components.accordion.AccordionInactiveTabSize</td></tr></thead><tbody><tr>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.components.customlayout.CustomLayoutUsingTheme?restartApplication</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>initial</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentscustomlayoutCustomLayoutUsingTheme::/VVerticalLayout[0]/VVerticalLayout[0]/VCustomLayout[0]/VVerticalLayout[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>label</td>
+</tr>
+<tr>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestscomponentscustomlayoutCustomLayoutUsingTheme::/VVerticalLayout[0]/VVerticalLayout[0]/VCustomLayout[0]/VVerticalLayout[0]/VButton[1]/domChild[0]/domChild[0]</td>
+ <td></td>
+</tr>
+<tr>
+ <td>screenCapture</td>
+ <td></td>
+ <td>button</td>
+</tr>
+</tbody></table></body></html>
--- /dev/null
+package com.vaadin.tests.components.customlayout;
+
+import com.vaadin.tests.components.TestBase;
+import com.vaadin.tests.util.LoremIpsum;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Button.ClickEvent;
+import com.vaadin.ui.Button.ClickListener;
+import com.vaadin.ui.CustomLayout;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.NativeButton;
+import com.vaadin.ui.TextField;
+import com.vaadin.ui.VerticalLayout;
+
+public class CustomLayoutUsingTheme extends TestBase implements ClickListener {
+
+ private CustomLayout layout;
+
+ @Override
+ protected void setup() {
+ setTheme("tests-tickets");
+ layout = new CustomLayout("Ticket1775");
+ addComponent(layout);
+ layout.addComponent(new TextField("Username"), "loginUser");
+ layout.addComponent(new TextField("Password"), "loginPassword");
+ layout.addComponent(new Button("Login"), "loginButton");
+ layout.setWidth(null);
+
+ VerticalLayout menu = new VerticalLayout();
+ menu.addComponent(new Button("Set body to label", new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ layout.addComponent(new Label(LoremIpsum.get(200)), "body");
+ }
+ }));
+ menu.addComponent(new Button("Set body to huge NativeButton",
+ new ClickListener() {
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ layout.addComponent(new NativeButton(
+ "This is it, the body!"), "body");
+ }
+ }));
+ layout.addComponent(menu, "menu");
+ }
+
+ @Override
+ protected String getDescription() {
+ return "Test for using a CustomLayout with a template read from an input stream and passed through the state";
+ }
+
+ @Override
+ protected Integer getTicketNumber() {
+ return null;
+ }
+
+ @Override
+ public void buttonClick(ClickEvent event) {
+ layout.addComponent(new TextField("A text field!"), "location2");
+ }
+
+}
--- /dev/null
+<b>Contents</b>
+<div location="location1">This is where the first component goes</div>
+<div style="width: 500px; border: 1 px solid blue; margin: 10px;" location="location2">This is where the second component goes</div>
+<b>End of template</b>
\ No newline at end of file