Window.open(Resource) only working once

Hi,

I am trying to use Window.open(Resource) as a way of downloading
executable scripts to the client browser. I found that it works ok once,
but then all browser <==> server interaction stops. I posted sample
code that shows this problem.

Server: ITMill 5.3.1, JBoss 4.0.5, Ubuntu 9.04
Client IE7 and FF3, Windows XP, SP2 (same result with both).

Any ideas on what is wrong ?

Thanks
Andrew



package sample.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import com.itmill.toolkit.Application;
import com.itmill.toolkit.terminal.StreamResource;
import com.itmill.toolkit.ui.Button;
import com.itmill.toolkit.ui.Panel;
import com.itmill.toolkit.ui.ProgressIndicator;
import com.itmill.toolkit.ui.Window;
import com.itmill.toolkit.ui.Button.ClickEvent;
import com.itmill.toolkit.ui.Button.ClickListener;

public class OpenResourceTestApplication extends Application
{
	private Window mainWindow = new Window("TestApplication Window");
	private Button button1;

	@Override
	public void init()
	{
		button1 = new Button("Button1");
		button1.setEnabled(true);

		final ProgressIndicator pi = new ProgressIndicator() {
			@Override
			public boolean isEnabled()
			{
				return true;
			}
		};

		pi.setIndeterminate(false);
		pi.setVisible(false);
		pi.setPollingInterval(1000);

		Panel panel = new Panel();
		panel.addComponent(pi);
		mainWindow.addComponent(panel);

		button1.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event)
			{
				try
				{
					CustomResource resource = new CustomResource("test.bat",
						"ECHO \"hello\"\r\nPAUSE\r\n", "application/x-msdos-program",
						OpenResourceTestApplication.this);
					mainWindow.open(resource);
				}
				catch (IOException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		});

		mainWindow.getLayout().setSizeFull();
		mainWindow.setSizeFull();
		mainWindow.addComponent(button1);
		setMainWindow(mainWindow);
	}

	public class CustomResource extends StreamResource
	{
		private final String mimeType;

		public CustomResource(final String basename,
			final String contents,
			final String mimeType,
			final Application application) throws IOException
		{
			super(make(contents), basename, application);
			this.mimeType = mimeType;
		}

		@Override
		public String getMIMEType()
		{
			return mimeType;
		}

		@Override
		public long getCacheTime()
		{
			// Every resource will have different contents, so make
			// sure the browser does not cache it.
			return 0;
		}
	}

	private static CustomStream make(String textContents) throws IOException
	{
		final ByteArrayOutputStream out = new ByteArrayOutputStream();
		out.write(textContents.getBytes());
		final ByteArrayInputStream inputStream = new ByteArrayInputStream(out.toByteArray());
		final CustomStream stream = new CustomStream(inputStream);
		return stream;
	}

	/**
	 * Helper class to map an InputStream to a StreamResource.StreamSource.
	 */
	private static class CustomStream implements StreamResource.StreamSource
	{
		private InputStream inputStream;

		public CustomStream(InputStream inputStream)
		{
			super();
			this.inputStream = inputStream;
		}

		public InputStream getStream()
		{
			return inputStream;
		}
	}
}

Hi,

I tested with ITMill 5.4, and get the same result.

Can anyone suggest what I might be doing wrong, or is anyone aware if this is a known problem ?

Thanks
Andrew

Hi Andrew,

The problem seems to be that you assign the test.bat resource that you create to the main window of the application. This causes the application to now use the test.bat as the main window, replacing the current content (server-side). Since test.bat doesn’t render anything, and this is Ajax, the client still shows the last things visible even though the button is no longer attached to anything. Phew, that was a mouthful…

In other words, mainWindow.open(resource) causes the main window contents to be replaced by the resource you supply → the button is thrown away.

If you change mainWindow.open(resource) to, for example, mainWindow.open(resource, “_new”), the resource is opened in a new window. This might be blocked by popup blockers and such, but at least the resource is downloaded and you still have a working layout in your main window.

Another way to do it would be to use a vaadin subwindow instead of the main window (or native window popup), e.g.

Window win = new Window("my resource window");
win.open(resource);
mainWindow.addWindow(win);

This way you avoid the popup blockers, but you end up with a window that the user needs to close.

Hope you’re not running any “format c:” commands in your batch files :stuck_out_tongue:

/Jonatan

Jonatan,

Great - that works !!!

I think the thing that I didn’t realize, was that the Window function:

public void open(Resource resource, String windowName)

didn’t say the windowName was the same as the targetName, and
would trigger the W3C related behavior in the client browser.

I used “_blank”, because it is standard, and seems to work as well as “_new”.

Some extra documentation similar to the following might be helpful for the Window.open() functions.

“_blank” - Always opens the link in a new window or tab - if you click the link several times you’ll end up with several new windows or tabs

“_self, _parent or _top” - Replaces the current page with the linked content, unless it’s a download in which case the download will usually start.

name - If an existing window or tab with the same name exists, the link will load in to it, otherwise a new window or tab will be created - if you click the link several times you’ll still only have one new window or tab.

Many thanks
Andrew

Great suggestion! I created a ticket for this
#3047

/Jonatan