Use sensible margins; added support for rendering interfaces implemented
and inner classes declared within the box for the appropriate class. git-svn-id: https://samskivert.googlecode.com/svn/trunk@193 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: Driver.java,v 1.4 2001/07/17 06:01:08 mdb Exp $
|
||||
// $Id: Driver.java,v 1.5 2001/07/17 07:18:09 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool;
|
||||
|
||||
@@ -49,16 +49,24 @@ public class Driver
|
||||
if (print) {
|
||||
// we use the print system to render things
|
||||
PrinterJob job = PrinterJob.getPrinterJob();
|
||||
job.setPrintable(viz);
|
||||
|
||||
// pop up a dialog to format our pages
|
||||
// PageFormat format = job.pageDialog(job.defaultPage());
|
||||
PageFormat format = job.defaultPage();
|
||||
|
||||
// use sensible margins
|
||||
Paper paper = new Paper();
|
||||
paper.setImageableArea(72*0.5, 72*0.5, 72*7.5, 72*10);
|
||||
format.setPaper(paper);
|
||||
|
||||
// pop up a dialog to control printing
|
||||
job.printDialog();
|
||||
|
||||
// use our configured page format
|
||||
job.setPrintable(viz, format);
|
||||
|
||||
try {
|
||||
// invoke the printing process
|
||||
job.print();
|
||||
} catch (PrinterException pe) {
|
||||
pe.printStackTrace(System.err);
|
||||
|
||||
+80
-5
@@ -1,11 +1,12 @@
|
||||
//
|
||||
// $Id: CascadingChainVisualizer.java,v 1.7 2001/07/17 06:01:08 mdb Exp $
|
||||
// $Id: CascadingChainVisualizer.java,v 1.8 2001/07/17 07:18:09 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.font.TextLayout;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.geom.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -38,6 +39,24 @@ public class CascadingChainVisualizer
|
||||
// the header will be the name of this chain surrounded by N
|
||||
// points of space and a box
|
||||
Rectangle2D bounds = getTextBox(gfx, layout);
|
||||
|
||||
// add our inner classes and interface implementations, but only
|
||||
// if we're not an out of package class
|
||||
if (chain.inPackage()) {
|
||||
String[] impls = chain.getImplementsNames();
|
||||
for (int i = 0; i < impls.length; i++) {
|
||||
bounds = accomodate(bounds, impls[i],
|
||||
FontPicker.getImplementsFont(),
|
||||
gfx.getFontRenderContext());
|
||||
}
|
||||
String[] decls = chain.getDeclaresNames();
|
||||
for (int i = 0; i < decls.length; i++) {
|
||||
bounds = accomodate(bounds, decls[i],
|
||||
FontPicker.getDeclaresFont(),
|
||||
gfx.getFontRenderContext());
|
||||
}
|
||||
}
|
||||
|
||||
double maxwid = bounds.getWidth();
|
||||
|
||||
// the children will be below the name of this chain and inset by
|
||||
@@ -62,6 +81,17 @@ public class CascadingChainVisualizer
|
||||
chain.setBounds(cbounds.getX(), cbounds.getY(), maxwid, y);
|
||||
}
|
||||
|
||||
protected Rectangle2D accomodate (Rectangle2D bounds, String name,
|
||||
Font font, FontRenderContext frc)
|
||||
{
|
||||
TextLayout layout = new TextLayout(name, font, frc);
|
||||
Rectangle2D tbounds = layout.getBounds();
|
||||
bounds.setRect(bounds.getX(), bounds.getY(),
|
||||
Math.max(bounds.getWidth(), tbounds.getWidth()+INSET),
|
||||
bounds.getHeight() + tbounds.getHeight());
|
||||
return bounds;
|
||||
}
|
||||
|
||||
// docs inherited from interface
|
||||
public void renderChain (Chain chain, Graphics2D gfx)
|
||||
{
|
||||
@@ -76,16 +106,55 @@ public class CascadingChainVisualizer
|
||||
TextLayout layout = new TextLayout(chain.getName(), font,
|
||||
gfx.getFontRenderContext());
|
||||
|
||||
// stroke a box that will contain the name
|
||||
Rectangle2D tbounds = getTextBox(gfx, layout);
|
||||
double dx = -tbounds.getX(), dy = -tbounds.getY();
|
||||
tbounds.setRect(x, y, tbounds.getWidth(), tbounds.getHeight());
|
||||
gfx.draw(tbounds);
|
||||
double maxwid = tbounds.getWidth();
|
||||
|
||||
// now draw the name
|
||||
// draw the name
|
||||
layout.draw(gfx, (float)(x + dx + HEADER_BORDER),
|
||||
(float)(y + dy + HEADER_BORDER));
|
||||
|
||||
// draw the interface and inner class info, but only if we're not
|
||||
// an out of package class
|
||||
double ix = x + HEADER_BORDER + INSET;
|
||||
double iy = y + tbounds.getHeight() - HEADER_BORDER;
|
||||
|
||||
if (chain.inPackage()) {
|
||||
String[] impls = chain.getImplementsNames();
|
||||
for (int i = 0; i < impls.length; i++) {
|
||||
TextLayout ilay =
|
||||
new TextLayout(impls[i], FontPicker.getImplementsFont(),
|
||||
gfx.getFontRenderContext());
|
||||
Rectangle2D ibounds = ilay.getBounds();
|
||||
double newwid = ibounds.getWidth() + 2*HEADER_BORDER + INSET;
|
||||
if (newwid > maxwid) {
|
||||
maxwid = newwid;
|
||||
}
|
||||
ilay.draw(gfx, (float)(ix - ibounds.getX()),
|
||||
(float)(iy - ibounds.getY()));
|
||||
iy += ibounds.getHeight();
|
||||
}
|
||||
|
||||
String[] decls = chain.getDeclaresNames();
|
||||
for (int i = 0; i < decls.length; i++) {
|
||||
TextLayout ilay =
|
||||
new TextLayout(decls[i], FontPicker.getDeclaresFont(),
|
||||
gfx.getFontRenderContext());
|
||||
Rectangle2D ibounds = ilay.getBounds();
|
||||
double newwid = ibounds.getWidth() + 2*HEADER_BORDER + INSET;
|
||||
if (newwid > maxwid) {
|
||||
maxwid = newwid;
|
||||
}
|
||||
ilay.draw(gfx, (float)(ix - ibounds.getX()),
|
||||
(float)(iy - ibounds.getY()));
|
||||
iy += ibounds.getHeight();
|
||||
}
|
||||
}
|
||||
|
||||
// stroke a box that will contain the name
|
||||
tbounds.setRect(x, y, maxwid, iy - y + HEADER_BORDER);
|
||||
gfx.draw(tbounds);
|
||||
|
||||
// render our connecty lines
|
||||
ArrayList kids = chain.getChildren();
|
||||
if (kids.size() > 0) {
|
||||
@@ -139,4 +208,10 @@ public class CascadingChainVisualizer
|
||||
* The number of points of spacing between each child chain.
|
||||
*/
|
||||
protected static final double GAP = 4;
|
||||
|
||||
/**
|
||||
* The number of points that interfaces and inner class declarations
|
||||
* are indented.
|
||||
*/
|
||||
protected static final double INSET = 3;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: Chain.java,v 1.4 2001/07/17 01:54:19 mdb Exp $
|
||||
// $Id: Chain.java,v 1.5 2001/07/17 07:18:09 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
@@ -16,10 +16,11 @@ public class Chain implements Element
|
||||
/**
|
||||
* Constructs a chain with the specified class as its root.
|
||||
*/
|
||||
public Chain (String name, Class root)
|
||||
public Chain (String name, Class root, boolean inpkg)
|
||||
{
|
||||
_name = name;
|
||||
_root = root;
|
||||
_inpkg = inpkg;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,6 +40,15 @@ public class Chain implements Element
|
||||
return _root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the class represented by this point in the chain is
|
||||
* in the package we are visualizing, false if it is not.
|
||||
*/
|
||||
public boolean inPackage ()
|
||||
{
|
||||
return _inpkg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the class that forms the root of this chain.
|
||||
*/
|
||||
@@ -47,6 +57,77 @@ public class Chain implements Element
|
||||
return _root.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of the interfaces implemented by this class.
|
||||
*/
|
||||
public String[] getImplementsNames ()
|
||||
{
|
||||
Class[] ifaces = _root.getInterfaces();
|
||||
String[] names = new String[ifaces.length];
|
||||
String pkg = ChainUtil.pkgFromClass(_root.getName());
|
||||
|
||||
for (int i = 0; i < ifaces.length; i++) {
|
||||
String name = ifaces[i].getName();
|
||||
String ipkg = ChainUtil.pkgFromClass(name);
|
||||
if (pkg.equals(ipkg)) {
|
||||
names[i] = ChainUtil.nameFromClass(name);
|
||||
} else {
|
||||
names[i] = removeOverlap(pkg, name);
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
protected static String removeOverlap (String pkg, String name)
|
||||
{
|
||||
// strip off package elements until we've eliminated all but one
|
||||
// level of overlap
|
||||
String overlap = "";
|
||||
int didx;
|
||||
|
||||
while ((didx = pkg.indexOf(".", overlap.length()+1)) != -1) {
|
||||
// see if this chunk still overlaps
|
||||
String prefix = pkg.substring(0, didx);
|
||||
if (name.startsWith(prefix)) {
|
||||
overlap = prefix;
|
||||
} else {
|
||||
// we've stopped overlapping, we need to back up one
|
||||
// element and then we're good to go
|
||||
if ((didx = overlap.lastIndexOf(".")) == -1) {
|
||||
overlap = "";
|
||||
} else {
|
||||
overlap = overlap.substring(0, didx);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if there's an overlap, remove it
|
||||
if (overlap.length() > 0) {
|
||||
return ".." + name.substring(overlap.length());
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the names of the inner classes declared by this class.
|
||||
*/
|
||||
public String[] getDeclaresNames ()
|
||||
{
|
||||
Class[] decls = _root.getDeclaredClasses();
|
||||
String[] names = new String[decls.length];
|
||||
|
||||
for (int i = 0; i < decls.length; i++) {
|
||||
String name = decls[i].getName();
|
||||
int didx = name.indexOf("$");
|
||||
names[i] = (didx == -1) ? name : name.substring(didx+1);
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a <code>Rectangle2D</code> instance representing the size
|
||||
* of this chain (and all contained subchains).
|
||||
@@ -100,7 +181,11 @@ public class Chain implements Element
|
||||
*/
|
||||
public void addClass (String name, Class child)
|
||||
{
|
||||
Chain chain = new Chain(name, child);
|
||||
// we assume that the addition of a derived class is only done for
|
||||
// classes that are in the package we're visualizing. out of
|
||||
// package classes are only included as roots of chains that
|
||||
// subsequently contain classes that are in the package
|
||||
Chain chain = new Chain(name, child, true);
|
||||
if (!_children.contains(chain)) {
|
||||
_children.add(chain);
|
||||
}
|
||||
@@ -157,6 +242,7 @@ public class Chain implements Element
|
||||
|
||||
protected String _name;
|
||||
protected Class _root;
|
||||
protected boolean _inpkg;
|
||||
|
||||
protected ArrayList _children = new ArrayList();
|
||||
protected Rectangle2D _bounds = new Rectangle2D.Double();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: ChainUtil.java,v 1.3 2001/07/14 00:55:21 mdb Exp $
|
||||
// $Id: ChainUtil.java,v 1.4 2001/07/17 07:18:09 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
@@ -115,7 +115,7 @@ public class ChainUtil
|
||||
// if we have no parent, we want to insert ourselves as a root
|
||||
// class
|
||||
if (parent == null || parent.equals(Object.class)) {
|
||||
insertRoot(roots, name, target);
|
||||
insertRoot(roots, name, target, true);
|
||||
|
||||
} else {
|
||||
String tpkg = pkgFromClass(target.getName());
|
||||
@@ -125,7 +125,7 @@ public class ChainUtil
|
||||
// into the hierarchy as a root class
|
||||
if (!tpkg.equals(ppkg)) {
|
||||
String pname = generateName(parent, pkgroot, true);
|
||||
insertRoot(roots, pname, parent);
|
||||
insertRoot(roots, pname, parent, false);
|
||||
}
|
||||
|
||||
// and now hang ourselves off of our parent class
|
||||
@@ -196,9 +196,9 @@ public class ChainUtil
|
||||
}
|
||||
|
||||
protected static boolean insertRoot (ArrayList roots, String name,
|
||||
Class root)
|
||||
Class root, boolean inpkg)
|
||||
{
|
||||
Chain chroot = new Chain(name, root);
|
||||
Chain chroot = new Chain(name, root, inpkg);
|
||||
// make sure no chain already exists for this root
|
||||
if (!roots.contains(chroot)) {
|
||||
roots.add(chroot);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// $Id: HierarchyVisualizer.java,v 1.6 2001/07/17 05:28:46 mdb Exp $
|
||||
// $Id: HierarchyVisualizer.java,v 1.7 2001/07/17 07:18:09 mdb Exp $
|
||||
|
||||
package com.samskivert.viztool.viz;
|
||||
|
||||
@@ -37,7 +37,13 @@ public class HierarchyVisualizer implements Printable
|
||||
// dump all the classes into an array list so that we can
|
||||
// repeatedly scan through the list
|
||||
while (iter.hasNext()) {
|
||||
_classes.add(iter.next());
|
||||
// strip out inner classes, we'll catch those via their
|
||||
// declaring classes
|
||||
String name = (String)iter.next();
|
||||
if (name.indexOf("$") != -1) {
|
||||
continue;
|
||||
}
|
||||
_classes.add(name);
|
||||
}
|
||||
|
||||
// compile a list of all packages in our collection
|
||||
|
||||
Reference in New Issue
Block a user