replace main window w/o user action

hello,
i want to implement a splash screen that works for both, servlet and portlet2.
the reason why i need this, is the fact that if the init() method takes some time, it looks like the portal/servlet is dead and the user does not know what is going on.
i have this function:

void replaceMainWindow(Window newMainWindow) {
    removeWindow(getMainWindow());
    setMainWindow(newMainWindow);
}

if the method gets called by an user action (eg button click) it works as expected but if i use a progress indicator and transaction listener it does not, i have to reload the page manually.
here is some pseudo code to explain it better:

boolean initialized = false;
ProgressIndicator poller;
Thread initBackendThread; <- sets initialized to true as last action
Window mainWindow;
Window splashScreen;
...
init() {
    ...
    splashScreen.addComponent(poller);
    setMainWindow(splashScreen);
    initBackendThread.start();
}
...
transactionStart(...) {
    if (initialized && ...) {
        replaceMainWindow(mainWindow);
    }
}
...

i solved the problem right now using the same window for main and splash and a content cache but i dont like this solution.
if anyone could explain me how it works correctly, i would be very grateful.

thx in advance
felix

i have found another solution besides a content cache.

i have created a simple timer widget and the interface PollEventListener which declares the method pollEvent.
my application implements the interface.
in the changeVariables-method of the server side component the pollEvent-method gets called on the listener.
if i replace the main window in the pollEvent-method, it works as expected.

but still, i do not like this solution too…
isn’t there a way to get this done without some content-cache-hack or an extra widget?
does anyone know, why i can not change the main window in the transactionStart (same for onRequestStart from portlet or servlet listeners) method?

I guess that you have a timer in that second thread that calles the replace method after a set of time? In that case you have a problem with how Vaadin communicates.

See, the communication between the server and the browser works always in the same direction. It starts with the user doing something in the browser. The browser then sends an event to the server, the server does what is asked and then it sends back to the browser everything what has changed as a response. At this point the browser repaints the parts that has changed. The communication is always like this: browser->server->browser

Having another thread initialize a change is not an event sent from the browser, but it’s all happening on the server side. As the server can’t automatically push the changes to the browser, the browser will never get any changes. When you hit refresh, or do anything else that does a server roundtrip, the changed data (change of main window) will ride along in that request.

Because of this, the timer and the request to change the main window has to be executed from the browser, or then you have to implement push functionality with the ICEPush add-on. Push might be a little overkill when there is only one thing to push. I suggest you use the
Refresher
add-on with a appropiate timer for your splash screen, and remove the component after the first refresh.

thx for your reply.
no, thats not the case, i already have a timer (progressindicator) on the splashscreen, so it would make no sense to add another.
the timer polls, transactionlistener is called and the replace method gets called out of the transactionStart method when the flag initialized is true.
and initialized gets set to true by the initBackendThread…
well im not good in explaining i will bring my question down to a point:

why can’t i change the main window in the transactionStart or onRequestStart methods (triggered by a progressindicator) but by a call to a button.clicklistener ?

in a portlet context both ways are generating an UIDL-ResourceRequest.

here are again some code snippets:

[code]
Button b = new Button(“click”);
b.addListener(new ClickListener() {
@Override
public void buttonClick(ClickEvent event) {
replaceMainWindow(realMainWindow);
}
});

[/code] works

and

@Override public void transactionStart(Application application, Object transactionData) { // using ProgressIndicator to trigger this method constantly until initialized is true if (initialized && getMainWindow() != realMainWindow) { replaceMainWindow(realMainWindow); } } works not

btw what i wrote in my 2nd post, is exactly the same thing what you proposed with the refresher.

Hi,

If I remember correctly there is some issues with the setMainWindow() method and changing the main window won’t always work. The recommended way to do this is to change the contents of the main window instead of changing the window.

-Henri

thx for your answer.
my problem is that im limited to vaadin 6.2 and there portlet modes are handled by a window for each mode. this has changed in 6.4 to the content approach i know, but that wont help me in this case.
i know i could use the content way in 6.2 too, but i generally try to use frameworks in the way they are intended to work.
but well thinking about it, using the content way would be a cleaner solution than using a non-default widget or some content cache in my opinion…
if its not possible to use the progressindicator and transactionlistener approach, i think i will try your idea.

thanks