Class Layer

java.lang.Object
edu.cnu.mdi.item.Layer
Direct Known Subclasses:
CityLayer, CountryBoundaryLayer, CountryFillLayer, Etopo5Layer, GraticuleLayer, ShapefileLayer

public class Layer extends Object
A z-layer (drawing layer) that owns an ordered list of AItem objects.

Role in the MDI rendering model

   View → Container → Layers → Items
 

Layers are rendered bottom-to-top by the owning container. The layer manages item ordering, selection state, hit-testing, and notifies registered ItemChangeListeners when items are added, removed, or selected.

Visibility vs. locking

  • Visible layers are drawn and participate in hit-testing.
  • Locked layers are still drawn (if visible) but their items are treated as non-interactive: hit-testing returns null, selection helpers are no-ops, and deletion helpers skip locked layers.

Why delegation instead of inheritance

This class delegates to an internal ArrayList rather than extending one. Extending ArrayList would expose the full List mutation API (add(int, E), set(), addAll(), etc.) to callers, making it trivial to bypass the change-notification logic in add(edu.cnu.mdi.item.AItem) and remove(edu.cnu.mdi.item.AItem). The delegation approach exposes only the operations this layer actually supports, each of which fires the correct event.

Thread safety

Mutating operations synchronize on this to provide basic safety when background threads modify items while the Swing EDT is painting.

