diff --git a/projects/viztool/src/java/com/samskivert/viztool/Driver.java b/projects/viztool/src/java/com/samskivert/viztool/Driver.java
index 6abc3892..8c728ccb 100644
--- a/projects/viztool/src/java/com/samskivert/viztool/Driver.java
+++ b/projects/viztool/src/java/com/samskivert/viztool/Driver.java
@@ -1,5 +1,5 @@
//
-// $Id: Driver.java,v 1.5 2001/07/17 07:18:09 mdb Exp $
+// $Id: Driver.java,v 1.6 2001/07/24 18:07:35 mdb Exp $
package com.samskivert.viztool;
@@ -31,6 +31,7 @@ public class Driver
// run ourselves on the classpath
String classpath = System.getProperty("java.class.path");
+ // System.err.println("Scanning " + classpath + ".");
ClassEnumerator enum = new ClassEnumerator(classpath);
// print out the warnings
diff --git a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java
index bfad782f..2e3ea5af 100644
--- a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java
+++ b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/ChainGroup.java
@@ -1,5 +1,5 @@
//
-// $Id: ChainGroup.java,v 1.6 2001/07/17 06:01:08 mdb Exp $
+// $Id: ChainGroup.java,v 1.7 2001/07/24 18:07:35 mdb Exp $
package com.samskivert.viztool.viz;
@@ -28,13 +28,60 @@ public class ChainGroup
// process the classes provided by our enumerator
_roots = ChainUtil.buildChains(pkgroot, iter);
+ // System.err.println(_roots.size() + " chains for " + pkg + ".");
+ }
+
+ protected ChainGroup (String pkg, ArrayList roots)
+ {
+ _pkg = pkg;
+ _roots = roots;
}
/**
- * Lays out the chains in this group and returns the total size.
+ * Returns the dimensions of this chain group. This value is only
+ * valid after layout has been called.
*/
- public Rectangle2D layout (Graphics2D gfx, double pageWidth,
- double pageHeight)
+ public Rectangle2D getBounds ()
+ {
+ return _size;
+ }
+
+ /**
+ * Sets the upper left coordinate of this group. The group itself
+ * never looks at this information, but it will be made available as
+ * the x and y coordinates of the rectangle returned by
+ * getBounds.
+ */
+ public void setPosition (double x, double y)
+ {
+ _size.setRect(x, y, _size.getWidth(), _size.getHeight());
+ }
+
+ /**
+ * Returns the page on which this group should be rendered.
+ */
+ public int getPage ()
+ {
+ return _page;
+ }
+
+ /**
+ * Sets the page on which this group should be rendered.
+ */
+ public void setPage (int page)
+ {
+ _page = page;
+ }
+
+ /**
+ * Lays out the chains in this group and returns the total size. If
+ * the layout process requires that this chain group be split across
+ * multiple pages, a new chain group containing the overflow chains
+ * will be returned. If the group fits in the allotted space, null
+ * will be returned.
+ */
+ public ChainGroup layout (
+ Graphics2D gfx, double pageWidth, double pageHeight)
{
// lay out the internal structure of our chains
ChainVisualizer clay = new CascadingChainVisualizer();
@@ -58,19 +105,28 @@ public class ChainGroup
// arrange them on the page
ElementLayout elay = new PackedColumnElementLayout();
- Rectangle2D[] dims = elay.layout(_roots, pageWidth, pageHeight);
-
- // for now we're punting and assume that no group will exceed a
- // single page in size
- double width = dims[0].getWidth();
- double height = dims[0].getHeight() + titleAscent;
+ ArrayList overflow = new ArrayList();
+ _size = elay.layout(_roots, pageWidth, pageHeight, overflow);
// make sure we're wide enough for our title
- width = Math.max(width, layout.getAdvance() + 4);
+ double width = Math.max(_size.getWidth(), layout.getAdvance() + 4);
- _size = new Rectangle2D.Double();
+ // adjust for our border and title
+ double height = _size.getHeight() + titleAscent;
_size.setRect(0, 0, width + 2*BORDER, height + 2*BORDER);
- return _size;
+
+ // if we have overflow elements, create a new chain group with
+ // these elements, remove them from our roots list and be on our
+ // way
+ if (overflow.size() > 0) {
+ // remove the overflow roots from our list
+ for (int i = 0; i < overflow.size(); i++) {
+ _roots.remove(overflow.get(i));
+ }
+ return new ChainGroup(_pkg, overflow);
+ }
+
+ return null;
}
/**
@@ -132,9 +188,17 @@ public class ChainGroup
return (Chain)_roots.get(index);
}
+ public String toString ()
+ {
+ return "[pkg=" + _pkg + ", roots=" + _roots.size() +
+ ", size=" + _size + ", page=" + _page + "]";
+ }
+
protected String _pkg;
protected ArrayList _roots;
+
protected Rectangle2D _size;
+ protected int _page;
protected static final double BORDER = 72/8;
}
diff --git a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java
index e6cebedd..24eed0a5 100644
--- a/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java
+++ b/projects/viztool/src/java/com/samskivert/viztool/hierarchy/HierarchyVisualizer.java
@@ -1,5 +1,5 @@
//
-// $Id: HierarchyVisualizer.java,v 1.7 2001/07/17 07:18:09 mdb Exp $
+// $Id: HierarchyVisualizer.java,v 1.8 2001/07/24 18:07:35 mdb Exp $
package com.samskivert.viztool.viz;
@@ -45,6 +45,7 @@ public class HierarchyVisualizer implements Printable
}
_classes.add(name);
}
+ // System.err.println("Scanned " + _classes.size() + " classes.");
// compile a list of all packages in our collection
HashSet pkgset = new HashSet();
@@ -60,18 +61,15 @@ public class HierarchyVisualizer implements Printable
_packages[i] = (String)iter.next();
}
Arrays.sort(_packages, Comparators.STRING);
+ // System.err.println("Scanned " + _packages.length + " packages.");
// now create chain groups for each package
- _groups = new ChainGroup[_packages.length];
- for (int i = 0; i < _groups.length; i++) {
+ _groups = new ArrayList();
+ for (int i = 0; i < _packages.length; i++) {
PackageEnumerator penum = new PackageEnumerator(
_packages[i], _classes.iterator(), false);
- _groups[i] = new ChainGroup(pkgroot, _packages[i], penum);
+ _groups.add(new ChainGroup(pkgroot, _packages[i], penum));
}
-
- // we'll need these for later
- _bounds = new Rectangle2D.Double[_packages.length];
- _pagenos = new int[_packages.length];
}
/**
@@ -98,12 +96,16 @@ public class HierarchyVisualizer implements Printable
// render the groups on the requested page
int rendered = 0;
- for (int i = 0; i < _groups.length; i++) {
+ for (int i = 0; i < _groups.size(); i++) {
+ ChainGroup group = (ChainGroup)_groups.get(i);
+
// skip groups not on this page
- if (_pagenos[i] != pageIndex) {
+ if (group.getPage() != pageIndex) {
continue;
}
- _groups[i].render(gfx, _bounds[i].getX(), _bounds[i].getY());
+
+ Rectangle2D bounds = group.getBounds();
+ group.render(gfx, bounds.getX(), bounds.getY());
rendered++;
}
@@ -113,26 +115,32 @@ public class HierarchyVisualizer implements Printable
public void layout (Graphics2D gfx, double x, double y,
double width, double height)
{
- double starty = x;
+ double starty = y;
int pageno = 0;
// lay out our groups
- for (int i = 0; i < _groups.length; i++) {
+ for (int i = 0; i < _groups.size(); i++) {
+ ChainGroup group = (ChainGroup)_groups.get(i);
+
// lay out the group in question
- Rectangle2D bounds = _groups[i].layout(gfx, width, height);
+ ChainGroup ngrp = group.layout(gfx, width, height);
+ // if the process of laying this group out caused it to become
+ // split across pages, insert this new group into the list
+ if (ngrp != null) {
+ _groups.add(i+1, ngrp);
+ }
// determine if we need to skip to the next page or not
- if ((y > 0) && (y + bounds.getHeight() > height)) {
+ Rectangle2D bounds = group.getBounds();
+ if ((y > starty) && (y + bounds.getHeight() > height + starty)) {
y = starty;
pageno++;
}
// assign x and y coordinates to this group
- bounds.setRect(x, y, bounds.getWidth(), bounds.getHeight());
- // and store it
- _bounds[i] = bounds;
- // also make a note of our page index
- _pagenos[i] = pageno;
+ group.setPosition(x, y);
+ // make a note of our page index
+ group.setPage(pageno);
// increment our y location
y += (bounds.getHeight() + GAP);
@@ -142,13 +150,16 @@ public class HierarchyVisualizer implements Printable
public void paint (Graphics2D gfx, int pageIndex)
{
// render the groups on the requested page
- for (int i = 0; i < _groups.length; i++) {
+ for (int i = 0; i < _groups.size(); i++) {
+ ChainGroup group = (ChainGroup)_groups.get(i);
+
// skip groups not on this page
- if (_pagenos[i] != pageIndex) {
+ if (group.getPage() != pageIndex) {
continue;
}
- _groups[i].render((Graphics2D)gfx,
- _bounds[i].getX(), _bounds[i].getY());
+
+ Rectangle2D bounds = group.getBounds();
+ group.render((Graphics2D)gfx, bounds.getX(), bounds.getY());
}
}
@@ -156,11 +167,9 @@ public class HierarchyVisualizer implements Printable
protected ArrayList _classes = new ArrayList();
protected String[] _packages;
- protected ChainGroup[] _groups;
+ protected ArrayList _groups;
protected PageFormat _format;
- protected Rectangle2D[] _bounds;
- protected int[] _pagenos;
protected static final int PAGE_WIDTH = (int)(72 * 7.5);
protected static final int PAGE_HEIGHT = (int)(72 * 10);
diff --git a/projects/viztool/src/java/com/samskivert/viztool/layout/ElementLayout.java b/projects/viztool/src/java/com/samskivert/viztool/layout/ElementLayout.java
index 8e9865e8..182defdd 100644
--- a/projects/viztool/src/java/com/samskivert/viztool/layout/ElementLayout.java
+++ b/projects/viztool/src/java/com/samskivert/viztool/layout/ElementLayout.java
@@ -1,5 +1,5 @@
//
-// $Id: ElementLayout.java,v 1.2 2001/07/17 01:54:19 mdb Exp $
+// $Id: ElementLayout.java,v 1.3 2001/07/24 18:07:35 mdb Exp $
package com.samskivert.viztool.viz;
@@ -15,12 +15,13 @@ import java.util.List;
public interface ElementLayout
{
/**
- * Lay out the supplied list of elements. Page numbers should be
- * assigned to all elements if the layout spans multiple pages.
+ * Lay out the supplied list of elements. Any elements that do not fit
+ * into the allotted space should be added to the overflow list. The
+ * supplied elements list should not be modified.
*
- * @return an array of rectangle objects representing the width and
- * height of each page that was laid out.
+ * @return the bounding dimensions of the collection of elements that
+ * were laid out.
*/
- public Rectangle2D[] layout (List elements,
- double pageWidth, double pageHeight);
+ public Rectangle2D layout (List elements, double pageWidth,
+ double pageHeight, List overflow);
}
diff --git a/projects/viztool/src/java/com/samskivert/viztool/layout/PackedColumnElementLayout.java b/projects/viztool/src/java/com/samskivert/viztool/layout/PackedColumnElementLayout.java
index f387e41d..74fe1203 100644
--- a/projects/viztool/src/java/com/samskivert/viztool/layout/PackedColumnElementLayout.java
+++ b/projects/viztool/src/java/com/samskivert/viztool/layout/PackedColumnElementLayout.java
@@ -1,5 +1,5 @@
//
-// $Id: PackedColumnElementLayout.java,v 1.4 2001/07/17 05:16:16 mdb Exp $
+// $Id: PackedColumnElementLayout.java,v 1.5 2001/07/24 18:07:35 mdb Exp $
package com.samskivert.viztool.viz;
@@ -13,19 +13,16 @@ import java.util.*;
public class PackedColumnElementLayout implements ElementLayout
{
// docs inherited from interface
- public Rectangle2D[] layout (List elements,
- double pageWidth, double pageHeight)
+ public Rectangle2D layout (List elements, double pageWidth,
+ double pageHeight, List overflow)
{
- // create a new list containing the elements whose order we can
- // manipulate willy nilly
+ // sort the elements first by height then alphabetically
Element[] elems = new Element[elements.size()];
elements.toArray(elems);
Arrays.sort(elems, HEIGHT_COMP);
// lay out the elements across the page
- ArrayList pagedims = new ArrayList();
double x = 0, y = 0, rowheight = 0, maxwidth = 0;
- int pageno = 0;
for (int i = 0; i < elems.length; i++) {
Rectangle2D bounds = elems[i].getBounds();
@@ -42,26 +39,25 @@ public class PackedColumnElementLayout implements ElementLayout
// move down to the next row
x = 0;
y += (rowheight + GAP);
- // reset our max rowheight
- rowheight = bounds.getHeight();
+ // reset our max rowheight (we set it to -GAP because we
+ // will add rowheight to our last y position to compute
+ // the total height and if no more elements are laid out,
+ // we'll want to remove that trailing gap)
+ rowheight = -GAP;
}
// make sure we fit on this page (but force placement if we're
// currently at the top margin)
if ((y > 0) && ((y + bounds.getHeight()) > pageHeight)) {
- // make a note of how big the current page is
- pagedims.add(new Rectangle2D.Double(0, 0, maxwidth, y));
- // move to the next page
- x = 0;
- y = 0;
- rowheight = bounds.getHeight();
- maxwidth = 0;
- pageno++;
+ // if we didn't fit, we go onto the overflow list
+ overflow.add(elems[i]);
+ // and continue on because maybe some shorter elements
+ // further down the list will fit
+ continue;
}
// lay this element out at our current coordinates
elems[i].setBounds(x, y, bounds.getWidth(), bounds.getHeight());
-// elems[i].setPage(pageno);
// keep track of the maximum row height
if (bounds.getHeight() > rowheight) {
@@ -78,11 +74,7 @@ public class PackedColumnElementLayout implements ElementLayout
maxwidth = x;
}
- // make a note of how big the final page is
- pagedims.add(new Rectangle2D.Double(0, 0, maxwidth, y+rowheight));
- Rectangle2D[] dims = new Rectangle2D[pagedims.size()];
- pagedims.toArray(dims);
- return dims;
+ return new Rectangle2D.Double(0, 0, maxwidth, y+rowheight);
}
protected static class HeightComparator implements Comparator