diff --git a/core/src/build/conf/checkstyle.xml b/core/src/build/conf/checkstyle.xml index c4f2ce0..be1ded8 100644 --- a/core/src/build/conf/checkstyle.xml +++ b/core/src/build/conf/checkstyle.xml @@ -147,8 +147,8 @@ - - + + diff --git a/core/src/main/java/edu/umd/cs/piccolo/PCamera.java b/core/src/main/java/edu/umd/cs/piccolo/PCamera.java index eeda20c..1cb9465 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/PCamera.java +++ b/core/src/main/java/edu/umd/cs/piccolo/PCamera.java @@ -82,6 +82,13 @@ * nodes layers, but old value will always be null. */ public static final String PROPERTY_LAYERS = "layers"; + /** + * The property code that identifies a change in the set of this camera's + * layers (see {@link #getLayer getLayer}, {@link #getLayerCount + * getLayerCount}, {@link #getLayersReference getLayersReference}). A + * property change event's new value will be a reference to the list of this + * nodes layers, but old value will always be null. + */ public static final int PROPERTY_CODE_LAYERS = 1 << 11; /** @@ -92,15 +99,43 @@ * old value will always be null. */ public static final String PROPERTY_VIEW_TRANSFORM = "viewTransform"; + + /** + * The property code that identifies a change in this camera's view + * transform (see {@link #getViewTransform getViewTransform}, + * {@link #getViewTransformReference getViewTransformReference}). A property + * change event's new value will be a reference to the view transform, but + * old value will always be null. + */ public static final int PROPERTY_CODE_VIEW_TRANSFORM = 1 << 12; + /** + * Denotes that the view has no constraints. + */ public static final int VIEW_CONSTRAINT_NONE = 0; public static final int VIEW_CONSTRAINT_ALL = 1; public static final int VIEW_CONSTRAINT_CENTER = 2; + /** + * The component to which repaint notification are passed to when a camera + * wishes to be repainted. + */ private transient PComponent component; + /** + * Layers which the camera is viewing. + */ private transient List layers; + /** + * Transform that is applied to layers before they are rendered. + * + * This transform differs from the transform applied to the children of this + * PCamera (sticky objects) + */ private final PAffineTransform viewTransform; + + /** + * The constraints to apply to the viewing area. + */ private int viewConstraint; /** @@ -116,6 +151,8 @@ /** * Get the canvas associated with this camera. This will return null if not * canvas has been associated, as may be the case for internal cameras. + * + * @return the canvas associated with this camera */ public PComponent getComponent() { return component; @@ -124,19 +161,26 @@ /** * Set the canvas associated with this camera. When the camera is repainted * it will request repaints on this canvas. + * + * @param newComponent the component to which this camera will dispatch + * repaint requests to */ - public void setComponent(final PComponent aComponent) { - component = aComponent; + public void setComponent(final PComponent newComponent) { + component = newComponent; invalidatePaint(); } /** * Repaint this camera, and forward the repaint request to the camera's * canvas if it is not null. + * + * @param localBounds the area that requires repainting + * @param sourceNode the node from which the repaint message originates, may + * be the camera itself */ - public void repaintFrom(final PBounds localBounds, final PNode descendentOrThis) { + public void repaintFrom(final PBounds localBounds, final PNode sourceNode) { if (getParent() != null) { - if (descendentOrThis != this) { + if (sourceNode != this) { localToParent(localBounds); } @@ -148,12 +192,18 @@ } } - private static PBounds TEMP_REPAINT_RECT = new PBounds(); + /** + * Used as an optimization during repaint. + */ + private static final PBounds TEMP_REPAINT_RECT = new PBounds(); /** * Repaint from one of the cameras layers. The repaint region needs to be * transformed from view to local in this case. Unlike most repaint methods - * in piccolo this one must not modify the viewBounds parameter. + * in Piccolo2d this one must not modify the viewBounds parameter. + * + * @param viewBounds the bounds of the region needing painting + * @param repaintedLayer layer dispatching the repaint notification */ public void repaintFromLayer(final PBounds viewBounds, final PLayer repaintedLayer) { TEMP_REPAINT_RECT.setRect(viewBounds); @@ -172,6 +222,10 @@ * needs to be transformed from view to local in this case. * Unlike most repaint methods in piccolo this one must not * modify the viewBounds parameter. + * + * + * @param viewBounds the bounds of the region needing painting + * @param repaintedLayer layer dispatching the repaint notification */ public void repaintFromLayer(final PBounds viewBounds, final PNode repaintedLayer) { if (repaintedLayer instanceof PLayer) { @@ -182,25 +236,42 @@ } } - // **************************************************************** - // Layers - // **************************************************************** - /** * Return a reference to the list of layers managed by this camera. + * + * @return list of layers attached to this camera */ public List getLayersReference() { return layers; } + /** + * Returns the number of layers attached to this camera. + * + * @return number of layers attached to this camera + */ public int getLayerCount() { return layers.size(); } + /** + * Returns the layer at the given index. + * + * @param index the index of the layer + * + * @return layer at the given index + */ public PLayer getLayer(final int index) { return (PLayer) layers.get(index); } + /** + * Returns the index of the given layer or -1 it not found. + * + * @param layer layer to search for + * + * @return the index of the given layer or -1 it not found + */ public int indexOfLayer(final PLayer layer) { return layers.indexOf(layer); } @@ -208,6 +279,8 @@ /** * Add the layer to the end of this camera's list of layers. Layers may be * viewed by multiple cameras at once. + * + * @param layer layer to add to this camera */ public void addLayer(final PLayer layer) { addLayer(layers.size(), layer); @@ -216,6 +289,9 @@ /** * Add the layer at the given index in this camera's list of layers. Layers * may be viewed by multiple cameras at once. + * + * @param index index before which to add this layer + * @param layer Layer to add */ public void addLayer(final int index, final PLayer layer) { layers.add(index, layer); @@ -230,6 +306,7 @@ * If the layer is not found, it leaves the camera unchanged. * * @param layer the layer to be removed + * @return layer that was passed in */ public PLayer removeLayer(final PLayer layer) { layer.removeCamera(this); @@ -243,6 +320,9 @@ /** * Remove the layer at the given index from the list of layers managed by * this camera. + * + * @param index the index of the layer to remove + * @return layer that was removed */ public PLayer removeLayer(final int index) { final PLayer layer = (PLayer) layers.remove(index); @@ -254,6 +334,8 @@ /** * Return the total bounds of all the layers that this camera looks at. + * + * @return the bounds of all the layers taken together */ public PBounds getUnionOfLayerFullBounds() { final PBounds result = new PBounds(); @@ -267,13 +349,11 @@ return result; } - // **************************************************************** - // Painting Layers - // **************************************************************** - /** * Paint this camera (default background color is white) and then paint the * cameras view through the view transform. + * + * @param paintContext the context in which the painting occurs */ protected void paint(final PPaintContext paintContext) { super.paint(paintContext); @@ -292,6 +372,8 @@ * Paint all the layers that the camera is looking at, this method is called * after the cameras view transform and clip are applied to the * paintContext. + * + * @param paintContext the context in which the painting occurs */ protected void paintCameraView(final PPaintContext paintContext) { final int count = getLayerCount(); @@ -301,6 +383,12 @@ } } + /** + * Renders debug info onto the newly painted scene. Things like full bounds + * and bounds are painted as filled and outlines. + * + * @param paintContext the context in which the painting occurs + */ protected void paintDebugInfo(final PPaintContext paintContext) { if (PDebug.debugBounds || PDebug.debugFullBounds) { final Graphics2D g2 = paintContext.getGraphics(); @@ -356,7 +444,9 @@ /** * Override fullPaint to push the camera onto the paintContext so that it - * can be later be accessed by PPaintContext.getCamera(); + * can be later be accessed by PPaintContext.getCamera(). + * + * @param paintContext the context in which the painting occurs */ public void fullPaint(final PPaintContext paintContext) { paintContext.pushCamera(this); @@ -364,14 +454,17 @@ paintContext.popCamera(this); } - // **************************************************************** - // Picking - // **************************************************************** - /** * Generate and return a PPickPath for the point x,y specified in the local * coord system of this camera. Picking is done with a rectangle, halo * specifies how large that rectangle will be. + * + * @param x the x coordinate of the pick path given in local coordinates + * @param y the y coordinate of the pick path given in local coordinates + * @param halo the distance from the x,y coordinate that is considered for + * inclusion in the pick path + * + * @return the picked path */ public PPickPath pick(final double x, final double y, final double halo) { final PBounds b = new PBounds(new Point2D.Double(x, y), -halo, -halo); @@ -391,6 +484,9 @@ /** * After the direct children of the camera have been given a chance to be * picked objects viewed by the camera are given a chance to be picked. + * + * @param pickPath picked layer children add added to this pick path + * @return whether the pickPath has changed */ protected boolean pickAfterChildren(final PPickPath pickPath) { if (intersects(pickPath.getPickBounds())) { @@ -409,6 +505,9 @@ /** * Pick all the layers that the camera is looking at, this method is called * after the cameras view transform and clip are applied to the pickPath. + * + * @param pickPath picked layer children add added to this pick path + * @return whether the pickPath has changed */ protected boolean pickCameraView(final PPickPath pickPath) { final int count = getLayerCount(); @@ -432,16 +531,19 @@ /** * Return the bounds of this camera in the view coordinate system. + * + * @return the bounds of this camera in the view coordinate system */ public PBounds getViewBounds() { return (PBounds) localToView(getBounds()); } /** - * Translates and scales the camera's view transform so that the given - * bounds (in camera layer's coordinate system)are centered within the - * cameras view bounds. Use this method to point the camera at a given - * location. + * Animates the camera's view so that the given bounds (in camera layer's + * coordinate system) are centered within the cameras view bounds. Use this + * method to point the camera at a given location. + * + * @param centerBounds the targetBounds */ public void setViewBounds(final Rectangle2D centerBounds) { animateViewToCenterBounds(centerBounds, true, 0); @@ -450,6 +552,8 @@ /** * Return the scale applied by the view transform to the layers viewed by * this camera. + * + * @return The scale of the viewTransform viewing the layers */ public double getViewScale() { return viewTransform.getScale(); @@ -458,6 +562,8 @@ /** * Scale the view transform that is applied to the layers viewed by this * camera by the given amount. + * + * @param scale the scale to change the Layers' view transform */ public void scaleView(final double scale) { scaleViewAboutPoint(scale, 0, 0); @@ -466,6 +572,10 @@ /** * Scale the view transform that is applied to the layers viewed by this * camera by the given amount about the given point. + * + * @param scale the scale at which the view should be + * @param x the x coordinate the view should change to + * @param y the y coordinate the view should change to */ public void scaleViewAboutPoint(final double scale, final double x, final double y) { viewTransform.scaleAboutPoint(scale, x, y); @@ -477,6 +587,8 @@ /** * Set the scale of the view transform that is applied to the layers viewed * by this camera. + * + * @param scale the scale of the transform viewing the layers */ public void setViewScale(final double scale) { scaleView(scale / getViewScale()); @@ -484,6 +596,9 @@ /** * Translate the view transform that is applied to the camera's layers. + * + * @param dx the delta which the x coordinate should be increased by + * @param dy the delta which the y coordinate should be increased by */ public void translateView(final double dx, final double dy) { viewTransform.translate(dx, dy); @@ -495,6 +610,9 @@ /** * Sets the offset of the view transform that is applied to the camera's * layers. + * + * @param x the new x translation of the view transform + * @param y the new y translation of the view transform */ public void setViewOffset(final double x, final double y) { viewTransform.setOffset(x, y); @@ -505,6 +623,8 @@ /** * Get a copy of the view transform that is applied to the camera's layers. + * + * @return the viewTransform being applied to the layers */ public PAffineTransform getViewTransform() { return (PAffineTransform) viewTransform.clone(); @@ -513,6 +633,9 @@ /** * Get a reference to the view transform that is applied to the camera's * layers. + * + * @return a direct reference to the view transform being applied to the + * layers */ public PAffineTransform getViewTransformReference() { return viewTransform; @@ -520,6 +643,8 @@ /** * Set the view transform that is applied to the views layers. + * + * @param aTransform the new view transform */ public void setViewTransform(final AffineTransform aTransform) { viewTransform.setTransform(aTransform); @@ -538,6 +663,14 @@ * true, then the camera will also scale its view so that the given bounds * fit fully within the cameras view bounds, else the camera will maintain * its original scale. + * + * @param centerBounds the bounds which the animation will pace at the + * center of the view + * @param shouldScaleToFit whether the camera should scale the view while + * animating to it + * @param duration how many milliseconds the animations should take + * + * @return the scheduled PTransformActivity */ public PTransformActivity animateViewToCenterBounds(final Rectangle2D centerBounds, final boolean shouldScaleToFit, final long duration) { @@ -565,6 +698,11 @@ * immediately, and null will be returned. Else a new PTransformActivity * will get returned that is set to animate the camera's view transform to * the new bounds. + * + * @param panToBounds the bounds to which the view will animate to + * @param duration the duration of the animation given in milliseconds + * + * @return the scheduled PTransformActivity */ public PTransformActivity animateViewToPanToBounds(final Rectangle2D panToBounds, final long duration) { final PBounds viewBounds = getViewBounds(); @@ -585,7 +723,20 @@ } /** + * Pan the camera's view from its current transform when the activity starts + * to a new transform so that the view bounds will contain (if possible, + * intersect if not possible) the new bounds in the camera layers coordinate + * system. If the duration is 0 then the view will be transformed + * immediately, and null will be returned. Else a new PTransformActivity + * will get returned that is set to animate the camera's view transform to + * the new bounds. + * * @deprecated Renamed to animateViewToPanToBounds + * + * @param includeBounds the bounds to which the view will animate to + * @param duration the duration of the animation given in milliseconds + * + * @return the scheduled PTransformActivity */ public PTransformActivity animateViewToIncludeBounds(final Rectangle2D includeBounds, final long duration) { return animateViewToPanToBounds(includeBounds, duration); @@ -594,6 +745,12 @@ /** * Animate the cameras view transform from its current value when the * activity starts to the new destination transform value. + * + * @param destination the transform to which the view should be transformed + * into + * @param duration the duraiton in milliseconds the animation should take + * + * @return the scheduled PTransformActivity */ public PTransformActivity animateViewToTransform(final AffineTransform destination, final long duration) { if (duration == 0) { @@ -611,14 +768,15 @@ } }; - final PTransformActivity ta = new PTransformActivity(duration, PUtil.DEFAULT_ACTIVITY_STEP_RATE, t, destination); + final PTransformActivity transformActivity = new PTransformActivity(duration, PUtil.DEFAULT_ACTIVITY_STEP_RATE, + t, destination); final PRoot r = getRoot(); if (r != null) { - r.getActivityScheduler().addActivity(ta); + r.getActivityScheduler().addActivity(transformActivity); } - return ta; + return transformActivity; } // **************************************************************** @@ -626,15 +784,28 @@ // constraints to the view transform. // **************************************************************** + /** + * Returns the constraint being applied to the view. + * + * @return the viewConstraint being applied to the view + */ public int getViewConstraint() { return viewConstraint; } + /** + * Sets the view constraint to apply to the view. + * + * @param constraint the new constraint to apply to the view + */ public void setViewConstraint(final int constraint) { viewConstraint = constraint; applyViewConstraints(); } + /** + * Transforms the view so that it conforms to the given constraint. + */ protected void applyViewConstraints() { if (viewConstraint == VIEW_CONSTRAINT_NONE) { return; @@ -673,6 +844,10 @@ /** * Convert the point from the camera's view coordinate system to the * camera's local coordinate system. The given point is modified by this. + * + * @param viewPoint the point to transform to the local coordinate system + * from the view's coordinate system + * @return the transformed point */ public Point2D viewToLocal(final Point2D viewPoint) { return viewTransform.transform(viewPoint, viewPoint); @@ -682,6 +857,11 @@ * Convert the dimension from the camera's view coordinate system to the * camera's local coordinate system. The given dimension is modified by * this. + * + * @param viewDimension the dimension to transform from the view system to + * the local coordinate system + * + * @return returns the transformed dimension */ public Dimension2D viewToLocal(final Dimension2D viewDimension) { return viewTransform.transform(viewDimension, viewDimension); @@ -691,6 +871,10 @@ * Convert the rectangle from the camera's view coordinate system to the * camera's local coordinate system. The given rectangle is modified by this * method. + * + * @param viewRectangle the rectangle to transform from view to local + * coordinate System + * @return the transformed rectangle */ public Rectangle2D viewToLocal(final Rectangle2D viewRectangle) { return viewTransform.transform(viewRectangle, viewRectangle); @@ -700,6 +884,9 @@ * Convert the point from the camera's local coordinate system to the * camera's view coordinate system. The given point is modified by this * method. + * + * @param localPoint point to transform from local to view coordinate system + * @return the transformed point */ public Point2D localToView(final Point2D localPoint) { return viewTransform.inverseTransform(localPoint, localPoint); @@ -709,6 +896,10 @@ * Convert the dimension from the camera's local coordinate system to the * camera's view coordinate system. The given dimension is modified by this * method. + * + * @param localDimension the dimension to transform from local to view + * coordinate systems + * @return the transformed dimension */ public Dimension2D localToView(final Dimension2D localDimension) { return viewTransform.inverseTransform(localDimension, localDimension); @@ -718,6 +909,10 @@ * Convert the rectangle from the camera's local coordinate system to the * camera's view coordinate system. The given rectangle is modified by this * method. + * + * @param localRectangle the rectangle to transform from local to view + * coordinate system + * @return the transformed rectangle */ public Rectangle2D localToView(final Rectangle2D localRectangle) { return viewTransform.inverseTransform(localRectangle, localRectangle); @@ -734,8 +929,15 @@ * Write this camera and all its children out to the given stream. Note that * the cameras layers are written conditionally, so they will only get * written out if someone else writes them unconditionally. + * + * @param out the PObjectOutputStream to which this camera should be + * serialized + * @throws IOException if an error occured writing to the output stream */ private void writeObject(final ObjectOutputStream out) throws IOException { + if (!(out instanceof PObjectOutputStream)) { + throw new RuntimeException("cannot serialize PCamera to a non PObjectOutputStream"); + } out.defaultWriteObject(); final int count = getLayerCount(); @@ -747,6 +949,14 @@ ((PObjectOutputStream) out).writeConditionalObject(component); } + /** + * Deserializes this PCamera from the ObjectInputStream. + * + * @param in the source ObjectInputStream + * @throws IOException when error occurs during read + * @throws ClassNotFoundException if the stream attempts to deserialize a + * missing class + */ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); diff --git a/core/src/main/java/edu/umd/cs/piccolo/PCanvas.java b/core/src/main/java/edu/umd/cs/piccolo/PCanvas.java index 7617282..84d7545 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/PCanvas.java +++ b/core/src/main/java/edu/umd/cs/piccolo/PCanvas.java @@ -82,23 +82,86 @@ * reflect the correct spelling */ public static final String INTERATING_CHANGED_NOTIFICATION = "INTERATING_CHANGED_NOTIFICATION"; + + /** + * The property name that identifies a change in the interacting state. + * + * @deprecated in favor of PROPERTY_INTERACTING + */ public static final String INTERACTING_CHANGED_NOTIFICATION = "INTERACTING_CHANGED_NOTIFICATION"; + /** + * The property name that identifies a change in the interacting state. + */ + public static final String PROPERTY_INTERACTING = "INTERACTING_CHANGED_NOTIFICATION"; + + /** + * Used as a public global to track the current canvas. + * + * @deprecated since it falsely assumes that there is only one PCanvas per + * program + */ public static PCanvas CURRENT_ZCANVAS = null; + /** + * The camera though which this Canvas is viewing. + */ private PCamera camera; + + /** + * Stack of cursors used to keep track of cursors as they change through + * interactions. + */ private final PStack cursorStack; + + /** + * Whether the canvas is considered to be interacting, will probably mean + * worse render quality. + */ private int interacting; - private int defaultRenderQuality; + /** + * The render quality to use when the scene is not being interacted or + * animated. + */ + private int normalRenderQuality; + /** + * The quality to use while the scene is being animated. + */ private int animatingRenderQuality; + /** + * The quality to use while the scene is being interacted with. + */ private int interactingRenderQuality; + /** + * The one and only pan handler. + */ private PPanEventHandler panEventHandler; + /** + * The one and only ZoomEventHandler. + */ private PZoomEventHandler zoomEventHandler; + private boolean paintingImmediately; + /** + * Used to track whether the last paint operation was during an animation. + */ private boolean animatingOnLastPaint; + /** + * The mouse listener that is registered for large scale mouse events. + */ private transient MouseListener mouseListener; + /** + * Remembers the key processor. + */ private transient KeyEventPostProcessor keyEventPostProcessor; + /** + * The mouse wheel listeners that's registered to receive wheel events. + */ private transient MouseWheelListener mouseWheelListener; + /** + * The mouse listener that is registered to receive small scale mouse events + * (like motion). + */ private transient MouseMotionListener mouseMotionListener; /** @@ -131,6 +194,11 @@ }); } + /** + * Creates and returns a basic Scene Graph. + * + * @return a built PCamera scene + */ protected PCamera createDefaultCamera() { return PUtil.createBasicScenegraph(); } @@ -143,6 +211,8 @@ * Get the pan event handler associated with this canvas. This event handler * is set up to get events from the camera associated with this canvas by * default. + * + * @return the current pan event handler, may be null */ public PPanEventHandler getPanEventHandler() { return panEventHandler; @@ -169,6 +239,8 @@ * Get the zoom event handler associated with this canvas. This event * handler is set up to get events from the camera associated with this * canvas by default. + * + * @return the current zoom event handler, may be null */ public PZoomEventHandler getZoomEventHandler() { return zoomEventHandler; @@ -195,6 +267,8 @@ * Return the camera associated with this canvas. All input events from this * canvas go through this camera. And this is the camera that paints this * canvas. + * + * @return camera through which this PCanvas views the scene */ public PCamera getCamera() { return camera; @@ -204,6 +278,8 @@ * Set the camera associated with this canvas. All input events from this * canvas go through this camera. And this is the camera that paints this * canvas. + * + * @param newCamera the camera which this PCanvas should view the scene */ public void setCamera(final PCamera newCamera) { if (camera != null) { @@ -220,6 +296,8 @@ /** * Return root for this canvas. + * + * @return the root PNode at the "bottom" of the scene */ public PRoot getRoot() { return camera.getRoot(); @@ -227,6 +305,8 @@ /** * Return layer for this canvas. + * + * @return the first layer attached to this camera */ public PLayer getLayer() { return camera.getLayer(0); @@ -234,6 +314,8 @@ /** * Add an input listener to the camera associated with this canvas. + * + * @param listener listener to register for event notifications */ public void addInputEventListener(final PInputEventListener listener) { getCamera().addInputEventListener(listener); @@ -241,6 +323,8 @@ /** * Remove an input listener to the camera associated with this canvas. + * + * @param listener listener to unregister from event notifications */ public void removeInputEventListener(final PInputEventListener listener) { getCamera().removeInputEventListener(listener); @@ -251,8 +335,11 @@ // **************************************************************** /** - * Return true if this canvas has been marked as interacting. If so the - * canvas will normally render at a lower quality that is faster. + * Return true if this canvas has been marked as interacting, or whether + * it's root is interacting. If so the canvas will normally render at a + * lower quality that is faster. + * + * @return whether the canvas has been flagged as being interacted with */ public boolean getInteracting() { return interacting > 0 || getRoot().getInteracting(); @@ -263,6 +350,8 @@ * isAnimating were run in the last PRoot.processInputs() loop. This values * is used by this canvas to determine the render quality to use for the * next paint. + * + * @return whether the PCanvas is currently being animated */ public boolean getAnimating() { return getRoot().getActivityScheduler().getAnimating(); @@ -272,8 +361,10 @@ * Set if this canvas is interacting. If so the canvas will normally render * at a lower quality that is faster. Also repaints the canvas if the render * quality should change. + * + * @param isInteracting whether the PCanvas should be considered interacting */ - public void setInteracting(boolean isInteracting) { + public void setInteracting(final boolean isInteracting) { final boolean wasInteracting = getInteracting(); if (isInteracting) { @@ -286,7 +377,7 @@ if (!getInteracting()) { // determine next render quality and repaint if // it's greater then the old // interacting render quality. - int nextRenderQuality = defaultRenderQuality; + int nextRenderQuality = normalRenderQuality; if (getAnimating()) { nextRenderQuality = animatingRenderQuality; } @@ -295,10 +386,10 @@ } } - isInteracting = getInteracting(); + final boolean newInteracting = getInteracting(); - if (wasInteracting != isInteracting) { - firePropertyChange(INTERACTING_CHANGED_NOTIFICATION, wasInteracting, isInteracting); + if (wasInteracting != newInteracting) { + firePropertyChange(PROPERTY_INTERACTING, wasInteracting, newInteracting); } } @@ -311,7 +402,7 @@ * PPaintContext.LOW_QUALITY_RENDERING */ public void setDefaultRenderQuality(final int requestedQuality) { - defaultRenderQuality = requestedQuality; + normalRenderQuality = requestedQuality; repaint(); } @@ -348,6 +439,8 @@ /** * Set the canvas cursor, and remember the previous cursor on the cursor * stack. + * + * @param cursor the cursor to push onto the cursor stack */ public void pushCursor(final Cursor cursor) { cursorStack.push(getCursor()); @@ -370,12 +463,23 @@ // they get delivered to the Piccolo framework. // **************************************************************** + /** + * Tracks whether button1 of the mouse is down. + */ private boolean isButton1Pressed; + /** + * Tracks whether button2 of the mouse is down. + */ private boolean isButton2Pressed; + /** + * Tracks whether button3 of the mouse is down. + */ private boolean isButton3Pressed; /** * Override setEnabled to install/remove canvas input sources as needed. + * + * @param enabled new enable status of the Pcanvas */ public void setEnabled(final boolean enabled) { super.setEnabled(enabled); @@ -431,14 +535,14 @@ } /** {@inheritDoc} */ - public void mousePressed(MouseEvent e) { + public void mousePressed(final MouseEvent rawEvent) { requestFocus(); boolean shouldBalanceEvent = false; - e = copyButtonsFromModifiers(e, MouseEvent.MOUSE_PRESSED); + final MouseEvent event = copyButtonsFromModifiers(rawEvent, MouseEvent.MOUSE_PRESSED); - switch (e.getButton()) { + switch (event.getButton()) { case MouseEvent.BUTTON1: if (isButton1Pressed) { shouldBalanceEvent = true; @@ -459,22 +563,25 @@ } isButton3Pressed = true; break; + default: + throw new RuntimeException("mousePressed without buttons specified"); + } if (shouldBalanceEvent) { - sendRetypedMouseEventToInputManager(e, MouseEvent.MOUSE_RELEASED); + sendRetypedMouseEventToInputManager(event, MouseEvent.MOUSE_RELEASED); } - sendInputEventToInputManager(e, MouseEvent.MOUSE_PRESSED); + sendInputEventToInputManager(event, MouseEvent.MOUSE_PRESSED); } /** {@inheritDoc} */ - public void mouseReleased(MouseEvent e) { + public void mouseReleased(final MouseEvent rawEvent) { boolean shouldBalanceEvent = false; - e = copyButtonsFromModifiers(e, MouseEvent.MOUSE_RELEASED); + final MouseEvent event = copyButtonsFromModifiers(rawEvent, MouseEvent.MOUSE_RELEASED); - switch (e.getButton()) { + switch (event.getButton()) { case MouseEvent.BUTTON1: if (!isButton1Pressed) { shouldBalanceEvent = true; @@ -495,13 +602,15 @@ } isButton3Pressed = false; break; + default: + throw new RuntimeException("mouseReleased without buttons specified"); } if (shouldBalanceEvent) { - sendRetypedMouseEventToInputManager(e, MouseEvent.MOUSE_PRESSED); + sendRetypedMouseEventToInputManager(event, MouseEvent.MOUSE_PRESSED); } - sendInputEventToInputManager(e, MouseEvent.MOUSE_RELEASED); + sendInputEventToInputManager(event, MouseEvent.MOUSE_RELEASED); } private boolean isAnyButtonDown(final MouseEvent e) { @@ -612,15 +721,33 @@ keyEventPostProcessor = null; } - protected void sendInputEventToInputManager(final InputEvent e, final int type) { - getRoot().getDefaultInputManager().processEventFromCamera(e, type, getCamera()); + /** + * Sends the given input event with the given type to the current + * InputManager. + * + * @param event event to dispatch + * @param type type of event being dispatched + */ + protected void sendInputEventToInputManager(final InputEvent event, final int type) { + getRoot().getDefaultInputManager().processEventFromCamera(event, type, getCamera()); } - public void setBounds(final int x, final int y, final int w, final int h) { - camera.setBounds(camera.getX(), camera.getY(), w, h); - super.setBounds(x, y, w, h); + /** + * Updates the bounds of the component and updates the camera accordingly. + * + * @param x left of bounds + * @param y top of bounds + * @param width width of bounds + * @param height height of bounds + */ + public void setBounds(final int x, final int y, final int width, final int height) { + camera.setBounds(camera.getX(), camera.getY(), width, height); + super.setBounds(x, y, width, height); } + /** + * {@inheritDoc} + */ public void repaint(final PBounds bounds) { PDebug.processRepaint(); @@ -630,6 +757,9 @@ repaint((int) bounds.x, (int) bounds.y, (int) bounds.width, (int) bounds.height); } + /** + * {@inheritDoc} + */ public void paintComponent(final Graphics g) { PDebug.startProcessingOutput(); @@ -655,7 +785,7 @@ } } else { - paintContext.setRenderQuality(defaultRenderQuality); + paintContext.setRenderQuality(normalRenderQuality); } // paint piccolo @@ -673,6 +803,10 @@ PDebug.endProcessingOutput(g2); } + /** + * If not painting immediately, send paint notification to RepaintManager, + * otherwise does nothing. + */ public void paintImmediately() { if (paintingImmediately) { return; @@ -683,22 +817,62 @@ paintingImmediately = false; } + /** + * Helper for creating a timer. It's an extension point for subclasses to + * install their own timers. + * + * @param delay the number of milliseconds to wait before invoking the + * listener + * @param listener the listener to invoke after the delay + * + * @return the created Timer + */ public Timer createTimer(final int delay, final ActionListener listener) { return new Timer(delay, listener); } + /** + * Returns the quality to use when not animating or interacting. + * + * @deprecated in favor or getNormalRenderQuality + * @return the render quality to use when not animating or interacting + */ public int getDefaultRenderQuality() { - return defaultRenderQuality; + return normalRenderQuality; } + /** + * Returns the quality to use when not animating or interacting. + * + * @return the render quality to use when not animating or interacting + */ + public int getNormalRenderQuality() { + return normalRenderQuality; + } + + /** + * Returns the quality to use when animating. + * + * @return Returns the quality to use when animating + */ public int getAnimatingRenderQuality() { return animatingRenderQuality; } + /** + * Returns the quality to use when interacting. + * + * @return Returns the quality to use when interacting + */ public int getInteractingRenderQuality() { return interactingRenderQuality; } + /** + * Returns the input event listeners registered to receive input events. + * + * @return array or input event listeners + */ public PInputEventListener[] getInputEventListeners() { return camera.getInputEventListeners(); } diff --git a/core/src/main/java/edu/umd/cs/piccolo/PComponent.java b/core/src/main/java/edu/umd/cs/piccolo/PComponent.java index df4ab87..20e9854 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/PComponent.java +++ b/core/src/main/java/edu/umd/cs/piccolo/PComponent.java @@ -41,13 +41,37 @@ */ public interface PComponent { - public void repaint(PBounds bounds); + /** + * Called to notify PComponent that given bounds need repainting. + * + * @param bounds bounds needing repaint + */ + void repaint(PBounds bounds); - public void paintImmediately(); + /** + * Sends a repaint notification the repaint manager if PComponent is not + * already painting immediately. + */ + void paintImmediately(); - public void pushCursor(Cursor cursor); + /** + * Pushes the given cursor onto the cursor stack and sets the current cursor + * to the one provided. + * + * @param cursor The cursor to set as the current one and push + */ + void pushCursor(Cursor cursor); - public void popCursor(); + /** + * Pops the topmost cursor from the stack and sets it as the current one. + */ + void popCursor(); - public void setInteracting(boolean interacting); + /** + * Sets whether the component is currently being interacted with. + * + * @param interacting whether the component is currently being interacted + * with + */ + void setInteracting(boolean interacting); } diff --git a/core/src/main/java/edu/umd/cs/piccolo/PInputManager.java b/core/src/main/java/edu/umd/cs/piccolo/PInputManager.java index 896f701..095d6a5 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/PInputManager.java +++ b/core/src/main/java/edu/umd/cs/piccolo/PInputManager.java @@ -52,21 +52,64 @@ */ public class PInputManager extends PBasicInputEventHandler implements PRoot.InputSource { + /** + * Records the last known mouse position on the canvas. + */ private final Point2D lastCanvasPosition; + + /** + * Records the current known mouse position on the canvas. + */ private final Point2D currentCanvasPosition; + /** + * The next InputEvent that needs to be processed. + */ private InputEvent nextInput; + + /** + * The type of the next InputEvent that needs to be processed. + */ private int nextType; + + /** + * The Input Source the next event to process came from. + */ private PCamera nextInputSource; + /** + * The current mouse focus. + */ private PPickPath mouseFocus; + + /** + * The previous mouse focus. + */ private PPickPath previousMouseFocus; + + /** + * Tracks where the mouse is right now on the canvas. + */ private PPickPath mouseOver; + + /** + * Tracks the previous location of the mouse on the canvas. + */ private PPickPath previousMouseOver; + + /** + * Tracks the input event listener that should receive keyboard events. + */ private PInputEventListener keyboardFocus; - private int pressedCount; + /** + * Tracks the number mouse buttons currently pressed. + */ + private int buttonsPressed; + /** + * Creates a PInputManager and sets last positions to the origin (0,0). + */ public PInputManager() { super(); lastCanvasPosition = new Point2D.Double(); @@ -80,6 +123,8 @@ /** * Return the node that currently has the keyboard focus. This node receives * the key events. + * + * @return the current keyboard focus */ public PInputEventListener getKeyboardFocus() { return keyboardFocus; @@ -87,6 +132,8 @@ /** * Set the node that should receive key events. + * + * @param eventHandler sets the keyboard event focus, may be null */ public void setKeyboardFocus(final PInputEventListener eventHandler) { final PInputEvent focusEvent = new PInputEvent(this, null); @@ -103,15 +150,23 @@ } /** - * Return the node that currently has the mouse focus. This will return the - * node that received the current mouse pressed event, or null if the mouse + * Return the current Pick Path under the mouse focus. This will return the + * path that received the current mouse pressed event, or null if the mouse * is not pressed. The mouse focus gets mouse dragged events even what the * mouse is not over the mouse focus. + * + * @return the current Pick Path under the mouse focus */ public PPickPath getMouseFocus() { return mouseFocus; } + /** + * Sets the current Pick Path under the mouse focus. The mouse focus gets + * mouse dragged events even when the mouse is not over the mouse focus. + * + * @param path the new mouse focus + */ public void setMouseFocus(final PPickPath path) { previousMouseFocus = mouseFocus; mouseFocus = path; @@ -119,19 +174,36 @@ /** * Return the node the the mouse is currently over. + * + * @return the path over which the mouse currently is */ public PPickPath getMouseOver() { return mouseOver; } + /** + * Records the path which is directly below the mouse. + * + * @param path path over which the mouse has been moved + */ public void setMouseOver(final PPickPath path) { mouseOver = path; } + /** + * Returns the position on the Canvas of the last event. + * + * @return position of last canvas event + */ public Point2D getLastCanvasPosition() { return lastCanvasPosition; } + /** + * Returns the position of the current canvas event. + * + * @return position of current canvas event + */ public Point2D getCurrentCanvasPosition() { return currentCanvasPosition; } @@ -144,88 +216,121 @@ // focus nodes. // **************************************************************** + /** {@inheritDoc} */ public void keyPressed(final PInputEvent event) { dispatchEventToListener(event, KeyEvent.KEY_PRESSED, keyboardFocus); } + /** {@inheritDoc} */ public void keyReleased(final PInputEvent event) { dispatchEventToListener(event, KeyEvent.KEY_RELEASED, keyboardFocus); } + /** {@inheritDoc} */ public void keyTyped(final PInputEvent event) { dispatchEventToListener(event, KeyEvent.KEY_TYPED, keyboardFocus); } + /** {@inheritDoc} */ public void mouseClicked(final PInputEvent event) { dispatchEventToListener(event, MouseEvent.MOUSE_CLICKED, previousMouseFocus); } + /** {@inheritDoc} */ public void mouseWheelRotated(final PInputEvent event) { setMouseFocus(getMouseOver()); dispatchEventToListener(event, MouseWheelEvent.WHEEL_UNIT_SCROLL, mouseOver); } + /** {@inheritDoc} */ public void mouseWheelRotatedByBlock(final PInputEvent event) { setMouseFocus(getMouseOver()); dispatchEventToListener(event, MouseWheelEvent.WHEEL_BLOCK_SCROLL, mouseOver); } + /** {@inheritDoc} */ public void mouseDragged(final PInputEvent event) { checkForMouseEnteredAndExited(event); dispatchEventToListener(event, MouseEvent.MOUSE_DRAGGED, mouseFocus); } + /** {@inheritDoc} */ public void mouseEntered(final PInputEvent event) { dispatchEventToListener(event, MouseEvent.MOUSE_ENTERED, mouseOver); } + /** {@inheritDoc} */ public void mouseExited(final PInputEvent event) { dispatchEventToListener(event, MouseEvent.MOUSE_EXITED, previousMouseOver); } + /** {@inheritDoc} */ public void mouseMoved(final PInputEvent event) { checkForMouseEnteredAndExited(event); dispatchEventToListener(event, MouseEvent.MOUSE_MOVED, mouseOver); } + /** {@inheritDoc} */ public void mousePressed(final PInputEvent event) { - if (pressedCount == 0) { + if (buttonsPressed == 0) { setMouseFocus(getMouseOver()); } - pressedCount++; + buttonsPressed++; dispatchEventToListener(event, MouseEvent.MOUSE_PRESSED, mouseFocus); - if (pressedCount < 1 || pressedCount > 3) { - System.err.println("invalid pressedCount on mouse pressed: " + pressedCount); + if (buttonsPressed < 1 || buttonsPressed > 3) { + System.err.println("invalid pressedCount on mouse pressed: " + buttonsPressed); } } + /** {@inheritDoc} */ public void mouseReleased(final PInputEvent event) { - pressedCount--; + buttonsPressed--; checkForMouseEnteredAndExited(event); dispatchEventToListener(event, MouseEvent.MOUSE_RELEASED, mouseFocus); - if (pressedCount == 0) { + if (buttonsPressed == 0) { setMouseFocus(null); } - if (pressedCount < 0 || pressedCount > 2) { - System.err.println("invalid pressedCount on mouse released: " + pressedCount); + if (buttonsPressed < 0 || buttonsPressed > 2) { + System.err.println("invalid pressedCount on mouse released: " + buttonsPressed); } } + /** + * Fires events whenever the mouse moves from PNode to PNode. + * + * @param event to check to see if the top node has changed. + */ protected void checkForMouseEnteredAndExited(final PInputEvent event) { - final PNode c = mouseOver != null ? mouseOver.getPickedNode() : null; - final PNode p = previousMouseOver != null ? previousMouseOver.getPickedNode() : null; + final PNode currentNode = getPickedNode(mouseOver); + final PNode previousNode = getPickedNode(previousMouseOver); - if (c != p) { + if (currentNode != previousNode) { dispatchEventToListener(event, MouseEvent.MOUSE_EXITED, previousMouseOver); dispatchEventToListener(event, MouseEvent.MOUSE_ENTERED, mouseOver); previousMouseOver = mouseOver; } } + /** + * Returns picked node on pickPath if pickPath is not null, or null. + * + * @param pickPath from which to extract picked node + * + * @return the picked node or null if pickPath is null + */ + private PNode getPickedNode(final PPickPath pickPath) { + if (pickPath == null) { + return null; + } + else { + return pickPath.getPickedNode(); + } + } + // **************************************************************** // Event Dispatch. // **************************************************************** - + /** {@inheritDoc} */ public void processInput() { if (nextInput == null) { return; @@ -265,6 +370,13 @@ } } + /** + * Flags the given event as needing to be processed. + * + * @param event the event to be processed + * @param type type of event to be processed + * @param camera camera from which the event was dispatched + */ public void processEventFromCamera(final InputEvent event, final int type, final PCamera camera) { // queue input nextInput = event; @@ -275,6 +387,14 @@ camera.getRoot().processInputs(); } + /** + * Dispatches the given event to the listener, or does nothing if listener + * is null. + * + * @param event event to be dispatched + * @param type type of event to dispatch + * @param listener target of dispatch + */ private void dispatchEventToListener(final PInputEvent event, final int type, final PInputEventListener listener) { if (listener != null) { // clear the handled bit since the same event object is used to send diff --git a/core/src/main/java/edu/umd/cs/piccolo/PLayer.java b/core/src/main/java/edu/umd/cs/piccolo/PLayer.java index 845346a..29bcdcb 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/PLayer.java +++ b/core/src/main/java/edu/umd/cs/piccolo/PLayer.java @@ -68,10 +68,24 @@ * of cameras, but old value will always be null. */ public static final String PROPERTY_CAMERAS = "cameras"; + + /** + * The property code that identifies a change in the set of this layer's + * cameras (see {@link #getCamera getCamera}, {@link #getCameraCount + * getCameraCount}, {@link #getCamerasReference getCamerasReference}). In + * any property change event the new value will be a reference to the list + * of cameras, but old value will always be null. + */ public static final int PROPERTY_CODE_CAMERAS = 1 << 13; + /** + * Cameras which are registered as viewers of this PLayer. + */ private transient List cameras; + /** + * Creates a PLayer without any cameras attached to it. + */ public PLayer() { super(); cameras = new ArrayList(); @@ -84,6 +98,8 @@ /** * Get the list of cameras viewing this layer. + * + * @return direct reference to registered cameras */ public List getCamerasReference() { return cameras; @@ -91,6 +107,8 @@ /** * Get the number of cameras viewing this layer. + * + * @return the number of cameras attached to this layer */ public int getCameraCount() { if (cameras == null) { @@ -101,6 +119,9 @@ /** * Get the camera in this layer's camera list at the specified index. + * + * @param index index of camera to fetch + * @return camera at the given index */ public PCamera getCamera(final int index) { return (PCamera) cameras.get(index); @@ -109,6 +130,8 @@ /** * Add a camera to this layer's camera list. This method it called * automatically when a layer is added to a camera. + * + * @param camera the camera to add to this layer */ public void addCamera(final PCamera camera) { addCamera(cameras.size(), camera); @@ -117,6 +140,9 @@ /** * Add a camera to this layer's camera list at the specified index. This * method it called automatically when a layer is added to a camera. + * + * @param index index at which the camera should be inserted + * @param camera Camera to add to layer */ public void addCamera(final int index, final PCamera camera) { cameras.add(index, camera); @@ -126,6 +152,10 @@ /** * Remove the camera from this layer's camera list. + * + * @param camera the camera to remove from the layer, does nothing if not + * found + * @return camera that was passed in */ public PCamera removeCamera(final PCamera camera) { if (cameras.remove(camera)) { @@ -137,6 +167,10 @@ /** * Remove the camera at the given index from this layer's camera list. + * + * @param index the index of the camera we wish to remove + * + * @return camera that was removed */ public PCamera removeCamera(final int index) { final PCamera result = (PCamera) cameras.remove(index); @@ -154,19 +188,27 @@ /** * Override repaints and forward them to the cameras that are viewing this * layer. + * + * @param localBounds bounds flagged as needing repainting + * @param repaintSource the source of the repaint notification */ - public void repaintFrom(final PBounds localBounds, final PNode childOrThis) { - if (childOrThis != this) { + public void repaintFrom(final PBounds localBounds, final PNode repaintSource) { + if (repaintSource != this) { localToParent(localBounds); } notifyCameras(localBounds); if (getParent() != null) { - getParent().repaintFrom(localBounds, childOrThis); + getParent().repaintFrom(localBounds, repaintSource); } } + /** + * Dispatches repaint notification to all registered cameras. + * + * @param parentBounds bounds needing repainting in parent coordinate system + */ protected void notifyCameras(final PBounds parentBounds) { final int count = getCameraCount(); for (int i = 0; i < count; i++) { @@ -187,8 +229,14 @@ * the layer writes out any cameras that are viewing it conditionally, so * they will only get written out if someone else writes them * unconditionally. + * + * @param out object to which the layer should be streamed + * @throws IOException may occur while serializing to stream */ private void writeObject(final ObjectOutputStream out) throws IOException { + if (!(out instanceof PObjectOutputStream)) { + throw new RuntimeException("May not serialize PLayer to a non PObjectOutputStream"); + } out.defaultWriteObject(); final int count = getCameraCount(); @@ -199,6 +247,15 @@ out.writeObject(Boolean.FALSE); } + /** + * Deserializes PLayer from the provided ObjectInputStream. + * + * @param in stream from which PLayer should be read + * + * @throws IOException since it involves quite a bit of IO + * @throws ClassNotFoundException may occur is serialized stream has been + * renamed after serialization + */ private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); diff --git a/core/src/main/java/edu/umd/cs/piccolo/PNode.java b/core/src/main/java/edu/umd/cs/piccolo/PNode.java index efb39ee..61f7ad5 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/PNode.java +++ b/core/src/main/java/edu/umd/cs/piccolo/PNode.java @@ -109,6 +109,13 @@ * client properties but old value will always be null. */ public static final String PROPERTY_CLIENT_PROPERTIES = "clientProperties"; + + /** + * The property code that identifies a change in this node's client + * propertie (see {@link #getClientProperty getClientProperty}). In an + * property change event the new value will be a reference to the map of + * client properties but old value will always be null. + */ public static final int PROPERTY_CODE_CLIENT_PROPERTIES = 1 << 0; /** @@ -118,6 +125,13 @@ * a reference to this node's bounds, but old value will always be null. */ public static final String PROPERTY_BOUNDS = "bounds"; + + /** + * The property code that identifies a change of this node's bounds (see + * {@link #getBounds getBounds}, {@link #getBoundsReference + * getBoundsReference}). In any property change event the new value will be + * a reference to this node's bounds, but old value will always be null. + */ public static final int PROPERTY_CODE_BOUNDS = 1 << 1; /** @@ -128,6 +142,14 @@ * cache, but old value will always be null. */ public static final String PROPERTY_FULL_BOUNDS = "fullBounds"; + + /** + * The property code that identifies a change of this node's full bounds + * (see {@link #getFullBounds getFullBounds}, + * {@link #getFullBoundsReference getFullBoundsReference}). In any property + * change event the new value will be a reference to this node's full bounds + * cache, but old value will always be null. + */ public static final int PROPERTY_CODE_FULL_BOUNDS = 1 << 2; /** @@ -138,6 +160,14 @@ * null. */ public static final String PROPERTY_TRANSFORM = "transform"; + + /** + * The property code that identifies a change of this node's transform (see + * {@link #getTransform getTransform}, {@link #getTransformReference + * getTransformReference}). In any property change event the new value will + * be a reference to this node's transform, but old value will always be + * null. + */ public static final int PROPERTY_CODE_TRANSFORM = 1 << 3; /** @@ -146,6 +176,12 @@ * null in any property change event. */ public static final String PROPERTY_VISIBLE = "visible"; + + /** + * The property code that identifies a change of this node's visibility (see + * {@link #getVisible getVisible}). Both old value and new value will be + * null in any property change event. + */ public static final int PROPERTY_CODE_VISIBLE = 1 << 4; /** @@ -154,6 +190,12 @@ * correctly in any property change event. */ public static final String PROPERTY_PAINT = "paint"; + + /** + * The property code that identifies a change of this node's paint (see + * {@link #getPaint getPaint}). Both old value and new value will be set + * correctly in any property change event. + */ public static final int PROPERTY_CODE_PAINT = 1 << 5; /** @@ -162,6 +204,12 @@ * value will be null in any property change event. */ public static final String PROPERTY_TRANSPARENCY = "transparency"; + + /** + * The property code that identifies a change of this node's transparency + * (see {@link #getTransparency getTransparency}). Both old value and new + * value will be null in any property change event. + */ public static final int PROPERTY_CODE_TRANSPARENCY = 1 << 6; /** @@ -170,6 +218,11 @@ * be null in any property change event. */ public static final String PROPERTY_PICKABLE = "pickable"; + /** + * The property code that identifies a change of this node's pickable status + * (see {@link #getPickable getPickable}). Both old value and new value will + * be null in any property change event. + */ public static final int PROPERTY_CODE_PICKABLE = 1 << 7; /** @@ -178,6 +231,12 @@ * Both old value and new value will be null in any property change event. */ public static final String PROPERTY_CHILDREN_PICKABLE = "childrenPickable"; + + /** + * The property code that identifies a change of this node's children + * pickable status (see {@link #getChildrenPickable getChildrenPickable}). + * Both old value and new value will be null in any property change event. + */ public static final int PROPERTY_CODE_CHILDREN_PICKABLE = 1 << 8; /** @@ -188,6 +247,14 @@ * value will always be null. */ public static final String PROPERTY_CHILDREN = "children"; + + /** + * The property code that identifies a change in the set of this node's + * direct children (see {@link #getChildrenReference getChildrenReference}, + * {@link #getChildrenIterator getChildrenIterator}). In any property change + * event the new value will be a reference to this node's children, but old + * value will always be null. + */ public static final int PROPERTY_CODE_CHILDREN = 1 << 9; /** @@ -196,8 +263,17 @@ * correctly in any property change event. */ public static final String PROPERTY_PARENT = "parent"; + + /** + * The property code that identifies a change of this node's parent (see + * {@link #getParent getParent}). Both old value and new value will be set + * correctly in any property change event. + */ public static final int PROPERTY_CODE_PARENT = 1 << 10; + /** + * Is an optimization for use during repaints + */ private static final PBounds TEMP_REPAINT_BOUNDS = new PBounds(); /** @@ -206,57 +282,119 @@ public static PSceneGraphDelegate SCENE_GRAPH_DELEGATE = null; /** - * PSceneGraphDelegate is an interface to recive low level node - * events. It together with PNode.SCENE_GRAPH_DELEGATE gives Piccolo users - * an efficient way to learn about low level changes in Piccolo's scene - * graph. Most users will not need to use this. + * Tracks the parent of this node, may be null. */ - public interface PSceneGraphDelegate { - public void nodePaintInvalidated(PNode node); - - public void nodeFullBoundsInvalidated(PNode node); - } - private transient PNode parent; + /** + * Tracks all immediate child nodes. + */ private List children; + /** + * Bounds of the PNode. + */ private final PBounds bounds; - private PAffineTransform transform; - private Paint paint; - private float transparency; - private MutableAttributeSet clientProperties; - private PBounds fullBoundsCache; - - private int propertyChangeParentMask = 0; - private transient SwingPropertyChangeSupport changeSupport; - private transient EventListenerList listenerList; - - private boolean pickable; - private boolean childrenPickable; - private boolean visible; - private boolean childBoundsVolatile; - private boolean paintInvalid; - private boolean childPaintInvalid; - private boolean boundsChanged; - private boolean fullBoundsInvalid; - private boolean childBoundsInvalid; - private boolean occluded; - - private String name; - - public void setName(final String name) { - this.name = name; - } - - public String getName() { - return name; - } /** - * Calls {@link PNode} followed by {@link PNode#setName(String)}. + * Transform that applies to this node in relation to its parent. */ - public PNode(final String name) { + private PAffineTransform transform; + + /** + * The paint to use for the background of this node. + */ + private Paint paint; + + /** + * How Opaque this node should be 1f = fully opaque, 0f = completely + * transparent. + */ + private float transparency; + + /** + * A modifiable set of client properties. + */ + private MutableAttributeSet clientProperties; + + /** + * An optimization that remembers the full bounds of a node rather than + * computing it every time. + */ + private PBounds fullBoundsCache; + + /** + * Mask used when deciding whether to bubble up property change events to + * parents. + */ + private int propertyChangeParentMask = 0; + + /** + * Used to handle property change listeners. + */ + private transient SwingPropertyChangeSupport changeSupport; + + /** + * List of event listeners. + */ + private transient EventListenerList listenerList; + + /** + * Whether this node is pickable or not. + */ + private boolean pickable; + + /** + * Whether to stop processing pick at this node and not bother drilling down + * into children. + */ + private boolean childrenPickable; + + /** + * Whether this node will be rendered. + */ + private boolean visible; + + private boolean childBoundsVolatile; + + /** + * Whether this node needs to be repainted. + */ + private boolean paintInvalid; + + /** + * Whether children need to be repainted. + */ + private boolean childPaintInvalid; + + /** + * Whether this node's bounds have changed, and so needs to be relaid out. + */ + private boolean boundsChanged; + + /** + * Whether this node's full bounds need to be recomputed. + */ + private boolean fullBoundsInvalid; + + /** + * Whether this node's child bounds need to be recomputed. + */ + private boolean childBoundsInvalid; + + private boolean occluded; + + /** + * Stores the name associated to this node. + */ + private String name; + + /** + * Creates a new PNode with the given name. + * + * @param newName name to assign to node + */ + public PNode(final String newName) { this(); - setName(name); + setName(newName); } /** @@ -300,6 +438,10 @@ * change the node's transform. Use animateTransformToBounds() to animate * the node's transform instead. * + * @param x left of target bounds + * @param y top of target bounds + * @param width width of target bounds + * @param height height of target bounds * @param duration amount of time that the animation should take * @return the newly scheduled activity */ @@ -309,33 +451,33 @@ setBounds(x, y, width, height); return null; } - else { - final PBounds dst = new PBounds(x, y, width, height); - final PInterpolatingActivity ta = new PInterpolatingActivity(duration, PUtil.DEFAULT_ACTIVITY_STEP_RATE) { - private PBounds src; + final PBounds dst = new PBounds(x, y, width, height); - protected void activityStarted() { - src = getBounds(); - startResizeBounds(); - super.activityStarted(); - } + final PInterpolatingActivity interpolatingActivity = new PInterpolatingActivity(duration, + PUtil.DEFAULT_ACTIVITY_STEP_RATE) { + private PBounds src; - public void setRelativeTargetValue(final float zeroToOne) { - PNode.this.setBounds(src.x + zeroToOne * (dst.x - src.x), src.y + zeroToOne * (dst.y - src.y), - src.width + zeroToOne * (dst.width - src.width), src.height + zeroToOne - * (dst.height - src.height)); - } + protected void activityStarted() { + src = getBounds(); + startResizeBounds(); + super.activityStarted(); + } - protected void activityFinished() { - super.activityFinished(); - endResizeBounds(); - } - }; + public void setRelativeTargetValue(final float zeroToOne) { + PNode.this.setBounds(src.x + zeroToOne * (dst.x - src.x), src.y + zeroToOne * (dst.y - src.y), + src.width + zeroToOne * (dst.width - src.width), src.height + zeroToOne + * (dst.height - src.height)); + } - addActivity(ta); - return ta; - } + protected void activityFinished() { + super.activityFinished(); + endResizeBounds(); + } + }; + + addActivity(interpolatingActivity); + return interpolatingActivity; } /** @@ -351,6 +493,10 @@ * bounds rectangle. Use animateToBounds() to animate the node's bounds * rectangle instead. * + * @param x left of target bounds + * @param y top of target bounds + * @param width width of target bounds + * @param height height of target bounds * @param duration amount of time that the animation should take * @return the newly scheduled activity */ @@ -373,7 +519,10 @@ * applied last on each frame, so it will appear to have replaced the * original. Generally you will not want to do that. * + * @param x the final target x position of node + * @param y the final target y position of node * @param duration amount of time that the animation should take + * @param scale the final scale for the duration * @param theta final theta value (in radians) for the animation * @return the newly scheduled activity */ @@ -525,8 +674,10 @@ // **************************************************************** /** - * Return mutable attributed set of client properites associated with this + * Return mutable attributed set of client properties associated with this * node. + * + * @return the client properties associated to this node */ public MutableAttributeSet getClientProperties() { if (clientProperties == null) { @@ -540,6 +691,8 @@ * attributes added with addAttribute will return a non-null * value. * + * @param key key to use while fetching client attribute + * * @return the value of this attribute or null */ public Object getAttribute(final Object key) { @@ -554,11 +707,14 @@ /** * Add an arbitrary key/value to this node. *

- * The get/add attribute methods provide access to - * a small per-instance attribute set. Callers can use get/add attribute - * to annotate nodes that were created by another module. + * The get/add attribute methods provide access to a small + * per-instance attribute set. Callers can use get/add attribute to annotate + * nodes that were created by another module. *

* If value is null this method will remove the attribute. + * + * @param key to use when adding the attribute + * @param value value to associate to the new attribute */ public void addAttribute(final Object key, final Object value) { if (value == null && clientProperties == null) { @@ -604,28 +760,83 @@ // convenience methods for attributes - public Object getAttribute(final Object key, final Object def) { - final Object o = getAttribute(key); - return o == null ? def : o; + /** + * Fetches the value of the requested attribute, returning defaultValue is + * not found. + * + * @param key attribute to search for + * @param defaultValue value to return if attribute is not found + * + * @return value of attribute or defaultValue if not found + */ + public Object getAttribute(final Object key, final Object defaultValue) { + final Object value = getAttribute(key); + if (value == null) { + return defaultValue; + } + + return value; } - public boolean getBooleanAttribute(final Object key, final boolean def) { - final Boolean b = (Boolean) getAttribute(key); - return b == null ? def : b.booleanValue(); + /** + * Fetches the boolean value of the requested attribute, returning + * defaultValue is not found. + * + * @param key attribute to search for + * @param defaultValue value to return if attribute is not found + * + * @return value of attribute or defaultValue if not found + */ + public boolean getBooleanAttribute(final Object key, final boolean defaultValue) { + final Boolean value = (Boolean) getAttribute(key); + if (value == null) { + return defaultValue; + } + + return value.booleanValue(); } - public int getIntegerAttribute(final Object key, final int def) { - final Number n = (Number) getAttribute(key); - return n == null ? def : n.intValue(); + /** + * Fetches the integer value of the requested attribute, returning + * defaultValue is not found. + * + * @param key attribute to search for + * @param defaultValue value to return if attribute is not found + * + * @return value of attribute or defaultValue if not found + */ + public int getIntegerAttribute(final Object key, final int defaultValue) { + final Number value = (Number) getAttribute(key); + if (value == null) { + return defaultValue; + } + + return value.intValue(); } - public double getDoubleAttribute(final Object key, final double def) { - final Number n = (Number) getAttribute(key); - return n == null ? def : n.doubleValue(); + /** + * Fetches the double value of the requested attribute, returning + * defaultValue is not found. + * + * @param key attribute to search for + * @param defaultValue value to return if attribute is not found + * + * @return value of attribute or defaultValue if not found + */ + public double getDoubleAttribute(final Object key, final double defaultValue) { + final Number value = (Number) getAttribute(key); + if (value == null) { + return defaultValue; + } + + return value.doubleValue(); } /** * @deprecated use getAttribute(Object key)instead. + * + * @param key name of property to search for + * @return value of matching client property */ public Object getClientProperty(final Object key) { return getAttribute(key); @@ -633,6 +844,9 @@ /** * @deprecated use addAttribute(Object key, Object value)instead. + * + * @param key name of property to add + * @param value value or new attribute */ public void addClientProperty(final Object key, final Object value) { addAttribute(key, value); @@ -640,6 +854,8 @@ /** * @deprecated use getClientPropertyKeysEnumerator() instead. + * + * @return iterator for client property keys */ public Iterator getClientPropertyKeysIterator() { final Enumeration enumeration = getClientPropertyKeysEnumeration(); @@ -822,10 +1038,10 @@ * @param localPoint point in local coordinate system to be transformed. * @return point in global coordinates */ - public Point2D localToGlobal(Point2D localPoint) { + public Point2D localToGlobal(final Point2D localPoint) { PNode n = this; while (n != null) { - localPoint = n.localToParent(localPoint); + n.localToParent(localPoint); n = n.parent; } return localPoint; @@ -840,10 +1056,10 @@ * transformed. * @return dimension in global coordinates */ - public Dimension2D localToGlobal(Dimension2D localDimension) { + public Dimension2D localToGlobal(final Dimension2D localDimension) { PNode n = this; while (n != null) { - localDimension = n.localToParent(localDimension); + n.localToParent(localDimension); n = n.parent; } return localDimension; @@ -858,10 +1074,10 @@ * transformed. * @return rectangle in global coordinates */ - public Rectangle2D localToGlobal(Rectangle2D localRectangle) { + public Rectangle2D localToGlobal(final Rectangle2D localRectangle) { PNode n = this; while (n != null) { - localRectangle = n.localToParent(localRectangle); + n.localToParent(localRectangle); n = n.parent; } return localRectangle; @@ -874,9 +1090,9 @@ * @param globalPoint point in global coordinates to be transformed. * @return point in this node's local coordinate system. */ - public Point2D globalToLocal(Point2D globalPoint) { + public Point2D globalToLocal(final Point2D globalPoint) { if (parent != null) { - globalPoint = parent.globalToLocal(globalPoint); + parent.globalToLocal(globalPoint); } return parentToLocal(globalPoint); } @@ -889,9 +1105,9 @@ * @param globalDimension dimension in global coordinates to be transformed. * @return dimension in this node's local coordinate system. */ - public Dimension2D globalToLocal(Dimension2D globalDimension) { + public Dimension2D globalToLocal(final Dimension2D globalDimension) { if (parent != null) { - globalDimension = parent.globalToLocal(globalDimension); + parent.globalToLocal(globalDimension); } return parentToLocal(globalDimension); } @@ -904,9 +1120,9 @@ * @param globalRectangle rectangle in global coordinates to be transformed. * @return rectangle in this node's local coordinate system. */ - public Rectangle2D globalToLocal(Rectangle2D globalRectangle) { + public Rectangle2D globalToLocal(final Rectangle2D globalRectangle) { if (parent != null) { - globalRectangle = parent.globalToLocal(globalRectangle); + parent.globalToLocal(globalRectangle); } return parentToLocal(globalRectangle); } @@ -915,6 +1131,7 @@ * Return the transform that converts local coordinates at this node to the * global coordinate system. * + * @param dest PAffineTransform to transform to global coordinates * @return The concatenation of transforms from the top node down to this * node. */ @@ -925,19 +1142,16 @@ dest.concatenate(transform); } } - else { - if (dest == null) { - dest = getTransform(); - } - else { - if (transform != null) { - dest.setTransform(transform); - } - else { - dest.setToIdentity(); - } - } + else if (dest == null) { + dest = getTransform(); } + else if (transform != null) { + dest.setTransform(transform); + } + else { + dest.setToIdentity(); + } + return dest; } @@ -945,6 +1159,8 @@ * Return the transform that converts global coordinates to local * coordinates of this node. * + * @param dest PAffineTransform to transform from global to local + * * @return The inverse of the concatenation of transforms from the root down * to this node. */ @@ -1073,6 +1289,9 @@ * Return the propertyChangeParentMask that determines which property change * events are forwared to this nodes parent so that its property change * listeners will also be notified. + * + * @return mask used for deciding whether to bubble property changes up to + * parent */ public int getPropertyChangeParentMask() { return propertyChangeParentMask; @@ -1082,9 +1301,11 @@ * Set the propertyChangeParentMask that determines which property change * events are forwared to this nodes parent so that its property change * listeners will also be notified. + * + * @param newPropertyChangeParentMask new mask for property change bubble up */ - public void setPropertyChangeParentMask(final int propertyChangeParentMask) { - this.propertyChangeParentMask = propertyChangeParentMask; + public void setPropertyChangeParentMask(final int newPropertyChangeParentMask) { + this.propertyChangeParentMask = newPropertyChangeParentMask; } /** @@ -1094,8 +1315,7 @@ * also be fired on this nodes parent. * * @param propertyCode The code of the property changed. - * @param propertyName The programmatic name of the property that was - * changed. + * @param propertyName The name of the property that was changed. * @param oldValue The old value of the property. * @param newValue The new value of the property. */ @@ -1159,6 +1379,8 @@ * Return a copy of this node's bounds. These bounds are stored in the local * coordinate system of this node and do not include the bounds of any of * this node's children. + * + * @return copy of this node's local bounds */ public PBounds getBounds() { return (PBounds) getBoundsReference().clone(); @@ -1169,6 +1391,8 @@ * in the local coordinate system of this node and do not include the bounds * of any of this node's children. The value returned should not be * modified. + * + * @return direct reference to local bounds */ public PBounds getBoundsReference() { return bounds; @@ -1189,18 +1413,48 @@ public void endResizeBounds() { } + /** + * Set's this node's bounds left position, leaving y, width, and height + * unchanged. + * + * @param x new x position of bounds + * + * @return whether the change was successful + */ public boolean setX(final double x) { return setBounds(x, getY(), getWidth(), getHeight()); } + /** + * Set's this node's bounds top position, leaving x, width, and height + * unchanged. + * + * @param y new y position of bounds + * + * @return whether the change was successful + */ public boolean setY(final double y) { return setBounds(getX(), y, getWidth(), getHeight()); } + /** + * Set's this node's bounds width, leaving x, y, and height unchanged. + * + * @param width new width position of bounds + * + * @return whether the change was successful + */ public boolean setWidth(final double width) { return setBounds(getX(), getY(), width, getHeight()); } + /** + * Set's this node's bounds height, leaving x, y, and width unchanged. + * + * @param height new height position of bounds + * + * @return whether the change was successful + */ public boolean setHeight(final double height) { return setBounds(getX(), getY(), getWidth(), height); } @@ -1209,6 +1463,8 @@ * Set the bounds of this node to the given value. These bounds are stored * in the local coordinate system of this node. * + * @param newBounds bounds to apply to this node + * * @return true if the bounds changed. */ public boolean setBounds(final Rectangle2D newBounds) { @@ -1224,6 +1480,11 @@ * * Subclasses must call the super.setBounds() method. * + * @param x x position of bounds + * @param y y position of bounds + * @param width width to apply to the bounds + * @param height height to apply to the bounds + * * @return true if the bounds changed. */ public boolean setBounds(final double x, final double y, final double width, final double height) { @@ -1253,6 +1514,11 @@ * bounds field will contain the new value. * * See PPath for an example that uses this method. + * + * @param x x position of bounds + * @param y y position of bounds + * @param width width to apply to the bounds + * @param height height to apply to the bounds */ protected void internalUpdateBounds(final double x, final double y, final double width, final double height) { } @@ -1266,6 +1532,8 @@ /** * Return the x position (in local coords) of this node's bounds. + * + * @return local x position of bounds */ public double getX() { return getBoundsReference().getX(); @@ -1273,6 +1541,8 @@ /** * Return the y position (in local coords) of this node's bounds. + * + * @return local y position of bounds */ public double getY() { return getBoundsReference().getY(); @@ -1280,6 +1550,8 @@ /** * Return the width (in local coords) of this node's bounds. + * + * @return local width of bounds */ public double getWidth() { return getBoundsReference().getWidth(); @@ -1287,6 +1559,8 @@ /** * Return the height (in local coords) of this node's bounds. + * + * @return local width of bounds */ public double getHeight() { return getBoundsReference().getHeight(); @@ -1303,9 +1577,12 @@ /** * Center the bounds of this node so that they are centered on the given - * point specified on the local coords of this node. Note that this meathod - * will modify the nodes bounds, while centerFullBoundsOnPoint will modify - * the nodes transform. + * point specified on the local coordinates of this node. Note that this + * method will modify the nodes bounds, while centerFullBoundsOnPoint will + * modify the nodes transform. + * + * @param localX x position of point around which to center bounds + * @param localY y position of point around which to center bounds * * @return true if the bounds changed. */ @@ -1316,10 +1593,13 @@ } /** - * Center the ffull bounds of this node so that they are centered on the - * given point specified on the local coords of this nodes parent. Note that - * this meathod will modify the nodes transform, while centerBoundsOnPoint - * will modify the nodes bounds. + * Center the full bounds of this node so that they are centered on the + * given point specified on the local coordinates of this nodes parent. Note + * that this method will modify the nodes transform, while + * centerBoundsOnPoint will modify the nodes bounds. + * + * @param parentX x position around which to center full bounds + * @param parentY y position around which to center full bounds */ public void centerFullBoundsOnPoint(final double parentX, final double parentY) { final double dx = parentX - getFullBoundsReference().getCenterX(); @@ -1405,6 +1685,7 @@ * return the results instead of creating a new PBounds. * * @param dstBounds if not null the new bounds will be stored here + * @return union of children bounds */ public PBounds getUnionOfChildrenBounds(PBounds dstBounds) { if (dstBounds == null) { @@ -3088,6 +3369,24 @@ } /** + * Sets the name of this null, may be null. + * + * @param name new name for this node + */ + public void setName(final String name) { + this.name = name; + } + + /** + * Returns the name given to this node. + * + * @return name given to this node, may be null + */ + public String getName() { + return name; + } + + /** * Return the number of children that this node has. * * @return the number of children @@ -3234,4 +3533,27 @@ } return result; } + + /** + * PSceneGraphDelegate is an interface to recive low level node + * events. It together with PNode.SCENE_GRAPH_DELEGATE gives Piccolo users + * an efficient way to learn about low level changes in Piccolo's scene + * graph. Most users will not need to use this. + */ + public interface PSceneGraphDelegate { + /** + * Called to notify delegate that the node needs repainting + * + * @param node node needing repaint + */ + public void nodePaintInvalidated(PNode node); + + /** + * Called to notify delegate that the node and all it's children need + * repainting + * + * @param node node needing repaint + */ + public void nodeFullBoundsInvalidated(PNode node); + } } diff --git a/core/src/main/java/edu/umd/cs/piccolo/PRoot.java b/core/src/main/java/edu/umd/cs/piccolo/PRoot.java index 28a20c7..5f227f4 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/PRoot.java +++ b/core/src/main/java/edu/umd/cs/piccolo/PRoot.java @@ -84,6 +84,9 @@ * in here. */ public static interface InputSource { + /** + * Causes the system to process any pending Input Events + */ public void processInput(); } diff --git a/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java b/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java index af27386..966af9b 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java +++ b/core/src/main/java/edu/umd/cs/piccolo/activities/PTransformActivity.java @@ -113,7 +113,7 @@ public double[] getDestinationTransform() { if (destination == null) { return null; - } + } else { return (double[]) destination.clone(); } @@ -126,10 +126,10 @@ public void setDestinationTransform(final double[] newDestination) { if (newDestination == null) { destination = null; - } + } else { destination = (double[]) newDestination.clone(); - } + } } protected void activityStarted() { diff --git a/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java b/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java index 1a22847..37cb72f 100644 --- a/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java +++ b/core/src/main/java/edu/umd/cs/piccolo/util/PUtil.java @@ -254,5 +254,5 @@ } out.writeInt(PATH_TERMINATOR); - } + } } diff --git a/core/src/test/java/edu/umd/cs/piccolo/MockPCamera.java b/core/src/test/java/edu/umd/cs/piccolo/MockPCamera.java index 3daf135..797c122 100644 --- a/core/src/test/java/edu/umd/cs/piccolo/MockPCamera.java +++ b/core/src/test/java/edu/umd/cs/piccolo/MockPCamera.java @@ -8,9 +8,9 @@ import edu.umd.cs.piccolo.util.PBounds; -class MockPCamera extends PCamera { +class MockPCamera extends PCamera { private static final long serialVersionUID = 1L; - private List notifications = new ArrayList(); + private final List notifications = new ArrayList(); public void repaintFromLayer(final PBounds bounds, final PLayer layer) { notifications.add(new Notification("repaintFromLayer", bounds, layer)); @@ -42,8 +42,8 @@ return notifications.size(); } - public Notification getNotification(int i) { - return (Notification)notifications.get(i); + public Notification getNotification(final int i) { + return (Notification) notifications.get(i); } } \ No newline at end of file diff --git a/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java b/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java index 9ce2828..5a08e3f 100644 --- a/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java +++ b/core/src/test/java/edu/umd/cs/piccolo/PCanvasTest.java @@ -8,10 +8,10 @@ import edu.umd.cs.piccolo.util.PPaintContext; public class PCanvasTest extends TestCase { - private PCanvas canvas; + private PCanvas canvas; private MockPInputEventListener mockListener; - public void setUp() { + public void setUp() { canvas = new PCanvas(); mockListener = new MockPInputEventListener(); } diff --git a/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java b/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java index a3b623f..6b748f9 100644 --- a/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java +++ b/core/src/test/java/edu/umd/cs/piccolo/PLayerTest.java @@ -96,7 +96,7 @@ assertEquals(1, camera.getNotificationCount()); - final MockPCamera.Notification notification = (MockPCamera.Notification) camera.getNotification(0); + final MockPCamera.Notification notification = camera.getNotification(0); assertEquals(layer, notification.getLayer()); assertEquals(bounds, notification.getBounds()); } diff --git a/core/src/test/java/edu/umd/cs/piccolo/PNodeTest.java b/core/src/test/java/edu/umd/cs/piccolo/PNodeTest.java index c26f4c7..57dc5eb 100644 --- a/core/src/test/java/edu/umd/cs/piccolo/PNodeTest.java +++ b/core/src/test/java/edu/umd/cs/piccolo/PNodeTest.java @@ -934,6 +934,27 @@ assertEquals(2, paintCounts[0]); } + public void testSetTransparency1MeansInvisible() { + final PNode node = new PNode(); + node.setBounds(0, 0, 100, 100); + node.setVisible(true); + node.setPaint(Color.RED); + + final PCanvas canvas = buildCanvasContainingNode(node); + + final BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); + final Graphics g = GraphicsEnvironment.getLocalGraphicsEnvironment().createGraphics(img); + + canvas.paintComponent(g); + node.setTransparency(1f); + assertEquals(Color.RED.getRGB(), img.getRGB(10, 10)); + + node.setTransparency(0f); + canvas.paintComponent(g); + assertEquals(Color.WHITE.getRGB(), img.getRGB(10, 10)); + + } + private PCanvas buildCanvasContainingNode(final PNode node) { final PCanvas canvas = new PCanvas(); canvas.setSize(100, 100); diff --git a/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java b/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java index fb1811d..2505c28 100644 --- a/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java +++ b/core/src/test/java/edu/umd/cs/piccolo/nodes/PImageTest.java @@ -63,7 +63,7 @@ public void testCanBeCreatedFromFile() throws IOException { final BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB); - final File imgFile = File.createTempFile("test", ".jpeg"); + final File imgFile = File.createTempFile("test", ".jpeg"); ImageIO.write(img, "JPEG", imgFile); imgFile.deleteOnExit(); final PImage imageNode = new PImage(imgFile.getAbsolutePath()); diff --git a/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java b/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java index f5cb1b5..df90c4c 100644 --- a/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java +++ b/core/src/test/java/edu/umd/cs/piccolo/nodes/PPathTest.java @@ -76,9 +76,9 @@ final File file = File.createTempFile("test", "ser"); serializeToFile(srcPath, file); - final PPath resultPath = deserializeFromFile(srcBounds, file); + final PPath resultPath = deserializeFromFile(srcBounds, file); file.deleteOnExit(); - + assertEquals(resultPath.getBounds(), srcBounds); } @@ -87,7 +87,7 @@ PPath path; final FileInputStream fin = new FileInputStream(file); final ObjectInputStream in = new ObjectInputStream(fin); - path = (PPath) in.readObject(); + path = (PPath) in.readObject(); return path; }