Preloader

Hello all

I’m programming a vaadin web application and I came to the point where it would be necessary to show a preloader to the user to avoid misunderstandings.

More concretely, I would like to show a gif while content is being loaded.

Do you have any tips and tricks how to do so?
Could I make use of the preloader of vaadin (in the upper right corner)?

thanks!
ben

It is automatically started as yellow when a server round-trip has taken more than a certain amount of time, and red a little later. You could also try to use its images etc. yourself, but IIRC there is no API for starting and stopping the indicator from your program.

Also least the
Toolkit Productivity Tools
add-on has a wrapper for lazily loading a component. This approach could be useful in some cases.

Note that depending on what is the activity (from the point of view of the browser) taking time, browsers may be “stuck” and not animate images etc. while doing certain kinds of processing.

Thanks a bunch!

I will go with the Toolkit Productivity Tools Addon.
Thanks for your help!

It’s me again :slight_smile:

I ran into a bloody annoying error I cannot get rid of - I’ve been trying for hours.

I’m using the Toolkit Productivity Tools Addon. The preloader seems to work most times, but then sometimes (not predictable) following exception shows up:


java.util.ConcurrentModificationException
	at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
	at java.util.LinkedList$ListItr.next(LinkedList.java:696)
	at com.vaadin.ui.AbstractOrderedLayout.paintContent(AbstractOrderedLayout.java:144)
	at com.vaadin.ui.AbstractComponent.paint(AbstractComponent.java:754)
	at com.vaadin.ui.AbstractOrderedLayout.paintContent(AbstractOrderedLayout.java:146)
	at com.vaadin.ui.AbstractComponent.paint(AbstractComponent.java:754)
	at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.paintAfterVariableChanges(AbstractCommunicationManager.java:807)
	at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:621)
	at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:266)
	at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:476)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
	at java.lang.Thread.run(Thread.java:680)

Do you have any clue what this means? Apparently threading produces problems… but I can’t find the root of the error. Any pointers are greatly appreciated :slight_smile:

ben

The actual error means that you have a list which is being modified while it is being read. For example, you cannot do this

for(String str : myList) {
   myList.remove(str);
}

Additionally to TPT,
this add-on
might also be something you’re looking for.

Hi Kim!

The strange thing is that I do not alter any list at all. It’s Vaadin or the addon-on which causes the error.
But I cannot find the root why they are throwing this exception.

According to its description LazyLoadWrapper does only support Safari and Firefox. I have not tested it yet in IE. Do you have any experience with this add-on?

thanks for your help!

Hmm, that’s strange. TPT only removes progress indicator and replacing it with the actual component at the end. Ben, are you sure you’re not manipulating any lists/collections in your lazy load method, actually could you just show us a code snipped from that part ?

I’ll also check the TPT lazy loader in case something wrong there (but actually did not ever get such exception myself).

Dmitri

Hello Dmitri!

Thanks for responding!

Well, no, I’m not modifying any lists as far as I know.

With this simplified snippet I get the error.


package preloader.test;

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

import eu.livotov.tpt.TPTApplication;
import eu.livotov.tpt.gui.widgets.TPTLazyLoadingLayout;

@SuppressWarnings("serial")
public class MyVaadinApplication extends TPTApplication
{
    private Window window;

	@Override
	public void applicationInit() {
	VerticalLayout MainLayout = new VerticalLayout();
    	final VerticalLayout contentWindow = new VerticalLayout();
    	 
        window = new Window("My Vaadin Application");
        setMainWindow(window);
        
        window.addComponent(MainLayout);
    
        
        Button loadContent1 = new Button("load page 1");
        MainLayout.addComponent(loadContent1);
        loadContent1.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				contentWindow.removeAllComponents();
				contentWindow.addComponent(new TPTLazyLoadingLayout(new page1(), true));
			}
        });
        
        Button loadContent2 = new Button("load page 2");
        MainLayout.addComponent(loadContent2);
        loadContent2.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				contentWindow.removeAllComponents();
				contentWindow.addComponent(new TPTLazyLoadingLayout(new page2(), true));
			}
        });
        
        MainLayout.addComponent(contentWindow);

	}

	@Override
	public void firstApplicationStartup() {
		// TODO Auto-generated method stub
		
	}
    
}

