graph.setModel(model);
setProjectController(mediator);
setDataDomain(domain);
GraphLayoutCache view = new GraphLayoutCache(model, new DefaultCellViewFactory());
graph.setGraphLayoutCache(view);
graph.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if (e.isPopupTrigger()) {
Object selected = graph.getSelectionCell();
if (selected != null && selected instanceof DefaultGraphCell) {
Object userObject = ((DefaultGraphCell) selected).getUserObject();
if (userObject instanceof EntityCellMetadata) {
showPopup(e.getPoint(), ((EntityCellMetadata) userObject)
.fetchEntity());
}
}
}
}
});
graph.addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
graph.setScale(graph.getScale()
/ Math.pow(ZOOM_FACTOR, e.getWheelRotation()));
}
});
entityCells = new HashMap<String, DefaultGraphCell>();
createdObjects = new ArrayList<DefaultGraphCell>();
relCells = new HashMap<String, DefaultEdge>();
/**
* an array for entities that are not connected to anyone. We add them separately
* so that layout doesn't touch them
*/
List<DefaultGraphCell> isolatedObjects = new ArrayList<DefaultGraphCell>();
/**
* 1. Add all entities
*/
for (DataMap map : domain.getDataMaps()) {
DefaultGraphCell mapCell = new DefaultGraphCell();
createdObjects.add(mapCell);
for (Entity entity : getEntities(map)) {
DefaultGraphCell cell = createEntityCell(entity);
// mapCell.add(cell);
// cell.setParent(mapCell);
List<DefaultGraphCell> array = !isIsolated(domain, entity)
? createdObjects
: isolatedObjects;
array.add(cell);
array.add((DefaultGraphCell) cell.getChildAt(0)); // port
}
}
/**
* 2. Add all relationships
*/
for (DataMap map : domain.getDataMaps()) {
for (Entity entity : getEntities(map)) {
DefaultGraphCell sourceCell = entityCells.get(entity.getName());
postProcessEntity(entity, sourceCell);
}
}
view.insert(createdObjects.toArray());
if (doLayout) {
JGraphFacade facade = new JGraphFacade(graph);
JGraphOrganicLayout layout = new JGraphOrganicLayout();
layout.setNodeDistributionCostFactor(5000000000000.0);
layout.setEdgeLengthCostFactor(1000);
layout.setEdgeCrossingCostFactor(1000000);
layout.setOptimizeBorderLine(false);
layout.setOptimizeEdgeDistance(false);
// JGraphSimpleLayout layout = new
// JGraphSimpleLayout(JGraphSimpleLayout.TYPE_TILT, 4000, 2000);
layout.run(facade);
Map nested = facade.createNestedMap(true, true); // Obtain a map of the
// resulting attribute
// changes from the facade
edit(nested); // Apply the results to the actual graph
}
/**
* Adding isolated objects
*
* We're placing them so that they will take maximum space in left top corner. The
* sample order is below:
*
* 1 2 6 7... 3 5 8 ... 4 9... 10 ...
*/
if (isolatedObjects.size() > 0) {
int n = isolatedObjects.size() / 2; // number of isolated entities
int x = (int) Math.ceil((Math.sqrt(1 + 8 * n) - 1) / 2); // side of triangle
Dimension pref = graph.getPreferredSize();
int dx = pref.width / 2 / x; // x-distance between entities
int dy = pref.height / 2 / x; // y-distance between entities
int posX = dx / 2;
int posY = dy / 2;
int row = 0;
for (int isolatedIndex = 0; isolatedIndex < isolatedObjects.size();) {
for (int i = 0; isolatedIndex < isolatedObjects.size() && i < x - row; i++) {
GraphConstants.setBounds(isolatedObjects
.get(isolatedIndex)
.getAttributes(), new Rectangle2D.Double(
pref.width - posX,
pref.height - 3 * posY / 2,
10,
10));
isolatedIndex += 2; // because every 2nd object is port
posX += dx;
}
posX = dx / 2;
posY += dy / 2;
row++;
}
}
view.insert(isolatedObjects.toArray());
graph.getModel().addUndoableEditListener(this);
}