Overriding setContent method of UI throws exception

Hello,

I really don’t understand why this code throws exception.

public class SetcontentoverridetestUI extends UI {    
@Override
    public void setContent(Component content) {
        VerticalLayout layout = new VerticalLayout();
        super.setContent(layout);

        layout.addComponent(content);
    }

@Override
    protected void init(VaadinRequest request) {
        setContent(new Label("Hello"));
    }
}

13393.png

Ah, hmm. It looks like UI’s default constructor calls setContent(null), so it’s called when the UI is created.

    /**
     * Creates a new empty UI without a caption. The content of the UI must be
     * set by calling {@link #setContent(Component)} before using the UI.
     */
    public UI() {
        this(null);
    }

    /**
     * Creates a new UI with the given component (often a layout) as its
     * content.
     * 
     * @param content
     *            the component to use as this UIs content.
     * 
     * @see #setContent(Component)
     */
    public UI(Component content) {
        registerRpc(rpc);
        registerRpc(debugRpc);
        setSizeFull();
        setContent(content);
    }

Calling the setContent() is a completely unnecessary side-effect of the constructor, so I suppose you could file a ticket about that… However… That use-case is so marginal that there should not be much reason.

So, to work around the problem, just check for null in your setContent().

Is there some reason why you are overriding it like that? It’s probably fine, but I can’t think of a reason to do so.

I wrote something like this. I think thats not so marginal. I am grateful. Thanks for help mr. Grönroos.

@SuppressWarnings("serial")
@Theme("vaadinmultilanguagetest")

public class VaadinMultilanguageTestUI extends UI implements ValueChangeListener {
    ComboBox cmbLanguage;
    ArrayList<LocaleChangeListener> localeChangeListeners;
    ResourceBundle resourceBundle;
 
   @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = VaadinMultilanguageTestUI.class)
    public static class Servlet extends VaadinServlet {
    }

    public interface LocaleChangeListener {
        public void localeChange(ResourceBundle bundle);
    }

@Override
    public void valueChange(ValueChangeEvent event) {
        if (event.getProperty().getValue() == null)
            return;

        String language = event.getProperty().getValue().toString();
        Locale locale = null;
        switch (language) {
        case "Türkçe":
            locale = new Locale("tr", "TR");
            break;

        case "English":
            locale = new Locale("en", "US");
            break;

        case "русский":
            locale = new Locale("ru", "RU");
            break;

        default:
            locale = getLocale();
            break;
        }

        if (locale != null) {
            setLocale(locale);
            resourceBundle = ResourceBundle.getBundle("Test", locale);
            for (LocaleChangeListener listener : localeChangeListeners)
                listener.localeChange(resourceBundle);
        }
    }

    public void addLocaleChangeListener(LocaleChangeListener listener) {
        localeChangeListeners.add(listener);
    }

    public void removeLocaleChangeListener(LocaleChangeListener listener) {
       localeChangeListeners.remove(listener);
    }

    public VaadinMultilanguageTestUI(Component component) {
        super(component);
        setLocale(new Locale("en", "US"));
        resourceBundle = ResourceBundle.getBundle("Test", getLocale());
        localeChangeListeners = new ArrayList<LocaleChangeListener>();
        cmbLanguage = new ComboBox();
        cmbLanguage.setImmediate(true);
        cmbLanguage.addValueChangeListener(this);

        cmbLanguage.addItem("Türkçe");
        cmbLanguage.addItem("English");
        cmbLanguage.addItem("русский");
    }

    public VaadinMultilanguageTestUI() {
        this(null);
    }

    public ResourceBundle getResourceBundle() {
        return resourceBundle;
    }

@Override
    public void setContent(Component content) {
        VerticalLayout uiContent = new VerticalLayout();

        if (cmbLanguage != null)    {
            uiContent.addComponent(cmbLanguage);
            uiContent.setComponentAlignment(cmbLanguage, Alignment.TOP_RIGHT);
        }

        if (content != null)
            uiContent.addComponent(content);

        super.setContent(uiContent);
    }

@Override
    protected void init(VaadinRequest request) {
        Navigator navigator = new Navigator(this, this);

        navigator.addView("login", new LoginView());
        navigator.addView("home", new HomeView());
        navigator.addView("about-us", new AboutUsView());
    }
}