Class AItem

java.lang.Object
edu.cnu.mdi.item.AItem
All Implemented Interfaces:
IFeedbackProvider, IDrawable, EventListener
Direct Known Subclasses:
AMapItem, LineItem, PathBasedItem, PointItem

public abstract class AItem extends Object implements IDrawable, IFeedbackProvider
Abstract base class for all interactive graphical items rendered on an IContainer.

Role in the MDI item model

An AItem is the fundamental unit of interactive content in MDI. It lives on a Layer, which in turn belongs to an IContainer. Items are drawn by the container's rendering pipeline, hit-tested by the interaction layer, and can be dragged, resized, rotated, selected, or deleted according to a set of independently-controllable behavior flags.

Drawing pipeline

The public entry point for drawing is draw(Graphics2D, IContainer), which is called by the container. Subclasses must not override draw; instead they implement the two abstract methods:

Behavior flags and the lock

Each interactive behavior (dragging, resizing, rotating, deleting) is individually controlled by a boolean flag. However, the _locked flag is a master override: when true it suppresses dragging, resizing, rotating, and deleting regardless of the individual flags. Locking does not suppress visibility or selection display.

Items are locked by default (_locked = true). Call setLocked(false) or supply LOCKED=false in the constructor key-value pairs to make an item interactive.

Property-based construction

The constructor accepts an optional varargs list of alternating PropertyUtils key/value pairs. These are parsed and applied by applyProperties(Properties), which covers behavior flags, style attributes, and display name. Subclasses that need geometry parameters should override applyGeometryProperties(Properties).

Geometry

AItem provides three geometry fields that subclasses may use:

