Directory

← Back

KDubb FutureComponent

Unleash raw, multithreaded, asynchronous fury with FutureComponent. Especially useful when you present data from datasources

Author

Rating

Popularity

<100

While that red indicator is spinning and spinning your users are losing interest.

Unleash raw, multithreaded, asynchronous fury with FutureComponent.

If you use datasources or have any components prepared using long running processes FutureComponent is here to help. With FutureComponent the user will get instant feedback with a waiting indicator where your component will be. When it has been created, it will automatically be shown to the user with no extra effort on your part. Just fire and forget.

Not only does it show the user feedback instantly, but will finish quicker by allowing you to easily multithread these tasks. Normally component1 will have to be completely prepared before component2 starts being worked on, but not with your trusty friend FutureComponent.

Sample code

import java.util.Properties;
import java.util.concurrent.Callable;

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.kdubb.futurecomponent.factory.DefaultFutureFactory;
import com.kdubb.futurecomponent.factory.FutureFactory;
import com.vaadin.server.DeploymentConfiguration;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.server.VaadinServletRequest;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;

@SuppressWarnings("serial")
public class TestApp extends UI
{
	public static void main(String[] args) throws Exception
	{
		startInEmbeddedJetty();
	}

	public static Server startInEmbeddedJetty() throws Exception
	{
		Server server = new Server(8888);

		ServletContextHandler handler = new ServletContextHandler(ServletContextHandler.SESSIONS);
		handler.addServlet(Servlet.class, "/*");
		server.setHandler(handler);

		server.start();

		return server;
	}

	// mapping used to if demo war is built from these sources
	@WebServlet(urlPatterns = "/*")
	public static class Servlet extends VaadinServlet
	{
		@Override
		public VaadinServletRequest createVaadinRequest(HttpServletRequest request)
		{
			VaadinServletRequest result = super.createVaadinRequest(request);

			DeploymentConfiguration conf = result.getService().getDeploymentConfiguration();
			Properties params = conf.getInitParameters();
			params.setProperty("UI", TestApp.class.getName());

			return result;
		}
	}

	@Override
	protected void init(VaadinRequest request)
	{
		ApplicationContext context = new ClassPathXmlApplicationContext("spring/main.xml");
		final FutureFactory futureFactory = (FutureFactory)context.getBean(DefaultFutureFactory.class);
		
		setSizeFull();
		
		VerticalLayout layout = new VerticalLayout();
		layout.setSpacing(true);
		layout.setMargin(true);
		
		{
			Button button = new Button("Normal Window");
			button.addClickListener(new Button.ClickListener()
			{
				@Override
				public void buttonClick(ClickEvent event)
				{
					Window window = getNormalWindow();
					UI.getCurrent().addWindow(window);
				}
			});
			layout.addComponent(button);
		}
		{
			Button button = new Button("Futurized Window");
			button.addClickListener(new Button.ClickListener()
			{
				@Override
				public void buttonClick(ClickEvent event)
				{
					Window window = getFutureWindow(futureFactory);
					UI.getCurrent().addWindow(window);
				}
			});
			layout.addComponent(button);
		}
		
		this.setContent(layout);
	}
	
	private Component getLabel(String text)
	{
		try
		{
			Thread.sleep(500);
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}
		
		return new Label(text);
	}
	
	private Component getTable()
	{
		try
		{
			Thread.sleep(2500);
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}
		
		Table table = new Table();
		table.setWidth("100%");
		table.setPageLength(5);
		
		table.addContainerProperty("First Name", String.class,  null);
		table.addContainerProperty("Last Name",  String.class,  null);
		table.addContainerProperty("Year",       Integer.class, null);

		/* Add a few items in the table. */
		table.addItem(new Object[] {
		    "Nicolaus","Copernicus",new Integer(1473)}, new Integer(1));
		table.addItem(new Object[] {
		    "Tycho",   "Brahe",     new Integer(1546)}, new Integer(2));
		table.addItem(new Object[] {
		    "Giordano","Bruno",     new Integer(1548)}, new Integer(3));
		table.addItem(new Object[] {
		    "Galileo", "Galilei",   new Integer(1564)}, new Integer(4));
		table.addItem(new Object[] {
		    "Johannes","Kepler",    new Integer(1571)}, new Integer(5));
		table.addItem(new Object[] {
		    "Isaac",   "Newton",    new Integer(1643)}, new Integer(6));
		
		return table;
	}
	
