setTheme method in vaadin 7 ?

Hello everbody,

I want to implement my own theme for my application but I can’t find the setTheme() method anywhere ? is it normal ?

Thank you !

The method setTheme() has been replaced with the @Theme annotation, which you can specify for a Root.
If you need more complex logic for theme selection, you can also override Application.getThemeForRoot(), but that should rarely be necessary.

Henri,

I’m a kind of lost. How can we change the theme at runtime in order to change JUST the L&F?

Suppose we have a small application, but depending on a user perference we want to let him change the theme. How can we do that with Vaadin7 ?

In vaadin 6 we just have to call setTheme() method and set the theme selected.

Perhaps I’m following something else…

Thanks

True on-the-fly theme change support was left out in Vaadin 7. Changing the whole theme is a feature that was mostly used in demo applications and on certain portals etc. just because the portal allowed it.

You can override Application.getThemeForRoot(Root) to decide on the theme to use at application start, but need to restart/reload the application to actually change the theme.

For your own customizations to a theme (rather than changing the whole theme), you can structure your theme so that they depend on a style name near the “root” layout of the application and you set a style name for the layout to effectively change the theme of everything inside it. There will be other theme related enhancements in the near future that will make this easy to do in practice and perhaps even almost support changing whole themes on the fly.

Hi,

Putting things that could be configured into the code is
always
a bad idea.

Selecting/Setting up Colors on a per user basis is a feature that is always nice to have in every application.

I will have a look on that, at least the app L&F can be configured at the start then.

Please don’t forget to do this, it is more important than it seems to be.

geetings
Ralf

I totally agree with that. In fact, in my case because of business requirements, this “difference” could be a reason to keep using the version 6.

As Henri pointed out earlier, this is doable just by using simple style names or using the @Stylesheet annotation. Although setTheme might easier to figure out initially.

Not trying to dismiss the use case or need, just pointing out alternative solutions.

Hi,

Maybe, i am blind, but at the moment i don’t see a way to switch themes
at runtime

with hard coded constant annotations in the java source. Did i miss something?

greetings
Ralf

That’s because the structure of the theme css files does not support changing the theme
on the fly
, not in Vaadin 6 nor in Vaadin 7. In Vaadin 6, changing the theme after the view has been rendered forces a page reload in the browser to completely get rid of the styles from the previously set theme.

This in combination with changing the default in Vaadin 7 to rebuild the UI state from scratch when reloading in the browser means that we can not provide an API for changing the theme
on the fly
without lots of undesired side effects. This is why we have instead provided several options for defining the theme that will be used when a Root is initially rendered, with the @Theme annotation defined at
compile time
being the suggested default method.

For those that want to select a theme
at runtime
when a Root is initially loaded, we are providing the Application.getThemeForRoot method that can be overridden if the @Theme annotation is not enough.

If our ongoing theme refactoring will turn out to support changing the theme on the fly without a reload, we will most certainly also add an API for changing the theme on the fly.

come on… the typical use case would probably not be the user changing theme for whatever reason… but rather presenting the user with a theme selected at runtime (most likely at root-init) based on the url or another dynamic setting.

The option of using annotations just does not solve this case. (with this solution only… why even bother having the possibility to have more than one theme??)
The alternative of overriding and replacing the application class just seems soo unnecessary when it could have been done much easier.

Please make it possible to change the theme within the UI.init (or Root or whatever it will be called) method in a version soon

[quote=Leif Åstrand]

And now from the Vaadin Blog:

So now what? Application. getThemeForRoot () was the solution, and now that solution is gone. Like the other posters above, I need to select themes at runtime.

See UIProvider.getTheme() and
this thread
.

If you are implying that I need to override getTheme() in my UI class, I tried that:
public String getTheme() {
return ChameleonTheme.THEME_NAME;
}
and found it to not work.

Any other suggestions would be appreciated.

My use case: I’d like users to set a theme they prefer, even if it requires a logout/full refresh.

Just develop your own theme switching mechanism. It’s easy.
Even with Vaadin 6, I was always annoyed by the page reload effect when switching themes with setTheme().
So I decided to do it differently:
My application has 3 parts: menu, header and content.
In my custom switchTheme method, I set the style of those 3 elements like this:

public final void witchTheme(String theme) {
    header.setStyleName(HEADER_STYLE_NAME + theme);
    menu.setStyleName(MENU_STYLE_NAME + theme);
    content.setStyleName(CONTENT_STYLE_NAME + theme);
}

All my “themes” are contained in one css file and the switching is now as smooth as it should be.

I must second that the theme support in V7 is a real problem. I get the theme name as a URI- parameter and have no influence on that.

The “solution” of E. Denzer is not feasible in most cases. Themes are customer specific in my case. So I give the CSS and images and whatever to the customers marketing guys and they change on their own. So a strict separation.

Honestly, I did not understand the UIProvider.getTheme(). It adds IMHO an unnecessary degree of complexity.
Isn’t there a simple example for that in V7 ?

Currently the theme handling here is a showstopper on our path to V7.

Regards
Gerd

If you want to run the whole application with different themes based on URI parameters, UIProvider is the correct place to select the theme.

See e.g.
this tutorial
on how to use a UIProvider - you do not need to select different UIs but always return the same UI class and override getTheme(…) for the customization. In your web.xml, just replace the UI parameter with one for selecting the UIProvider.

The theme needs to be selected early so that it can be loaded early. Otherwise even the application loading indicator etc. would not use your theme, and/or late starting of the theme download would delay the startup of your application a little more (as it does in Vaadin 6). Reloading a page when changing themes is necessary anyway, and triggering a reload right when starting the application would lead to “flickering” and significantly degraded perceived performance.

In most applications - those where one doesn’t want to totally replace the theme but rather customize it - the solution by Emmanuel is simple and much more efficient than theme switching as it does not require reloads.

How about multy-tenant applications. I am desigig an app for ~12 tenants, they all want to have somehow different themes. Depending on the user (belonging to a differet tenant) a different theme should be selected. Can I select different themes for different (simultanuous) users?

In UIProvider you can use information that is available on the first request, so if e.g. your tenants are using different DNS names for the server or are logged in using JAAS before the first request for a Vaadin application, it should be easy to pick the theme based on that.

If the information is not available when starting the Vaadin UI, what exactly would you need?

yes you are right - tenant information should be available when starting the Vaadin UI. So setting the corresponding theme in UIProvider should work. No need to change the theme afterwards for multy-tenant purposes. Thanks.