Modification lifecycle

  1. setModification(ItemModification) — attaches the context.
  2. startModification() — classifies the operation.
  3. modify() — called repeatedly during the gesture.
  4. stopModification() — finalises, notifies, clears.
  • Field Details

    • _FOCUSFILL

      protected static final Color _FOCUSFILL
      Semi-transparent grey fill for the focus-point indicator.
    • SPSIZE

      protected static final int SPSIZE
      Pixel size of each selection-handle hit rectangle.
      See Also:
    • SPSIZE2

      protected static final int SPSIZE2
      Half of SPSIZE.
      See Also:
    • RPSIZE

      protected static final int RPSIZE
      Pixel size of the rotation-handle hit rectangle.
      See Also:
    • RPSIZE2

      protected static final int RPSIZE2
      Half of RPSIZE.
      See Also:
    • rotateIcon

      protected static Icon rotateIcon
      Icon rendered inside the rotation handle when the item is selected.
    • _path

      protected Path2D.Double _path
      World-coordinate path for polygon-like items; may be null.
    • _line

      protected Line2D.Double _line
      World-coordinate line for line items; may be null.
    • _focus

      protected Point2D.Double _focus
      World-coordinate focus — typically the centroid or anchor. Drawn as a small square when the item is selected.
    • _layer

      protected Layer _layer
      The layer this item lives on. Set at construction; nulled by prepareForRemoval().
    • _style

      protected IStyled _style
      The drawing style (colors, line style, symbol type, etc.). Never null under normal operation; may be null after prepareForRemoval().
      See Also:
    • _resizePolicy

      protected ResizePolicy _resizePolicy
      Resize policy applied during interactive resizing.
    • _visible

      protected boolean _visible
      Whether this item is rendered.
    • _draggable

      protected boolean _draggable
      Whether this item can be dragged. Suppressed by _locked.
    • _rotatable

      protected boolean _rotatable
      Whether this item can be rotated. Suppressed by _locked.
    • _styleEditable

      protected boolean _styleEditable
      Whether this item can be styled via the style editor.
    • _rightClickable

      protected boolean _rightClickable
      Whether this item responds to right-click.
    • _selectable

      protected boolean _selectable
      Whether this item can be selected.
    • _connectable

      protected boolean _connectable
      Whether this item can be connected to other items.
    • _doubleClickable

      protected boolean _doubleClickable
      Whether this item responds to double-click.
    • _locked

      protected boolean _locked
      Master lock flag. When true drag, resize, rotate, and delete are all suppressed, regardless of the individual flags.

      Default is true.

    • _resizable

      protected boolean _resizable
      Whether this item can be resized. Suppressed by _locked.

      This field is protected (not private) so that subclasses can read the raw flag value independently of the lock — for example, to include it in a serialised representation. The effective resizability is always exposed through isResizable(), which also checks _locked.

    • _deletable

      protected boolean _deletable
      Whether this item can be deleted. Suppressed by _locked.
    • _selected

      protected boolean _selected
      Whether this item is currently selected.
    • _enabled

      protected boolean _enabled
      Whether this item is enabled (responds to interaction).
    • _dirty

      protected boolean _dirty
      Whether the item's cached rendering data is stale. Setting this to true also clears _lastDrawnPolygon.
    • _lastDrawnPolygon

      protected Polygon _lastDrawnPolygon
      The screen polygon from the most recent drawItem(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) call. null when dirty or not yet drawn. Used for hit-testing and rubber-band selection.
    • _modification

      protected ItemModification _modification
      Active modification during a drag/resize/rotate gesture.
    • _displayName

      protected String _displayName
      Human-readable display name for feedback and menus.
    • _popupMenu

      protected JPopupMenu _popupMenu
      Right-click popup menu; created lazily by createPopupMenu().
  • Constructor Details

    • AItem

      public AItem(Layer layer, Object... keyVals)
      Construct an item on the given layer, optionally configuring it from property key-value pairs, and immediately register it.

      Registration adds the item to its layer (firing an ItemChangeType.ADDED event) and registers it as a feedback provider with the container's feedback control. Registration happens inside the constructor so that callers — including factory methods such as those in CreationSupport — do not need to take any extra step after construction.

      Construction-time event caveat

      Because registration fires the ADDED event before any subclass constructor body has run, a listener that immediately queries the item's geometry on ADDED will see only the state that applyProperties(java.util.Properties) has set — not any geometry a subclass sets after super() returns. In practice, MDI listeners that care about geometry wait for a subsequent draw or modification event, so this has not been a problem. If a future listener does need to read geometry on ADDED, the creation call-site should set geometry before adding the listener, or the listener should guard against uninitialized state.

      Parameters:
      layer - the layer to add this item to; must not be null
      keyVals - optional alternating PropertyUtils key/value pairs (may be empty or null)
      Throws:
      IllegalArgumentException - if layer is null
  • Method Details

    • applyProperties

      protected void applyProperties(Properties props)
      Apply a set of properties to this item's behavior flags, style, name, and geometry.

      Called from the Phase-1 constructor. May also be called later to reconfigure the item. Order: flags → name → style → geometry.

      Parameters:
      props - properties to apply; a no-op if null
    • applyStyleProperties

      protected void applyStyleProperties(Properties props)
      Apply style-related properties from props.

      Each property is applied only when the key is present; missing keys leave the current style unchanged. Subclasses that support additional style properties should override this method and call super.applyStyleProperties(props) first.

      Parameters:
      props - the properties to read; must not be null
    • applyGeometryProperties

      protected void applyGeometryProperties(Properties props)
      Apply geometry-specific properties from props.

      Default implementation is a no-op. Subclasses with geometric constructor parameters (radius, width, endpoint coordinates, etc.) should override this rather than adding constructor parameters.

      Parameters:
      props - the properties to read; never null
    • draw

      public void draw(Graphics2D g2, IContainer container)
      Draw this item onto the container.

      This is the method called by the container's rendering pipeline. Subclasses must not override it; implement drawItem(Graphics2D, IContainer) instead.

      Steps performed:

      1. Skip if _visible is false.
      2. Call shouldDraw(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) — skip drawItem(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) if false.
      3. Install any special clip from the owning BaseView.
      4. Save and restore the Stroke around drawItem(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer).
      5. Call drawSelections(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) unconditionally (selected items need handles even when scrolled partially out of view).
      Specified by:
      draw in interface IDrawable
      Parameters:
      g2 - the graphics context
      container - the container being rendered
    • drawItem

      public abstract void drawItem(Graphics2D g2, IContainer container)
      Perform the actual rendering of this item's geometry.

      Called by draw(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) after visibility and clip setup. The stroke is saved and restored by draw, so subclasses may freely change the stroke without cleanup.

      Parameters:
      g2 - the graphics context
      container - the container being rendered
    • shouldDraw

      public abstract boolean shouldDraw(Graphics2D g2, IContainer container)
      Return true if this item should be drawn on the current frame.

      This is a secondary visibility check beyond the simple _visible flag. A typical implementation checks whether the item's screen bounds intersect the current clip rectangle.

      Parameters:
      g2 - the graphics context (may be used to read clip bounds)
      container - the container being rendered
      Returns:
      true if drawItem(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) should be called
    • drawSelections

      public void drawSelections(Graphics2D g2, IContainer container)
      Draw selection handles and the focus indicator for this item.

      Called unconditionally by draw(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) whenever the item is visible, even when shouldDraw(java.awt.Graphics2D, edu.cnu.mdi.container.IContainer) returned false, so handles remain visible for selected items that are partially scrolled out of view.

      When selected, draws:

      Parameters:
      g2 - the graphics context
      container - the container being rendered
    • setFillFocus

      public void setFillFocus(boolean fillFocus)
      Return whether the focus indicator is drawn when selected.
    • focusFill

      protected void focusFill(Graphics2D g2, IContainer container)
      Draw a small filled square at the item's focus point.

      Only drawn when getFocus() returns a non-null point. The indicator is a 6×6 pixel square filled with _FOCUSFILL.

      Parameters:
      g2 - the graphics context
      container - the container being rendered
    • contains

      public boolean contains(IContainer container, Point screenPoint)
      Test whether this item, as rendered, contains the given screen point.

      Priority order:

      1. _lastDrawnPolygon — exact hit test.
      2. getBounds(IContainer) — axis-aligned bounding rectangle.
      3. inASelectRect(edu.cnu.mdi.container.IContainer, java.awt.Point) — selection/rotation handle rectangles.
      Parameters:
      container - the container rendering this item
      screenPoint - the pixel point to test
      Returns:
      true if the item contains screenPoint
    • inASelectRect

      protected boolean inASelectRect(IContainer container, Point screenPoint)
      Test whether the screen point falls inside any selection or rotation handle rectangle.
      Parameters:
      container - the container rendering this item
      screenPoint - the pixel point to test
      Returns:
      true if the point is inside any handle rectangle
    • inRotatePoint

      public boolean inRotatePoint(IContainer container, Point screenPoint)
      Test whether the screen point falls inside the rotation-handle rectangle.

      Returns false immediately if the item is not rotatable or not selected.

      Parameters:
      container - the container rendering this item
      screenPoint - the pixel point to test
      Returns:
      true if the point is inside the rotation handle
    • inSelectPoint

      public int inSelectPoint(IContainer container, Point screenPoint, boolean checkResizable)
      Return the index of the selection handle whose hit-test rectangle contains the given screen point, or -1 if none does.

      Returns -1 immediately if the item is not selected, or if checkResizable is true and the item is not resizable.

      Parameters:
      container - the container rendering this item
      screenPoint - the pixel point to test
      checkResizable - if true, skip the test when not resizable
      Returns:
      the zero-based handle index, or -1
    • enclosed

      public boolean enclosed(IContainer container, Rectangle r)
      Test whether a rubber-band rectangle completely encloses this item.

      The default implementation uses the cached screen polygon if available, otherwise the bounding rectangle. Subclasses with non-rectangular shapes may override for a more precise test.

      Parameters:
      container - the rendering container
      r - the rubber-band rectangle in screen coordinates
      Returns:
      true if r completely contains this item
    • getBounds

      public Rectangle getBounds(IContainer container)
      Return the screen-coordinate bounding rectangle of this item.

      The default implementation returns null. Subclasses should override to return a meaningful bounding box used for hit-testing and rubber-band selection.

      Parameters:
      container - the container rendering this item
      Returns:
      the pixel bounding rectangle, or null if unavailable
    • getWorldBounds

      public abstract Rectangle2D.Double getWorldBounds()
      Return the world-coordinate bounding rectangle of this item.
      Returns:
      the world-coordinate bounding rectangle
    • getSelectionPoints

      public Point[] getSelectionPoints(IContainer container)
      Return the selection handles for this item in screen coordinates.

      The default uses the vertices of _lastDrawnPolygon if available, otherwise the four corners of getBounds(edu.cnu.mdi.container.IContainer).

      Parameters:
      container - the container rendering this item
      Returns:
      array of handle points, or null if bounds are unavailable
    • getRotatePoint

      public Point getRotatePoint(IContainer container)
      Return the screen-coordinate rotation handle point, or null if the item does not support rotation.
      Parameters:
      container - the container rendering this item
      Returns:
      the rotation handle point, or null
    • getLastDrawnPolygon

      public Polygon getLastDrawnPolygon()
      Returns:
      the last drawn polygon, or null
    • getPath

      public Path2D.Double getPath()
      Returns:
      the world-coordinate path, or null
    • getLine

      public Line2D.Double getLine()
      Returns:
      the world-coordinate line, or null
    • getFocus

      public Point2D.Double getFocus()
      Return the world-coordinate focus of this item.

      The focus is the item's conceptual center: for point items it is their location; for polygon items it is typically the centroid. Returns null if no focus has been set.

      Returns:
      the world-coordinate focus, or null
    • setFocus

      public void setFocus(Point2D.Double wp)
      Set the world-coordinate focus of this item.
      Parameters:
      wp - the new focus; may be null to clear
    • getFocusPoint

      public Point getFocusPoint(IContainer container)
      Return the screen-coordinate location of the focus, or null if the focus is not set.
      Parameters:
      container - the container (used for world-to-screen transform)
      Returns:
      the pixel location of the focus, or null
    • updateFocus

      protected void updateFocus()
      Hook called when geometry changes and the focus should be recomputed. The default implementation is a no-op.
    • geometryChanged

      public void geometryChanged()
      Notify the item that its geometry has changed. Recomputes the focus and marks the item dirty.
    • translateWorld

      public abstract void translateWorld(double dx, double dy)
      Translate this item by (dx, dy) in world coordinates.
      Parameters:
      dx - the world-coordinate offset along the X axis
      dy - the world-coordinate offset along the Y axis
    • translateLocal

      public void translateLocal(int dx, int dy)
      Translate this item by (dx, dy) in screen (pixel) coordinates.

      Pixel deltas are converted to world deltas via the container transform, then delegated to translateWorld(double, double).

      Parameters:
      dx - horizontal pixel offset (positive = right)
      dy - vertical pixel offset (positive = down)
    • acceptModification

      public boolean acceptModification(GestureContext gc)
      Gives an item a final chance to accept or reject an interactive modification.

      The default implementation accepts all modifications. Subclasses may override this to enforce domain constraints after a drag, resize, or rotation gesture. For example, a map-native radar item can reject a drag that leaves a ground-based radar over water.

      This method is called near the end of the tool-handler gesture, before stopModification() clears the active modification context.

      Parameters:
      gc - the gesture context for the interaction
      Returns:
      true to keep the modified state; false to reject it
    • modificationRejected

      public void modificationRejected(GestureContext gc)
      Called when acceptModification(GestureContext) rejects a modification.

      The default implementation does nothing. Subclasses that reject modifications should usually restore their pre-gesture geometry here.

      Parameters:
      gc - the gesture context for the rejected interaction
    • setModification

      public void setModification(ItemModification itemModification)
      Attach a modification context to begin an interactive gesture.
      Parameters:
      itemModification - the modification context; null to cancel
    • getItemModification

      public ItemModification getItemModification()
      Returns:
      the active modification context, or null
    • startModification

      public void startModification()
      Classify and begin a drag, resize, or rotate modification.

      Priority: rotate (if start point is in rotation handle) → resize (if start point is in a selection handle) → drag (otherwise).

      This method is a no-op if _modification is null.

    • modify

      public abstract void modify()
      Update this item's geometry in response to a mouse movement during an active modification.

      Called repeatedly while the user is dragging, resizing, or rotating. The current mouse position is available through _modification.

    • stopModification

      public void stopModification()
      Finalise the current modification, notify layer listeners, and clear the modification record.

      Fires ItemChangeType.MOVED, ItemChangeType.ROTATED, or ItemChangeType.RESIZED depending on the modification type. This method is a no-op if _modification is null.

    • isVisible

      public boolean isVisible()
      Description copied from interface: IDrawable
      Whether this drawable is currently visible.

      Callers should respect this flag and skip drawing when it returns false. Default is true.

      Specified by:
      isVisible in interface IDrawable
      Returns:
      true if this item is visible
    • setVisible

      public void setVisible(boolean visible)
      Description copied from interface: IDrawable
      Set whether this drawable should be visible.

      The default implementation ignores the flag. Implementations that track visibility should override this together with IDrawable.isVisible().

      Specified by:
      setVisible in interface IDrawable
      Parameters:
      visible - true to make the item visible
    • isDraggable

      public boolean isDraggable()
      Return true if this item can be dragged. Returns false when locked, regardless of the drag flag.
      Returns:
      effective draggability
    • setDraggable

      public void setDraggable(boolean draggable)
      Parameters:
      draggable - true to allow dragging
    • isDeletable

      public boolean isDeletable()
      Return true if this item can be deleted. Returns false when locked.
      Returns:
      effective deletability
    • setDeletable

      public void setDeletable(boolean deletable)
      Parameters:
      deletable - true to allow deletion
    • isResizable

      public boolean isResizable()
      Return true if this item can be resized. Returns false when locked.
      Returns:
      effective resizability
    • setResizable

      public void setResizable(boolean resizable)
      Parameters:
      resizable - true to allow resizing
    • isRotatable

      public boolean isRotatable()
      Return true if this item can be rotated. Returns false when locked.
      Returns:
      effective rotatability
    • setRotatable

      public void setRotatable(boolean rotatable)
      Parameters:
      rotatable - true to allow rotation
    • isStyleEditable

      public boolean isStyleEditable()
      Returns:
      true if this item can be styled via the style editor
    • setStyleEditable

      public void setStyleEditable(boolean styleEditable)
      Parameters:
      styleEditable - true to allow styling via the style editor
    • isConnectable

      public boolean isConnectable()
      Returns:
      true if this item can be connected to other items
    • setConnectable

      public void setConnectable(boolean connectable)
      Parameters:
      connectable - true to allow connections
    • isDoubleClickable

      public boolean isDoubleClickable()
      Returns:
      true if this item responds to double-click
    • setDoubleClickable

      public void setDoubleClickable(boolean doubleClickable)
      Parameters:
      doubleClickable - true to enable double-click
    • isSelectable

      public boolean isSelectable()
      Returns:
      true if this item can be selected
    • setSelectable

      public void setSelectable(boolean selectable)
      Parameters:
      selectable - true to allow selection
    • isLocked

      public boolean isLocked()
      Return true if this item is locked.

      A locked item ignores drag, resize, rotate, and delete operations regardless of its individual flags. Items are locked by default.

      Returns:
      true if locked
    • setLocked

      public void setLocked(boolean locked)
      Parameters:
      locked - true to lock the item
    • isRightClickable

      public boolean isRightClickable()
      Returns:
      true if this item responds to right-click
    • setRightClickable

      public void setRightClickable(boolean rightClickable)
      Parameters:
      rightClickable - true to enable right-click
    • isSelected

      public boolean isSelected()
      Returns:
      true if this item is currently selected
    • setSelected

      public void setSelected(boolean selected)
      Set the selected state of this item and request a container refresh.
      Parameters:
      selected - true to select the item
    • isEnabled

      public boolean isEnabled()
      Description copied from interface: IDrawable
      Whether this drawable is currently enabled.

      "Enabled" can be used by callers to decide, for example, whether to process interaction or feedback for this drawable. Default is true.

      Specified by:
      isEnabled in interface IDrawable
      Returns:
      true if this item is enabled
    • setEnabled

      public void setEnabled(boolean enabled)
      Description copied from interface: IDrawable
      Set whether this drawable is enabled.

      The default implementation ignores the flag. Implementations that track enabled state should override this together with IDrawable.isEnabled().

      Specified by:
      setEnabled in interface IDrawable
      Parameters:
      enabled - true to enable the item
    • isDirty

      public boolean isDirty()
      Return true if this item's cached rendering data is stale.
      Returns:
      the dirty flag
    • setDirty

      public void setDirty(boolean dirty)
      Set the dirty flag. Setting to true also clears _lastDrawnPolygon.
      Specified by:
      setDirty in interface IDrawable
      Parameters:
      dirty - new dirty state
    • isTrackable

      public boolean isTrackable()
      Return true if this item is "trackable" — that is, eligible to receive drag, resize, or rotate gestures from the interaction layer.

      An item is trackable only when it is unlocked, enabled, and at least one of _draggable, _rotatable, or _resizable is true. The interaction layer uses this as a fast pre-check before performing the more expensive hit-test against individual selection and rotation handles.

      Returns:
      true if the item should be tracked during mouse gestures
    • getStyle

      public IStyled getStyle()
      Return this item's style object.
      Returns:
      the style; may be null after prepareForRemoval()
    • setStyle

      public void setStyle(IStyled style)
      Replace the drawing style for this item.

      Passing null is accepted but will cause NullPointerExceptions in the drawing pipeline unless getStyleSafe() is used for all subsequent style accesses.

      Parameters:
      style - the new style; null is technically permitted but discouraged
    • getStyleSafe

      public IStyled getStyleSafe()
      Return this item's style, recreating it as a default Styled instance if _style is null.

      Used internally (e.g. in applyStyleProperties(java.util.Properties)) to guard against the style having been cleared by prepareForRemoval(). Prefer getStyle() in normal usage.

      Returns:
      the style object; never null
    • getAzimuth

      public double getAzimuth()
      Return the rotation angle in degrees, range (-180, 180].
      Returns:
      the azimuth in degrees
    • setAzimuth

      public void setAzimuth(double azimuth)
      Set the rotation angle, normalising the value to (-180, 180].
      Parameters:
      azimuth - the new azimuth in degrees
    • getDisplayName

      public String getDisplayName()
      Returns:
      the human-readable display name
    • setDisplayName

      public void setDisplayName(String name)
      Parameters:
      name - the new display name
    • getResizePolicy

      public ResizePolicy getResizePolicy()
      Returns:
      the resize policy
    • setResizePolicy

      public void setResizePolicy(ResizePolicy policy)
      Parameters:
      policy - the new resize policy
    • getContainer

      public IContainer getContainer()
      Return the IContainer that hosts this item's layer.
      Returns:
      the container; may be null after prepareForRemoval()
    • getLayer

      public Layer getLayer()
      Return the Layer on which this item lives.
      Returns:
      the layer; may be null after prepareForRemoval()
    • getView

      public BaseView getView()
      Return the BaseView that owns the container hosting this item, or null if unavailable.
      Returns:
      the owning view, or null
    • getPopupMenu

      public JPopupMenu getPopupMenu()
      Return this item's popup menu, creating it lazily on first call.
      Returns:
      the popup menu; never null
    • createPopupMenu

      protected JPopupMenu createPopupMenu()
      Build the basic popup menu for this item.

      The default menu contains an item-ordering sub-menu and a "Locked" checkbox. Subclasses may override and call super.createPopupMenu() before adding their own items.

      Returns:
      the newly created popup menu
    • prepareForPopup

      public void prepareForPopup(Point pp)
      Show this item's popup menu at the given screen point.
      Parameters:
      pp - the screen point; must not be null
    • doubleClicked

      public void doubleClicked(MouseEvent mouseEvent)
      Called when this item receives a double-click. The default implementation is a no-op.
      Parameters:
      mouseEvent - the double-click event
    • getFeedbackStrings

      public void getFeedbackStrings(IContainer container, Point pp, Point2D.Double wp, List<String> feedbackStrings)
      Populate the feedback string list with information about this item. The default implementation is a no-op.
      Specified by:
      getFeedbackStrings in interface IFeedbackProvider
      Parameters:
      container - the container rendering this item
      pp - the current mouse position in screen coordinates
      wp - the corresponding world-coordinate position
      feedbackStrings - the list to add strings to
    • equals

      public boolean equals(Object o)
      Identity-based equality: two AItem references are equal only when they are the same object.
      Overrides:
      equals in class Object
      Parameters:
      o - the object to compare
      Returns:
      true only if o == this
    • hashCode

      public int hashCode()
      Overrides:
      hashCode in class Object
    • prepareForRemoval

      public void prepareForRemoval()
      Prepare this item for removal from its layer.

      Performs two operations:

      1. Feedback de-registration. The item unregisters itself from the container's FeedbackControl so that it is no longer polled after removal. The container reference is captured before _layer is nulled.
      2. Reference nulling. Heavyweight references are set to null to assist garbage collection and to cause fast, obvious NullPointerExceptions if the item is used after removal.

      Subclasses holding additional heavyweight references should override this method, null those fields, and call super.prepareForRemoval() either first or last.

      Specified by:
      prepareForRemoval in interface IDrawable