	private Window getNormalWindow()
	{
		Window window = createNewWindow();
		window.setCaption("Normal Window");
		
		VerticalLayout layout = new VerticalLayout();
		layout.setSizeFull();
		layout.setSpacing(true);
		layout.setMargin(true);
		
		{
			Component component = getLabel("I took 1 second to generate");
			layout.addComponent(component);
		}
		{
			Component component = getTable();
			layout.addComponent(component);
			layout.setExpandRatio(component, 1);
		}
		{
			Component component = getLabel("Also took 1 second to get back");
			layout.addComponent(component);
		}
		{
			Component component = getTable();
			layout.addComponent(component);
			layout.setExpandRatio(component, 1);
		}
		
		window.setContent(layout);
		
		return window;
	}
	
	private Window getFutureWindow(FutureFactory futureFactory)
	{
		Window window = createNewWindow();
		window.setCaption("Window with FutureComponents");
		
		VerticalLayout layout = new VerticalLayout();
		layout.setWidth("100%");
		layout.setHeight("360px");
		layout.setSpacing(true);
		layout.setMargin(true);
		
		{
			Component component = futureFactory.getFutureComponent(new Callable<Component>()
			{
				@Override
				public Component call() throws Exception
				{
					return getLabel("I took 1 second to generate");
				}
			});
			layout.addComponent(component);
		}
		{
			Component component = futureFactory.getFutureComponent(new Callable<Component>()
			{
				@Override
				public Component call() throws Exception
				{
					return getTable();
				}
			});
			layout.addComponent(component);
			layout.setExpandRatio(component, 1);
		}
		{
			Component component = futureFactory.getFutureComponent(new Callable<Component>()
			{
				@Override
				public Component call() throws Exception
				{
					return getLabel("Also took 1 second to get back");
				}
			});
			layout.addComponent(component);
		}
		{
			Component component = futureFactory.getFutureComponent(new Callable<Component>()
			{
				@Override
				public Component call() throws Exception
				{
					return getTable();
				}
			});
			layout.addComponent(component);
			layout.setExpandRatio(component, 1);
		}
		
		window.setContent(layout);
		return window;
	}

	private Window createNewWindow()
	{
		Window window = new Window();
		window.setModal(true);
		window.setWidth("600px");
		window.setHeight("460px");
		
		return window;
	}
}
Component component = futureFactory.getFutureComponent(new Callable<Component>()
{
	@Override
	public Component call() throws Exception
	{
		Thread.sleep(1000);
		return new Label("I took 1 second to generate");
	}
});
<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
	<property name="corePoolSize" value="5" />
	<property name="maxPoolSize" value="10" />
	<property name="queueCapacity" value="25" />
</bean>
	
<bean id="futureFactory" class="com.kdubb.futurecomponent.factory.DefaultFutureFactory">
	<property name="executor" ref="executor" />
</bean>

Compatibility

(Loading compatibility data...)

Was this helpful? Need more help?
Leave a comment or a question below. You can also join the chat on Discord or ask questions on StackOverflow.

Version

Released
2013-01-14
Maturity
EXPERIMENTAL
License
Apache License 2.0

Compatibility

Framework
Vaadin 7.0+
Browser
Browser Independent

KDubb FutureComponent - Vaadin Add-on Directory

Unleash raw, multithreaded, asynchronous fury with FutureComponent. Especially useful when you present data from datasources KDubb FutureComponent - Vaadin Add-on Directory
While that red indicator is spinning and spinning your users are losing interest. Unleash raw, multithreaded, asynchronous fury with FutureComponent. If you use datasources or have any components prepared using long running processes FutureComponent is here to help. With FutureComponent the user will get instant feedback with a waiting indicator where your component will be. When it has been created, it will automatically be shown to the user with no extra effort on your part. Just fire and forget. Not only does it show the user feedback instantly, but will finish quicker by allowing you to easily multithread these tasks. Normally component1 will have to be completely prepared before component2 starts being worked on, but not with your trusty friend FutureComponent.

KDubb FutureComponent version 1.0.0
null

Online