See Also:
  • Constructor Details

    • Layer

      public Layer(IContainer container, String name)
      Create a z-layer and register it with the owning container.

      The layer auto-registers itself via IContainer.addLayer(Layer).

      Parameters:
      container - the owning container; must not be null
      name - a human-readable layer name; must not be null
      Throws:
      IllegalArgumentException - if either argument is null
  • Method Details

    • add

      public void add(AItem item)
      Add an item to the top of this layer and notify listeners.

      Items normally add themselves to their layer inside AItem(Layer, Object...). Re-adding an item already present on this layer is a no-op.

      Parameters:
      item - the item to add; must belong to this layer
      Throws:
      IllegalArgumentException - if item is null or belongs to a different layer
    • remove

      public boolean remove(AItem item)
      Remove an item from this layer.

      If the item is present, it is removed first, then AItem.prepareForRemoval() is called and a ItemChangeType.DELETED event is fired. An item not owned by this layer is left untouched.

      Parameters:
      item - the item to remove; if null or not on this layer the call is a no-op
      Returns:
      true if the item was found and removed
    • clearAllItems

      public void clearAllItems(IContainer container)
      Delete all deletable items from this layer, properly detaching each from container-managed services (feedback control, etc.).

      If this layer is locked the call is a no-op.

      Parameters:
      container - retained for source compatibility; item cleanup uses this layer's owning container
    • deleteSelectedItems

      public void deleteSelectedItems(IContainer container)
      Delete all currently selected, deletable items.

      If this layer is locked or not visible the call is a no-op.

      Parameters:
      container - retained for source compatibility; item cleanup uses this layer's owning container
    • deleteItem

      public void deleteItem(AItem item)
      Delete a single item from this layer.

      If this layer is locked the call is a no-op. The item is detached from the container's feedback control and AItem.prepareForRemoval() is called before removal.

      Parameters:
      item - the item to delete; if null the call is a no-op
    • size

      public int size()
      Return the number of items on this layer.
      Returns:
      item count (≥ 0)
    • isEmpty

      public boolean isEmpty()
      Return true if this layer contains no items.
      Returns:
      true if empty
    • contains

      public boolean contains(AItem item)
      Return true if this layer contains the given item.
      Parameters:
      item - the item to test; if null returns false
      Returns:
      true if item is on this layer
    • getAllItems

      public ArrayList<AItem> getAllItems()
      Return a snapshot of all items on this layer, in draw order (bottom-to-top).

      The returned list is a defensive copy — modifications to it do not affect this layer.

      Returns:
      a new, mutable ArrayList of all items; never null
    • draw

      public void draw(Graphics2D g, IContainer container)
      Draw all items on this layer in bottom-to-top order.

      If this layer is not visible the method returns immediately.

      Parameters:
      g - the graphics context
      container - the container being rendered
    • beforeDraw

      public void beforeDraw(Graphics2D g2, IContainer container)
      Hook for subclasses to perform custom drawing before the items are drawn.

      The default implementation is a no-op.

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

      public void afterDraw(Graphics2D g2, IContainer container)
      Hook for subclasses to perform custom drawing after the items are drawn.

      The default implementation is a no-op.

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

      public boolean isEditable()
      Return true if this layer is editable.
      Returns:
      the editable flag
    • setEditable

      public void setEditable(boolean editable)
      Set the editable state of this layer.
      Parameters:
      editable - true to make the layer editable
    • edit

      public void edit(Component parent)
      Edit the layer-level parameters of this layer.

      The default implementation is a no-op. Subclasses may override to provide a custom editing dialog or panel.

      Parameters:
      parent - the parent component for any dialogs; may be null
    • getItemAtPoint

      public AItem getItemAtPoint(IContainer container, Point screenPoint)
      Return the topmost visible item that contains the given screen point.

      Returns null if this layer is not visible or is locked.

      Parameters:
      container - the container performing the hit test
      screenPoint - the pixel location to test
      Returns:
      the topmost matching item, or null
    • getItemsAtPoint

      public ArrayList<AItem> getItemsAtPoint(IContainer container, Point screenPoint)
      Return all visible items that contain the given screen point, topmost first.

      Returns null if this layer is not visible or is locked, or if no items match.

      Parameters:
      container - the container performing the hit test
      screenPoint - the pixel location to test
      Returns:
      matching items (topmost first), or null
    • addEnclosedItems

      public void addEnclosedItems(IContainer container, ArrayList<AItem> dest, Rectangle rect)
      Append all visible items contained within the given rectangle to dest.

      Does nothing if this layer is locked or not visible.

      Parameters:
      container - the container performing the test
      dest - destination list; items are appended to it
      rect - the enclosing rectangle in screen coordinates
    • addItemsAtPoint

      public void addItemsAtPoint(ArrayList<AItem> dest, IContainer container, Point screenPoint)
      Append all visible items at the given screen point to dest.
      Parameters:
      dest - destination list; items are appended to it
      container - the container performing the hit test
      screenPoint - the pixel location to test
    • anySelected

      public boolean anySelected()
      Return true if at least one item on this layer is selected.
      Returns:
      true if any item is selected
    • getSelectedCount

      public int getSelectedCount()
      Return the number of selected items on this layer.
      Returns:
      selected item count (≥ 0)
    • getSelectedItems

      public ArrayList<AItem> getSelectedItems()
      Return a snapshot of all selected, visible items on this layer.
      Returns:
      selected items; never null but may be empty
    • addSelectedItems

      public void addSelectedItems(ArrayList<AItem> dest)
      Append all selected, visible items to dest.
      Parameters:
      dest - destination list; items are appended to it
    • selectAllItems

      public void selectAllItems(boolean select)
      Select or deselect all items on this layer.

      If this layer is locked the call is a no-op.

      Parameters:
      select - true to select, false to deselect
    • selectAllItems

      public void selectAllItems(boolean select, AItem excludedItem)
      Select or deselect all items on this layer, optionally excluding one.

      Both the layer lock and each item's own lock are respected. If this layer is locked the call is a no-op.

      Parameters:
      select - new selection state
      excludedItem - item to skip; may be null
    • selectItem

      public void selectItem(AItem item, boolean select)
      Select or deselect a single item and notify listeners.

      If this layer is locked, or the item itself is locked, the call is a no-op.

      Parameters:
      item - the target item; if null the call is a no-op
      select - new selection state
    • sendToFront

      public void sendToFront(AItem item)
      Bring an item to the very front (top draw order) of this layer.
      Parameters:
      item - the item to move; no-op if not on this layer
    • sendToBack

      public void sendToBack(AItem item)
      Send an item to the very back (bottom draw order) of this layer.
      Parameters:
      item - the item to move; no-op if not on this layer
    • sendForward

      public void sendForward(AItem item)
      Move an item one step toward the front (higher draw order).
      Parameters:
      item - the item to move; no-op if not on this layer or already at front
    • sendBackward

      public void sendBackward(AItem item)
      Move an item one step toward the back (lower draw order).
      Parameters:
      item - the item to move; no-op if not on this layer or already at back
    • setDirty

      public void setDirty(boolean dirty)
      Mark all items on this layer dirty or clean.
      Parameters:
      dirty - new dirty state for each item
    • addItemChangeListener

      public void addItemChangeListener(ItemChangeListener listener)
      Register an ItemChangeListener.

      Duplicate registrations are silently ignored (the listener is removed then re-added to avoid duplicates).

      Parameters:
      listener - the listener to add; if null the call is a no-op
    • removeItemChangeListener

      public void removeItemChangeListener(ItemChangeListener listener)
      Remove a previously registered ItemChangeListener.
      Parameters:
      listener - the listener to remove; if null the call is a no-op
    • notifyItemChangeListeners

      public void notifyItemChangeListeners(AItem item, ItemChangeType type)
      Notify all registered listeners that an item changed.
      Parameters:
      item - the affected item; may be null for layer-level events
      type - the type of change
    • getContainer

      public IContainer getContainer()
      Return the owning container.
      Returns:
      the container that owns this layer; never null
    • getName

      public String getName()
      Return the human-readable name of this layer.
      Returns:
      the layer name; never null
    • setName

      public void setName(String name)
      Set the human-readable name of this layer.
      Parameters:
      name - the new name; must not be null
      Throws:
      IllegalArgumentException - if name is null
    • isVisible

      public boolean isVisible()
      Return true if this layer is visible.
      Returns:
      the visibility flag
    • setVisible

      public void setVisible(boolean visible)
      Set the visibility of this layer.
      Parameters:
      visible - true to make the layer visible
    • isLocked

      public boolean isLocked()
      Return true if this layer is locked (edit-locked).

      A locked layer is still drawn if isVisible() returns true, but its items are treated as non-interactive.

      Returns:
      the locked flag
    • setLocked

      public void setLocked(boolean locked)
      Set the locked state of this layer.
      Parameters:
      locked - true to lock the layer
    • equals

      public boolean equals(Object o)
      Identity-based equality: two layer 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
    • toString

      public String toString()
      Return a human-readable description of this layer.
      Overrides:
      toString in class Object
      Returns:
      a string of the form "Layer[name, N items]"