Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[udig-dev] Add Layer Wizard Performance

I noticed if I dragged a layer from the catalog onto the map it was added instantly. However if I used the Add Data wizard the layers were added immediately, but it would take another 5-10 seconds for the wizard to close. I always found this somewhat annoying, so I decided to see if I could find the source of the issue.

I discovered the problem occurs when Tools' enabled states are updated after the newly added layers is selected. Updating each tool (from the import data wizard) makes a Display.AsyncExec call for each tool, which apparently, when you have 40 or so tools, causes quite a delay. This was not a problem when dragging from the catalog as this code is already executed in the display thread.

This can be fixed by wrapping the setEnabled calls in a single Display thread so it is only done once. I accomplished this by updating the ToolManager.setEnabled function as shown below (so it is execute once for each category of tools).

If this seems reasonable to others I can contribute the change back to the uDig master easily enough.

Emily

private void setEnabled( final IMap map, final Collection<? extends ToolCategory> categories) {
  if(selectedLayerListener == null)
    selectedLayerListener = new EditManagerListener();

  selectedLayerListener.setCurrentMap(map);

    //One listener is enough. Say NO to listeners hell:)
  if(!map.getEditManager().containsListener(selectedLayerListener))
    map.getEditManager().addListener(selectedLayerListener);

  PlatformGIS.syncInDisplayThread(new Runnable(){
    @Override
    public void run() {
      ILayer selectedLayer = map.getEditManager().getSelectedLayer();
			
      for( ToolCategory cat : categories ) {
        for( ModalItem item : cat ) {
          OpFilter enablesFor = item.getEnablesFor();
          // JG: I don't trust asserts in production code!
          // assert enablesFor instanceof LazyOpFilter;
          if( !(enablesFor instanceof LazyOpFilter) ){
            enablesFor = new LazyOpFilter(item, enablesFor);
          }

          boolean accept = enablesFor.accept(selectedLayer);
          item.setEnabled(accept);
        }
      }
  }});
}


Back to the top