diff --git a/core/src/main/java/edu/umd/cs/piccolo/nodes/PHtmlView.java b/core/src/main/java/edu/umd/cs/piccolo/nodes/PHtmlView.java index d183868..0ac75fd 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/nodes/PHtmlView.java +++ b/core/src/main/java/edu/umd/cs/piccolo/nodes/PHtmlView.java @@ -59,7 +59,7 @@ /** Default font to use if not overridden in the HTML markup. */ private static final Font DEFAULT_FONT = new JTextField().getFont(); - /** Default font color to use if not overridden in the HTML markup */ + /** Default font color to use if not overridden in the HTML markup. */ private static final Color DEFAULT_HTML_COLOR = Color.BLACK; /** @@ -236,11 +236,17 @@ /** * Applies all properties to the underlying JLabel, creates an htmlView and - * updates bounds + * updates bounds. */ private void update() { htmlLabel.setSize(htmlLabel.getPreferredSize()); - htmlView = BasicHTML.createHTMLView(htmlLabel, htmlLabel.getText() == null ? "" : htmlLabel.getText()); + + String htmlContent = htmlLabel.getText(); + if (htmlContent == null) { + htmlContent = ""; + } + + htmlView = BasicHTML.createHTMLView(htmlLabel, htmlContent); final Rectangle2D bounds = getBounds(); htmlBounds.setRect(0, 0, bounds.getWidth(), bounds.getHeight()); @@ -280,18 +286,19 @@ /** * Returns the address specified in the link under the given point. * - * @param clickedPoint + * @param clickedPoint point under which a link might be * @return String containing value of href for clicked link, or null if no * link clicked */ - public String getClickedAddress(final Point2D.Double clickedPoint) { + public String getClickedAddress(final Point2D clickedPoint) { return getClickedAddress(clickedPoint.getX(), clickedPoint.getY()); } /** * Returns the address specified in the link under the given point. * - * @param clickedPoint + * @param x x component of point under which link may be + * @param y y component of point under which link may be * @return String containing value of href for clicked link, or null if no * link clicked */ @@ -370,7 +377,11 @@ currentPos++; } - return currentPos == 0 || currentPos >= html.length() ? -1 : currentPos + 1; + if (currentPos == 0 || currentPos >= html.length()) { + return -1; + } + + return currentPos + 1; } /** @@ -408,16 +419,22 @@ if (tag.charAt(currentPos) == '\"') { final int startHref = currentPos + 1; currentPos = tag.indexOf('\"', startHref); - return currentPos == -1 ? null : tag.substring(startHref, currentPos); + if (currentPos == -1) { + return null; + } + return tag.substring(startHref, currentPos); } else if (currentPos < tag.length() && tag.charAt(currentPos) == '\'') { final int startHref = currentPos + 1; currentPos = tag.indexOf('\'', startHref); - return currentPos == -1 ? null : tag.substring(startHref, currentPos); + if (currentPos == -1) { + return null; + } + return tag.substring(startHref, currentPos); } else { final int startHref = currentPos; - + if (currentPos < tag.length()) { do { currentPos++; diff --git a/core/src/main/java/edu/umd/cs/piccolo/util/PBounds.java b/core/src/main/java/edu/umd/cs/piccolo/util/PBounds.java index 1e411c1..aed984c 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/util/PBounds.java +++ b/core/src/main/java/edu/umd/cs/piccolo/util/PBounds.java @@ -59,15 +59,28 @@ private boolean isEmpty = true; + /** + * Creates an empty bounds. + */ public PBounds() { super(); } + /** + * Creates a bounds identical to the one provided. + * + * @param aBounds bounds to be copied + */ public PBounds(final PBounds aBounds) { this(aBounds.x, aBounds.y, aBounds.width, aBounds.height); isEmpty = aBounds.isEmpty(); } + /** + * Creates a bounds with the same shape as the rectangle provided + * + * @param aBounds rectangle to be copied + */ public PBounds(final Rectangle2D aBounds) { this(aBounds.getX(), aBounds.getY(), aBounds.getWidth(), aBounds.getHeight()); isEmpty = aBounds.isEmpty(); @@ -83,19 +96,38 @@ isEmpty = false; } + /** + * Returns a clone of this node. + */ public Object clone() { return new PBounds(this); } + /** + * Returns true if this bounds has been flagged as empty. Not necessarily if + * it is empty. + * + * @return true if bounds marked as empty + */ public boolean isEmpty() { return isEmpty; } + /** + * Flags this bounds as empty. + * + * @return itself for chaining + */ public PBounds reset() { isEmpty = true; return this; } + /** + * Resets the bounds to (0,0,0,0) and flags it as empty. + * + * @return itself for chaining + */ public PBounds resetToZero() { x = 0; y = 0; @@ -105,11 +137,23 @@ return this; } + /** + * Sets the bounds to the same shape as the rectangle. And flags the bounds + * as not empty. + * + * @param r rectangle to copy + */ public void setRect(final Rectangle2D r) { super.setRect(r); isEmpty = false; } + /** + * Sets the bounds to the same shape as the bounds provided. And flags the + * bounds as not empty. + * + * @param b bounds to copy + */ public void setRect(final PBounds b) { isEmpty = b.isEmpty; x = b.x; @@ -118,14 +162,28 @@ height = b.height; } - public void setRect(final double x, final double y, final double w, final double h) { + /** + * Sets the shape of the bounds to the position and dimension provided. + * + * @param x new left of bounds + * @param y new top of bounds + * @param width new width of bounds + * @param height new height of bounds + */ + public void setRect(final double x, final double y, final double width, final double height) { this.x = x; this.y = y; - width = w; - height = h; + this.width = width; + this.height = height; isEmpty = false; } + /** + * Grows the bounds to contain the coordinate provided. + * + * @param newx x component of point + * @param newy y component of point + */ public void add(final double newx, final double newy) { if (isEmpty) { setRect(newx, newy, 0, 0); @@ -136,6 +194,11 @@ } } + /** + * Grows bounds to contain the rectangle if needed. + * + * @param r rectangle being added + */ public void add(final Rectangle2D r) { if (isEmpty) { setRect(r); @@ -145,23 +208,27 @@ } } - // optimized add when adding two PBounds together. - public void add(final PBounds r) { - if (r.isEmpty) { + /** + * Changes this bounds to contain the provided bounds. + * + * @param bounds bounds being added + */ + public void add(final PBounds bounds) { + if (bounds.isEmpty) { return; } else if (isEmpty) { - x = r.x; - y = r.y; - width = r.width; - height = r.height; + x = bounds.x; + y = bounds.y; + width = bounds.width; + height = bounds.height; isEmpty = false; } else { - final double x1 = x <= r.x ? x : r.x; - final double y1 = y <= r.y ? y : r.y; - final double x2 = x + width >= r.x + r.width ? x + width : r.x + r.width; - final double y2 = y + height >= r.y + r.height ? y + height : r.y + r.height; + final double x1 = x <= bounds.x ? x : bounds.x; + final double y1 = y <= bounds.y ? y : bounds.y; + final double x2 = x + width >= bounds.x + bounds.width ? x + width : bounds.x + bounds.width; + final double y2 = y + height >= bounds.y + bounds.height ? y + height : bounds.y + bounds.height; x = x1; y = y1; @@ -171,10 +238,22 @@ } } + /** + * Returns the x,y coordinate of the bounds. + * + * @return coordinate of the bounds + */ public Point2D getOrigin() { return new Point2D.Double(x, y); } + /** + * Changes the origin of these bounds. And flags it as non-empty. + * + * @param x new x component of bounds + * @param y new y componet of the bounds + * @return + */ public PBounds setOrigin(final double x, final double y) { this.x = x; this.y = y; @@ -182,23 +261,50 @@ return this; } + /** + * Returns the size of the bounds. + * + * @return size of the bounds + */ public Dimension2D getSize() { return new PDimension(width, height); } + /** + * Changes the size of the bounds, but retains the origin. + * + * @param width new width of the bounds + * @param height new height of the bounds + */ public void setSize(final double width, final double height) { setRect(x, y, width, height); } + /** + * Returns the midpoint of the bounds. + * + * @return midpoint of the bounds + */ public Point2D getCenter2D() { return new Point2D.Double(getCenterX(), getCenterY()); } + /** + * Translates the bounds by the given deltas. + * + * @param dx amount to move x + * @param dy amount to move y + * @return itself for chaining + */ public PBounds moveBy(final double dx, final double dy) { setOrigin(x + dx, y + dy); return this; } + /** + * Rounds the rectangle to the next largest bounds who's measurements are + * integers. Note: this is not the same as rounding its measurements. + */ public void expandNearestIntegerDimensions() { x = Math.floor(x); y = Math.floor(y); @@ -206,52 +312,77 @@ height = Math.ceil(height); } + /** + * Adjust the measurements of this bounds so that they are the amounts given + * "in" from their previous border. + * + * @param dx amount to move in from border along horizontal axis + * @param dy amount to move in from border along vertical axis + * @return itself for chaining + */ public PBounds inset(final double dx, final double dy) { setRect(x + dx, y + dy, width - dx * 2, height - dy * 2); return this; } - public PDimension deltaRequiredToCenter(final Rectangle2D b) { + /** + * Returns the required translation in order for this bounds origin to sit + * on the center of the provided rectangle. + * + * @param targetBounds rectangle to measure the center of + * @return the delta required to move to center of the targetBounds + */ + public PDimension deltaRequiredToCenter(final Rectangle2D targetBounds) { final PDimension result = new PDimension(); - final double xDelta = getCenterX() - b.getCenterX(); - final double yDelta = getCenterY() - b.getCenterY(); + final double xDelta = getCenterX() - targetBounds.getCenterX(); + final double yDelta = getCenterY() - targetBounds.getCenterY(); result.setSize(xDelta, yDelta); return result; } - public PDimension deltaRequiredToContain(final Rectangle2D b) { + /** + * Returns the required translation in order for these to contain the bounds + * provided. + * + * @param targetBounds rectangle to measure the center of + * @return the delta required in order for the bounds to overlap completely + * the targetBounds + */ + public PDimension deltaRequiredToContain(final Rectangle2D targetBounds) { final PDimension result = new PDimension(); - if (!contains(b)) { - final double bMaxX = b.getMaxX(); - final double bMinX = b.getMinX(); - final double bMaxY = b.getMaxY(); - final double bMinY = b.getMinY(); - final double maxX = getMaxX(); - final double minX = getMinX(); - final double maxY = getMaxY(); - final double minY = getMinY(); + if (contains(targetBounds)) { + return result; + } - if (bMaxX > maxX ^ bMinX < minX) { - final double difMaxX = bMaxX - maxX; - final double difMinX = bMinX - minX; - if (Math.abs(difMaxX) < Math.abs(difMinX)) { - result.width = difMaxX; - } - else { - result.width = difMinX; - } + final double targetMaxX = targetBounds.getMaxX(); + final double targetMinX = targetBounds.getMinX(); + final double targetMaxY = targetBounds.getMaxY(); + final double targetMinY = targetBounds.getMinY(); + final double maxX = getMaxX(); + final double minX = getMinX(); + final double maxY = getMaxY(); + final double minY = getMinY(); + + if (targetMaxX > maxX ^ targetMinX < minX) { + final double difMaxX = targetMaxX - maxX; + final double difMinX = targetMinX - minX; + if (Math.abs(difMaxX) < Math.abs(difMinX)) { + result.width = difMaxX; } + else { + result.width = difMinX; + } + } - if (bMaxY > maxY ^ bMinY < minY) { - final double difMaxY = bMaxY - maxY; - final double difMinY = bMinY - minY; - if (Math.abs(difMaxY) < Math.abs(difMinY)) { - result.height = difMaxY; - } - else { - result.height = difMinY; - } + if (targetMaxY > maxY ^ targetMinY < minY) { + final double difMaxY = targetMaxY - maxY; + final double difMinY = targetMinY - minY; + if (Math.abs(difMaxY) < Math.abs(difMinY)) { + result.height = difMaxY; + } + else { + result.height = difMinY; } } @@ -274,6 +405,11 @@ height = in.readDouble(); } + /** + * Returns a string representation of this PBounds for debugging purposes. + * + * @return string representation of this PBounds + */ public String toString() { final StringBuffer result = new StringBuffer(); diff --git a/core/src/main/java/edu/umd/cs/piccolo/util/PDebug.java b/core/src/main/java/edu/umd/cs/piccolo/util/PDebug.java index 1e56554..20725c9 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/util/PDebug.java +++ b/core/src/main/java/edu/umd/cs/piccolo/util/PDebug.java @@ -42,18 +42,34 @@ * @author Jesse Grosjean */ public class PDebug { - + /** Set to true to display clip bounds boxes. */ public static boolean debugRegionManagement = false; + + /** + * Set to true if you want to display common errors with painting and + * threading. + */ public static boolean debugPaintCalls = false; + + /** Set to true to display frame rate in the console. */ public static boolean debugPrintFrameRate = false; + + /** Set to true to display used memory in console. */ public static boolean debugPrintUsedMemory = false; + + /** Displays bounding boxes around nodes. Used in PCamera. */ public static boolean debugBounds = false; + + /** Displays a tint to all shapes within a bounding box. */ public static boolean debugFullBounds = false; + + /** Whether to complain whenever common threading issues occur. */ public static boolean debugThreads = false; + + /** How often in frames result info should be printed to the console. */ public static int printResultsFrameRate = 10; private static int debugPaintColor; - private static long framesProcessed; private static long startProcessingOutputTime; private static long startProcessingInputTime; @@ -65,18 +81,29 @@ super(); } + /** + * Generates a color for use while debugging. + * + * @return a color for use while debugging. + */ public static Color getDebugPaintColor() { final int color = 100 + debugPaintColor++ % 10 * 10; return new Color(color, color, color, 150); } - // called when scene graph needs update. + /** + * Checks that process inputs is being doing from the Swing Dispatch Thread. + */ public static void scheduleProcessInputs() { if (debugThreads && !SwingUtilities.isEventDispatchThread()) { System.out.println("scene graph manipulated on wrong thread"); } } + /** + * Ensures that painting is not invalidating paint regions and that it's + * being called from the dispatch thread. + */ public static void processRepaint() { if (processingOutput && debugPaintCalls) { System.err @@ -88,15 +115,28 @@ } } + /** + * Returns whether output is being processed. + * + * @return whether output is being processed + */ public static boolean getProcessingOutput() { return processingOutput; } + /** + * Records that processing of ouptut has begun. + */ public static void startProcessingOutput() { processingOutput = true; startProcessingOutputTime = System.currentTimeMillis(); } + /** + * Flags processing of output as finished. Updates all stats in the process. + * + * @param g graphics context in which processing has finished + */ public static void endProcessingOutput(final Graphics g) { processOutputTime += System.currentTimeMillis() - startProcessingOutputTime; framesProcessed++; @@ -124,10 +164,16 @@ processingOutput = false; } + /** + * Records that processing of input has started. + */ public static void startProcessingInput() { startProcessingInputTime = System.currentTimeMillis(); } + /** + * Records that processing of input has finished. + */ public static void endProcessingInput() { processInputTime += System.currentTimeMillis() - startProcessingInputTime; } @@ -136,6 +182,8 @@ * Return how many frames are processed and painted per second. Note that * since piccolo doesn't paint continuously this rate will be slow unless * you are interacting with the system or have activities scheduled. + * + * @return frame rate achieved */ public static double getTotalFPS() { if (framesProcessed > 0) { @@ -148,6 +196,8 @@ /** * Return the frames per second used to process input events and activities. + * + * @return # of frames per second that were allocated to processing input */ public static double getInputFPS() { if (processInputTime > 0 && framesProcessed > 0) { @@ -160,6 +210,8 @@ /** * Return the frames per seconds used to paint graphics to the screen. + * + * @return # of frames per second that were used up to processing output */ public static double getOutputFPS() { if (processOutputTime > 0 && framesProcessed > 0) { @@ -173,6 +225,8 @@ /** * Return the number of frames that have been processed since the last time * resetFPSTiming was called. + * + * @return total number of frames processed */ public long getFramesProcessed() { return framesProcessed; @@ -189,6 +243,13 @@ processOutputTime = 0; } + /** + * Returns an approximation of the amount of memory that is being used. + * + * Not that this call might affecting timings. + * + * @return approximate # of bytes of memory used + */ public static long getApproximateUsedMemory() { System.gc(); System.runFinalization(); diff --git a/core/src/main/java/edu/umd/cs/piccolo/util/PDimension.java b/core/src/main/java/edu/umd/cs/piccolo/util/PDimension.java index 94ec009..dda129b 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/util/PDimension.java +++ b/core/src/main/java/edu/umd/cs/piccolo/util/PDimension.java @@ -47,41 +47,86 @@ */ private static final long serialVersionUID = 1L; + /** The width of the dimension. */ public double width; + + /** The height of the dimension. */ public double height; + /** + * Returns a dimension with no width or height. + */ public PDimension() { super(); } + /** + * Copies the provided dimension. + * + * @param aDimension dimension to copy + */ public PDimension(final Dimension2D aDimension) { this(aDimension.getWidth(), aDimension.getHeight()); } + /** + * Creates a dimension with the provided dimensions. + * + * @param aWidth desired width + * @param aHeight desired height + */ public PDimension(final double aWidth, final double aHeight) { super(); width = aWidth; height = aHeight; } + /** + * Creates a dimension that's the size of a rectangel with the points + * provided as opposite corners. + * + * @param p1 first point on rectangle + * @param p2 point diagonally across from p1 + */ public PDimension(final Point2D p1, final Point2D p2) { width = p2.getX() - p1.getX(); height = p2.getY() - p1.getY(); } + /** + * Returns the height of the dimension. + * + * @return height height of the dimension + */ public double getHeight() { return height; } + /** + * Returns the width of the dimension. + * + * @return width width of the dimension + */ public double getWidth() { return width; } + /** + * Resizes the dimension to have the dimensions provided. + * + * @param aWidth desired width + * @param aHeight desired height + */ public void setSize(final double aWidth, final double aHeight) { width = aWidth; height = aHeight; } + /** + * Returns a string representation of this dimension object. + * + * @return string representation of this dimension object. + */ public String toString() { final StringBuffer result = new StringBuffer(); diff --git a/core/src/main/java/edu/umd/cs/piccolo/util/PNodeFilter.java b/core/src/main/java/edu/umd/cs/piccolo/util/PNodeFilter.java index d1a3cae..ff4face 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/util/PNodeFilter.java +++ b/core/src/main/java/edu/umd/cs/piccolo/util/PNodeFilter.java @@ -43,12 +43,18 @@ /** * Return true if the filter should accept the given node. + * + * @param aNode node under test + * @return true if node should be accepted */ - public boolean accept(PNode aNode); + boolean accept(PNode aNode); /** * Return true if the filter should test the children of the given node for * acceptance. + * + * @param aNode parent being tested + * @return true if children should be tested for acceptance */ - public boolean acceptChildrenOf(PNode aNode); + boolean acceptChildrenOf(PNode aNode); }