![]() |
|
|||||||
| Development Help Help for building applications or diagnosing problems with WWJ |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 | |
|
Junior Member
Join Date: Jul 2012
Location: New York
Posts: 7
![]() |
I created a class that uses MeasureTool to create and modify shapes on a new layer over WorldWind. The shapes (circle,ellipse,rectangle,square,polygon ) are created as the shapes themselves using MeasureTool and are then saved as as bounds using the getPositions() method in MeasureTool.
When modifying circles and ellipses though, I get a concurrentmodificationexception about 50% of the time when trying to move a point. It does not seem to be from my code - but from WorldWinds. Quote:
Code:
// create or modify the bounds
if (activeBounds == null)
{
activeBounds = BoundUtils.createManagedBounds(boundsName.getText(), getMeasureTool().getPositions());
}
else
{
activeBounds = BoundUtils.modifyManagedBounds(activeBounds, boundsName.getText(), getMeasureTool().getPositions());
}
|
|
|
|
|
|
|
#2 |
|
WW Dev. Team
Join Date: Sep 2010
Location: Boston, MA, USA
Posts: 325
![]() |
You need to modify the bounds on the Event Dispatch Thread. Using Swing, you can do this using the SwingUtilities.invokeLater:
Code:
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
// Modify bounds here
}
});
|
|
|
|
|
|
#3 |
|
Junior Member
Join Date: Jul 2012
Location: New York
Posts: 7
![]() |
I've tried to modify the bounds on the Event Dispatch Thread like you said, but the problem persists.
Is it possible that it has something to do with WW's code? I frequently get this exception as well: Jul 30, 2012 10:59:32 AM gov.nasa.worldwind.layers.RenderableLaye r doPreRender SEVERE: Exception while pre-rendering Renderable |
|
|
|
|
|
#4 |
|
WW Dev. Team
Join Date: Sep 2010
Location: Boston, MA, USA
Posts: 325
![]() |
You must somehow be modifying the bounds off of the EDT. That's the only way a ConcurrentModificationException could happen. The exception in preRender is probably the same exception (the ConcurrentModificationException is thrown during preRendering), but you could put a break point or log statement in RenderableLayer.doPreRender to confirm that.
Can you provide a simple example that demonstrates the problem? |
|
|
|
|
|
#5 |
|
Junior Member
Join Date: Jul 2012
Location: New York
Posts: 7
![]() |
A log already exists in RenderableLayer.doPreRender, which is where it's coming from.
Here is some of the code from the class that creates and modifies bounds. The exceptions only occur when there are a lot of points (e.g., compared to squares which have 5 points) Maybe there's an alternative way to do this to avoid the exception? Code:
public class ApplicationMeasureToolPanel extends BaseMeasureToolPanel
{
/**
* Note: BaseMeasureToolPanel is an SWT control panel for WorldWind's MeasureTool. Based on NASA's
* MeasureToolPanel.
*/
// the active Bounds is the one that we're currently editing
private Bounds activeBounds = null;
private Text boundsName;
private Label messageLabel1;
private Label messageLabel2;
public ApplicationMeasureToolPanel(Composite parent, WorldWindowContainer worldWindow,
final MeasureTool measureTool)
{
super(parent, worldWindow, measureTool);
}
/**
* Shape types that are usable by MeerCAT's Bounds Tool
*/
@Override
protected void hookShapeTypes()
{
getShapeTypes().put("Polygon", MeasureTool.SHAPE_POLYGON);
getShapeTypes().put("Circle", MeasureTool.SHAPE_CIRCLE);
getShapeTypes().put("Ellipse", MeasureTool.SHAPE_ELLIPSE);
getShapeTypes().put("Square", MeasureTool.SHAPE_SQUARE);
getShapeTypes().put("Quad", MeasureTool.SHAPE_QUAD);
}
/**
* Set the bounds to be modified upon pressing Save
*/
public void setActiveBounds(final Bounds bounds)
{
activeBounds = bounds;
ARKUtils.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
// show the points if there are any
if (activeBounds.hasPoints())
{
getMeasureTool().setPositions(activeBounds.getPositions());
// setPositions() makes the measure tool switch to polygon
// mode. Change the selected type in the dropdown so the
// user doesn't get surprised
getShapeCombo().setText("Polygon");
}
else
getMeasureTool().clear();
// show the name
boundsName.setText(activeBounds.getName());
}
});
}
/**
* Reset any part of the UI that this specific subclass handles
*/
@Override
public void resetMeasureTool(boolean suppressEvents)
{
// clear the active Location
activeBounds = null;
// clear the name field
ARKUtils.getDisplay().asyncExec(new Runnable()
{
@Override
public void run()
{
// check if the tool is disposed first because we
// also reset upon disposal
if (!getControl().isDisposed())
{
messageLabel1.setText("");
messageLabel2.setText("");
boundsName.setText("");
}
}
});
// parent handles the rest
super.resetMeasureTool(suppressEvents);
}
/**
* Provide options for saving Bounds to the database
*/
@Override
protected void hookControls()
{
createSetupGroup();
createMetricGroup();
createStartStopGroup();
createSaveGroup();
createMessageGroup();
createHelpGroup();
}
/**
* Provide options to set the Bounds name and set the shape type
*/
private void createSetupGroup()
{
Composite parent = getControl();
// Setup Group
Group setupGroup = new Group(parent, SWT.NONE);
setupGroup.setText("Setup Bounds");
setupGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
setupGroup.setLayout(new GridLayout(2, false));
Label nameLabel = new Label(setupGroup, SWT.NONE);
nameLabel.setText("Name");
nameLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
boundsName = new Text(setupGroup, SWT.BORDER);
boundsName.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
// add the shape controls from the parent class
createShapeControls(setupGroup);
}
/**
* Provide options to save the Bounds to the database
*/
private void createSaveGroup()
{
Composite parent = getControl();
// Save Group
Composite saveGroup = new Composite(parent, SWT.NONE);
saveGroup.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
saveGroup.setLayout(new GridLayout(2, true));
final Button cancelButton = new Button(saveGroup, SWT.NONE);
cancelButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
cancelButton.setText("Cancel");
final Button saveButton = new Button(saveGroup, SWT.NONE);
saveButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, true, 1, 1));
saveButton.setText("Save");
saveGroup.getShell().setDefaultButton(saveButton);
// handle the cancel button
cancelButton.addListener(SWT.Selection, new Listener()
{
@Override
public void handleEvent(Event event)
{
resetMeasureTool(false);
// close the tool
MeerCatEventHelper.fireEvent(MeerCatEventManagerFactory.BOUNDS_TOOL, this,
new BoundsToolEventArgs(BoundsToolAction.HIDE, null));
}
});
// handle the save button
saveButton.addListener(SWT.Selection, new Listener()
{
@Override
public void handleEvent(Event event)
{
if (getMeasureTool().getPositions().isEmpty())
{
messageLabel1.setText("No bounds provided.");
messageLabel2.setText("Draw some points.");
return;
}
// make sure name is not null
if (boundsName.getText().isEmpty())
{
messageLabel1.setText("No name provided.");
messageLabel2.setText("Choose a name.");
return;
}
// make sure name is not taken
IMeerCATOrmService ormService = MeerCATOrmServiceFactory.createMeerCatOrmService();
boolean exists = ormService.boundsExistsWithName(boundsName.getText());
ormService.close();
if (activeBounds == null && exists)
{
messageLabel1.setText("Name already exists.");
messageLabel2.setText("Choose a different name.");
return;
}
// create or modify the bounds
if (activeBounds == null)
{
activeBounds = BoundUtils.createManagedBounds(boundsName.getText(),
getMeasureTool().getPositions());
}
else
{
activeBounds = BoundUtils.modifyManagedBounds(activeBounds,
boundsName.getText(), getMeasureTool().getPositions());
}
resetMeasureTool(false);
// close the tool
MeerCatEventHelper.fireEvent(MeerCatEventManagerFactory.BOUNDS_TOOL, this,
new BoundsToolEventArgs(BoundsToolAction.HIDE, null));
// tell the bounds view to refresh
MeerCatEventHelper.fireEvent(MeerCatEventManagerFactory.BOUNDS_UPDATE, this,
new EventArgs());
}
});
}
/**
* Verify that the active bounds are managed. Clear if not.
*/
public void verifyBounds()
{
// see if the active location still exists
if (activeBounds != null)
{
IMeerCATOrmService ormService = MeerCATOrmServiceFactory.createMeerCatOrmService();
Bounds managedBounds = ormService.getEntityManagedVersion(activeBounds);
// clear the tool if it doesn't exist
if (managedBounds == null)
resetMeasureTool(false);
}
}
}
|
|
|
|
|
|
#6 |
|
Junior Member
Join Date: Jul 2012
Location: New York
Posts: 7
![]() |
Instead of modifying the bounds myself, I let WorldWind modify it for me since the code already exists. All the above code does is create the shapes, and save them as polygons.
|
|
|
|
|
|
#7 |
|
WW Dev. Team
Join Date: Sep 2010
Location: Boston, MA, USA
Posts: 325
![]() |
Are you using the SWT/AWT bridge to use World Wind in an SWT app? I see that you're using asyncExec to manipulate the bounds. This will run the update on the SWT event thread, but World Wind is rendering on the AWT event thread (as indicated by the stack trace in your first post). Have you tried using SwingUtilities.invokeLater to run the bounds updates on the AWT event thread?
|
|
|
|
|
|
#8 |
|
Junior Member
Join Date: Jul 2012
Location: New York
Posts: 7
![]() |
Yes, I'm using the SWT/AWT bridge, and I've also tried using SwingUtilities.invokeLater to run the bounds updates... it only causes the exception to occur more frequently.
|
|
|
|
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Calculating bounds of map objects | incubus | Technical Support | 2 | 06-09-2012 06:42 AM |
| Occassional index out of bounds in setting markers | jas511 | Bug Reports | 12 | 06-03-2011 12:57 AM |
| Modifying LineBuilder | Unregistered | Development Help | 1 | 06-26-2009 01:27 AM |
| Modifying SurfaceTileRenderer.renderTiles to avoid multitexturing | Unregistered | Development Help | 0 | 05-15-2009 06:05 PM |
| Metes and Bounds description:utility | tommoran | Add-ons & Scripts | 0 | 07-07-2006 08:55 PM |