/** Automatically layout this RenderableComplex. */ public void layout() { if (hideComponents) { return; // Don't do layout for hiding components } List list = getComponents(); if (list == null || list.size() == 0) return; int size = list.size(); int c = (int) Math.ceil(Math.sqrt(size)); Node rs[][] = new Node[c][c]; int index = 0; // Distribute for (int i = 0; i < c && index < size; i++) { // Row for (int j = 0; j < c && index < size; j++) { // Col rs[i][j] = (Node) list.get(index); index++; } } // Assign positions // Original position int x = position.x; int y = position.y; Dimension layerSize = new Dimension(); boolean isDone = false; Node r = null; Rectangle bounds = null; int dx = 0; int x0 = 0; int y0 = 0; for (int i = 0; i < c && !isDone; i++) { // Row // Get the center for each layer layerSize.width = 0; layerSize.height = 0; for (int j = 0; j < c; j++) { // Col if (rs[i][j] == null) { isDone = true; break; } r = rs[i][j]; if (r.getStoiBounds() != null) { layerSize.width += r.getStoiBounds().width; } if (r.getBounds() != null) { layerSize.width += r.getBounds().width; if (r.getBounds().height > layerSize.height) layerSize.height = r.getBounds().height; } else { layerSize.width += Node.getNodeWidth(); layerSize.height += 20; // arbitrarily } } if (layerSize.width == 0) // nothing is layered. break; // Assign positions to this layer. x = -layerSize.width / 2 + position.x; y += layerSize.height / 2; for (int j = 0; j < c; j++) { if (rs[i][j] == null) break; r = rs[i][j]; // All are nodes dx = 0; if (r.getStoiBounds() != null) dx = r.getStoiBounds().width; if (r.getBounds() != null) dx += r.getBounds().width / 2; else dx += Node.getNodeWidth() / 2; x += dx; x0 = r.position.x; y0 = r.position.y; // Need to call move to change positions of components in subcomplexes. r.move(x - x0, y - y0); dx += 1; // A little cushion x += dx; // Move to the right end } y += layerSize.height / 2 + 2; // Make subunits look together } // Want to keep at the original position x0 = position.x; y0 = position.y; setBoundsFromComponents(); dx = x0 - position.x; int dy = y0 - position.y; move(dx, dy); // Should not call the following method since it will invalidate the // layout results. invalidateTextBounds(); }