English

How To: Avoid displaying multiple 'finish' events using Display Listener

Summary

The map display process may take place asynchronously, that is, in multiple threads simultaneously to improve the performance. In such a case, one finish event is invoked when each display thread is finished. This means that the application may invoke a finish method of the associated DisplayListener more than once.

Therefore, if the DisplayListener's finish method is overridden to perform a certain function, this function may be called multiple times, although one would like to call it just once when the map is completely displayed.

Procedure

To make sure that all display threads are terminated before some function is performed, keep track of every start, finish, and cancel event of the DisplayListener. This can be done by creating a custom Listener by extending the DisplayAdapter class.

1. Create a new class that extends DisplayAdapter.

2. Create a counter method to record the events of the DisplayAdapter.

3. Adjust the counter accordingly for each time a thread starts, stops, or is cancelled.

4. Display a 'finished' message when the map is completely displayed.

The complete code is shown below.


Code:

class MyListener extends DisplayAdapter{

int m_requesting = 0;
int count=0;

// When a drawing thread is started, the method is called.
public void start(com.esri.mo.map.dpy.DisplayEvent de){
setCounter(+1);
// System.out.println("Start()...");

}

// When a drawing thread is cancelled, the method is called.
public void cancel(com.esri.mo.map.dpy.DisplayEvent de) {
setCounter(-1);
}

public void finish(com.esri.mo.map.dpy.DisplayEvent de) {
super.finish(de);
setCounter(-1);
}

public void extent(com.esri.mo.map.dpy.DisplayEvent e) {

}

private synchronized void setCounter(int change) {
if (change > 0 && m_requesting == 0) {
// Do nothing.
}
m_requesting += change;
if (change < 0 && m_requesting == 0) {
System.out.println("finished");
// Call the function here.
}
}

}

Note:
In MapObjects-Java 2.0, the finish event is invoked only once after the data is completely displayed. So there is no need to keep track of individual threads for this version.



Note:
The above code is suitable for a local data source. If using data from ArcIMS Feature Server, it might still return multiple 'finished' messages. In such a case, make sure data is completely downloaded to the client before performing the map display. DataListener can be used to manage the DataEvents.