The pages being loaded are:


package preloader.test;

import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;

import eu.livotov.tpt.gui.widgets.TPTLazyLoadingLayout;
import eu.livotov.tpt.gui.widgets.TPTLazyLoadingLayout.LazyLoader;

public class page1 extends VerticalLayout implements LazyLoader {

	private static final long serialVersionUID = 1L;

	public page1() {}
	
	public String getLazyLoadingMessage() {
		return "loading page 1...";
	}

	public Component lazyLoad(TPTLazyLoadingLayout layout) {
		addComponent(new Label("hello page from page 1"));
		return this;
	}
	
}

page2() looks the same, just with a different label.

Here you can see the demo of my snippet
here
.

When I click on the buttons, the preloader shows up and everything seems normal. But then, after a while (means a couple of clicks) the error in my post above occurs. Sometimes it takes longer, sometimes the error occurs just after 2-3 clicks.

What I have noticed, the error only occurs when I add the TPTLazyLoadingLayout object to the component. The error does not occur when I just create the new TPTLazyLoadingLayout object and do not add it to the concrete component.

Does this snippet help you? If I can be of any further assistance, please let me know.

thanks for having a look at it.
ben

ps. just for the record, here the entire exception which the server throws when the red “Internal error” box shows up.


java.util.ConcurrentModificationException
	at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
	at java.util.LinkedList$ListItr.next(LinkedList.java:696)
	at com.vaadin.ui.AbstractOrderedLayout.paintContent(AbstractOrderedLayout.java:144)
	at com.vaadin.ui.AbstractComponent.paint(AbstractComponent.java:754)
	at com.vaadin.ui.AbstractOrderedLayout.paintContent(AbstractOrderedLayout.java:146)
	at com.vaadin.ui.AbstractComponent.paint(AbstractComponent.java:754)
	at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.paintAfterVariableChanges(AbstractCommunicationManager.java:807)
	at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:621)
	at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:266)
	at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:476)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
	at java.lang.Thread.run(Thread.java:680)

Hi Ben,

I played with the demo and it seems error only occurs when you click button too often - while loading process from previous click is not yet finished. So just to test, please try to disable button in onClick listener and enable it back at the end of your lazy loader process.

From my side I’ll check the tpt code to see if I need to synchronize anything there

Hi Dmitri

Are you sure that the error only occurs during the loading process?
As far as I’m concerned, the error also occurs when I wait for a long time and the content has been lazy loaded successfully. Sometimes the error occurs on the first click too.

Ok, I can work on a snippet which deactivates the button until the content has been loaded.

hm interesting, it seems as if you are right!

now the error has not occur anymore.

snippet2

To sum it up:
It works when: There is only one lazy loading layout at a time, plus if one waits until the TPTLazyLoadingLayout has been added to the component before loading others.

in my case on the other hand it does not work:
because I load several boxes with TPTLazyLoadingLayout at the same time. Therefore it can happen, that a TPTLazyLoadingLayout is being ordered to preload while another TPTLazyLoadingLayout is still being loaded. This then causes the exception.

Thus, something could be wrong (a bug?) in TPT, will look more precisely at it.

BTW, there should not be any limits on number of TPTLazyLoaders on the screen, as they all are different instances. So seems to be really a bug there

Great, thank you so much!

Yes, a bug could be the case. Because some times it works fine, but then out of the blue the exception is thrown. Therefore I sense a thread related problem. Maybe a variable is being shared, but it shouldn’t. But that’s just my gut feeling.

If you need any help testing or something, let me know.

Any news?

Sorry to be a bit pushy :unsure:
It’s just that I could really make use of your lazy loading widget…

You might want to try LazyLoadingWrapper add-on also.

Hi everybody!

I have the same issue using TPTLazyLoader. And I also can’t find out steps to reproduce it.

P.S. TPT is really nice =)

Dimitri (and all),

Add this to your TPTLazyLoadingLayout class (specifically the synchronized):

private void activateLoadedView ( Component lazyLoad )
{

synchronized (TPTApplication.getCurrentApplication()) {

removeAllComponents ();
addComponent ( lazyLoad );

}

}

When you have many threads trying to update the UI at the same time, they get wires crossed - the synch block eliminates. :grin:

Thanks.