* @return A Figure.
*/
public Figure render(Object n) {
Locatable location = (Locatable) n;
final NamedObj object = location.getContainer();
EditorIcon icon;
try {
// In theory, there shouldn't be more than one
// icon, but if there are, use the last one.
List icons = object.attributeList(EditorIcon.class);
// Check to see whether there is an icon that has been created,
// but not inserted.
if (icons.size() == 0) {
XMLIcon alreadyCreated = (XMLIcon) _iconsPendingContainer
.get(object);
if (alreadyCreated != null) {
icons.add(alreadyCreated);
}
}
if (icons.size() > 0) {
icon = (EditorIcon) icons.get(icons.size() - 1);
} else {
// NOTE: This code is the same as in
// IconController.IconRenderer.
// NOTE: This used to directly create an XMLIcon within
// the container "object". However, this is not cosher,
// since we may not be able to get write access on the
// workspace. We instead use a hack supported by XMLIcon
// to create an XMLIcon with no container (this does not
// require write access to the workspace), and specify
// to it what the container will eventually be. Then
// we queue a change request to make that the container.
// Further, we have to make a record of the figure, indexed
// by the object, in case some other change request is
// executed before this gets around to setting the
// container. Otherwise, that second change request
// will result in the creation of a second figure.
icon = new XMLIcon(object.workspace(), "_icon");
icon.setContainerToBe(object);
icon.setPersistent(false);
// NOTE: Make sure this is done before the change request
// below is executed, which may be as early as when it is
// requested.
_iconsPendingContainer.put(object, icon);
// NOTE: Make sure the source of this change request is
// the graph model. Otherwise, this change request will
// trigger a redraw of the entire graph, which will result
// in another call to this very same method, which will
// result in creation of yet another figure before this
// method even returns!
final EditorIcon finalIcon = icon;
ChangeRequest request = new ChangeRequest(_model,
"Set the container of a new XMLIcon.") {
// NOTE: The KernelException should not be thrown,
// but if it is, it will be handled properly.
protected void _execute() throws KernelException {
_iconsPendingContainer.remove(object);
// If the icon already has a container, do nothing.
if (finalIcon.getContainer() != null) {
return;
}
// If the container already has an icon, do nothing.
if (object.getAttribute("_icon") != null) {
return;
}
finalIcon.setContainer(object);
}
};
request.setPersistent(false);
object.requestChange(request);