Closing window from inside a thread

Hi I have a problem with getting a modal window to close.

I have a button that when clicked performs a task which takes about 10 seconds. During this time the user should be prevented from inetracting with the application. To achieve this I have the button’s action listener create a modal window, add it to the main window of the application and then start a background thread to do the actual task.

Here is my code for this:


//display the modal progress window
ControlApplication.getInstance().getMainWindow().addWindow(getProgressDialog());
		
//start the capture (it will close the dialog)
CaptureThread thread = new CaptureThread(DyteqtaControlApplication.getInstance());
thread.start();

The getProgressDialog() is a lazy intialiser fro the actual window subclass which contains the modal dialog UI (essentially just a message saying ’ Wait, stuff is happening…')

As you can see from the “ControlApplication.getInstance()” I am using the
thread local application pattern
.

The CaptureThread class is a inner class which simply does the task and then attempts to close the progress dialog window, the relevant code is:

@Override
	public void run() {
			
		//get 5 seconds of data from the DAQ card
		logger.debug("Starting data acquisition...");
		double[] data = DAQTaskControl.acquireData(5000);
		logger.debug("...data acquisition complete");
		
		//create a new entry for the capture list
		CaptureData newCaptureData = new CaptureData("C-"+dataSource.size(), TIME_FORMATTER.format(new Date())); 
		newCaptureData.setData(data);
		logger.debug("Created new data set");
			
		//add list entry to the display list
		dataSource.addBean(newCaptureData);
		logger.debug("Added capture to list");
			
		//close the modal progress dialog
		application.getMainWindow().removeWindow(getProgressDialog());
		logger.debug("Closed modal progress dialog");
			
	}

I have to pass in the ControlApplication instance to the CaptureThread instance as the thread local pattern gets screwed-up if I ask for the application instance inside the new background thread (as expected).

My problem is this; the progress dialog window never gets closed. I can see in the log output that the expected operations have been performed, specifically I can see the line “Closed modal progress dialog” indicating that the code “application.getMainWindow().removeWindow(getProgressDialog());” has been executed, but the progress window never gets closed. I have tried an alternative methiod where I override the “close” method in the ProgressDialog window class to call the protected close() method of the Window class:

@Override
public void close(){
	super.close();
}

and then calling close on the progress window inside the “run()” method:

//close the modal progress dialog
getProgressDialog().close();
logger.debug("Closed modal progress dialog");

But that doesn’t close it either.

I’m stuck now, can anyone offer any help or suggestions?

Thanks in advance.

Hi Simon,

if you perform UI modifications in a background thread, these modifications are not automatically sent to the browser, since Vaadin doesn’t have any server push mechanism. You can work around this limitation by adding a
ProgressIndicator
that makes polling requests to the server.

By the way, you can also use an
InheritableThreadLocal
instead of a plain ThreadLocal to gain access to the ThreadLocal value of the parent thread within a child thread.

  • Teemu

Thanks for the info, its now working as required :slight_smile: