Our automated tests for CustomLayout from a theme are passing so it does seem to work in general with Vaadin 7.
Maybe there is something wrong with file locations or such. One thing to try would be to send the theme template via an InputStream given as a parameter to the other constructor of CustomLayout. If a theme read that way works, that would at least indicate that CustomLayout and your template work otherwise and just the path or such is a problem. To get the stream, try with ServletContext.getResourceAsStream(String) (with a suitably modified path) or Class.getResourceAsStream(String) - note that for the latter you may need to move the template to be on the classpath.
I am giving a try to OSGi + Vaadin 7 combination and I have been able to reproduce this issue. Testing several Vaadin 7 builds I found that using [b]
[i]
[/i]com.vaadin_7.0.0.nightly-20120113-0fff9b0fab8988136f138bb51739920043da4248
[/b] everything seems to be fine, while using[b]
[i]
[/i] vaadin-7.0.0.alpha3
[/b] or [b]
[i]
[/i]vaadin-7.0.0.alpha2rc1
[/b] breaks my demo and I can see the same error message on Vaadin console.
I pushed a fix to the issue that should cause the warnings. Based on the fact that our own tests are working without problems even when these warnings are present, I’m quite sure there are still some other issues hiding somewhere.
Based on the report regarding problems related to OSGi, I suspect the problem is related to how the server-side code attempts to find the html files int the theme folder. Putting a breakpoint on com.vaadin.terminal.gwt.server.CommunicationManager.getThemeResourceAsStream(Root, String, String) and checking what’s happening with the returned value could give some insights into this problem.
@Theme(“watering-hole”)
public class V7customlayoutRoot extends Root { @Override
public void init(WrappedRequest request) {
CustomLayout custom = getCustomLayout();
setContent(custom);
}
public CustomLayout getCustomLayout() {
return new CustomLayout("index");
}
}
NOTE: I have tried adding the CustomLayout to a Panel and then set the Panel as the content of the root. Also tried the same trick with the VerticalLayout to no avail.
Next is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
V7CustomLayout
Vaadin production mode
productionMode
false
V7customlayout Application
com.vaadin.terminal.gwt.server.ApplicationServlet
Vaadin root class to use
root
com.example.v7customlayout.V7customlayoutRoot
V7customlayout Application
/*
index.html
index.htm
index.jsp
default.html
default.htm
default.jsp
package com.example.cslayouttest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import com.vaadin.annotations.Theme;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.*;
import com.vaadin.ui.themes.BaseTheme;
@Theme("cslayouttesttheme")
public class CslayouttestUI extends UI {
@Override
public void init(VaadinRequest request) {
// Have a Panel where to put the custom layout.
Panel panel = new Panel("Login");
panel.setSizeUndefined();
addComponent(panel);
// Create custom layout from "layoutname.html" template.
CustomLayout custom = new CustomLayout("layoutname");
custom.addStyleName("customlayoutexample");
// Use it as the layout of the Panel.
panel.setContent(layout);
// Create a few components and bind them to the location tags
// in the custom layout.
TextField username = new TextField();
custom.addComponent(username, "username");
TextField password = new TextField();
custom.addComponent(password, "password");
Button ok = new Button("Login");
custom.addComponent(ok, "okbutton");
}
}
works for me in 7beta5.
layoutname.html is located in VAADIN/themes/cslayouttesttheme/layouts/
This, as a simple generated example,
CustomLayout layout = null;
try {
layout = new CustomLayout(
new ByteArrayInputStream(
"Here is a <span location='link1'></span> and here is another <span location='link2'></span>"
.getBytes()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Button link1 = new Button("link");
link1.addStyleName(BaseTheme.BUTTON_LINK);
layout.addComponent(link1, "link1");
Button link2 = new Button("link");
link2.addStyleName(BaseTheme.BUTTON_LINK);
layout.addComponent(link2, "link2");
// Use it as the layout of the Panel.
panel.setContent(layout);
// Create a few components and bind them to the location tags
// in the custom layout.
TextField username = new TextField();
custom.addComponent(username, "username");
TextField password = new TextField();
custom.addComponent(password, "password");
Button ok = new Button("Login");
custom.addComponent(ok, "okbutton");
}
works for me as well with 7beta5.
Also have another rather big html page with lots of javascripts and lots of graphics stuff running with the same basic approach.
I tried this page from the static file under the above VAADIN directory structure and also had it identically generated as ByteArrayInputstream. Both approaches worked perfectly with 7beta5. I even had the the vaadin components generated in a method just for the fun in another test by parsing another html filewere I put some tags for this purpose. Also works.
Hmm. What could be the problem here? Do the above examples work for you with beta 5? I think they were from the book or some example page, maybe I made some small changes for what had changed from then up to 7beta5, I dont quite remember.
We’re using CustomLayout with Vaadin 7.0.6 and we’re using it with the InputStream constructor. I getTemplateContent() returns the correct html. However nothing gets rendered on the actual page. It all works with Vaadin 6 though.
We realized an “unfortunate” change migrating our Vaadin 6 application to Vaadin 7 related to CustomLayout.
If we are adding a component with location, which cannot be found in the CustomLayout-html, the browser freeze.
As I remember, in Vaadin 6 it wasn’t problem if location not found, component just wasn’t added.
In my opinion, it is bad for debugging and hard to write test. Throwing an Exception or just “skipping” the unfound Component (just like in Vaadin 6) would be better way to react to “problematic code”.