Class PopupWindowPlacer


  • public abstract class PopupWindowPlacer
    extends java.lang.Object
    This class places a rectangle on the boundary of an inner bounds area, such that it is not placed outside of an outer boundary. It takes the concept of trying to make the placement at the closest distance, but preferring certain sides or angles of approach in iterating a solution. However, we reduce this concept down to a very simple form where iteration is not needed because we are basing the algorithm on a geometric model that has explicit solutions (for example, instead of picking a starting point around the perimeter and rotating counter-clockwise to find a fit, or, for example, creating a grid of placements and choosing the one that is closest but yet has preferences on one side or another). From the geometric model, we can, instead, calculate the first location that will fit with a preferred boundary location, such as fit on the right side of the context area, near the bottom. We could have chosen to iterate through the areas in a counter-clockwise fashion, but by using a builder model, we give the user more control of the order of choice. For example, the user might first prefer the right side near the bottom, then the left side near the bottom, followed by the top near the right, and then the bottom near the right.

    This first drawing shows the overall context of the inner bounds within an outer bounds along with a good placement and a bad placement that violates the outer bounds.

    
            +-----------------------------------------------+
            |                                        outer  |
            |                                               |
            |                                               |
            |      +------------------+                     |
            |      |       good       |                     |
            |      |     placement    |                     |
            |      |                  |                     |
            |      +------------------+---------+           |
            |                         |         |           |
            |                         |  inner  |           |
            |                         |         |           |
            |                         +---------+------------------+
            |                                   |       bad |      |
            |                                   |     placement    |
            +-----------------------------------+-----------+      |
                                                +------------------+
    
     
    The next two drawings show the LEFT and RIGHT edges with nominal locations of TOP, CENTER, and BOTTOM placements and the TOP and BOTTOM edges with nominal location of LEFT, CENTER, and RIGHT placements. There are a total of eight of these locations ("cells") around the inner bounds.
    
                  LEFT                            RIGHT
            +---------------+               +---------------+
            |               |               |               |
            |      TOP      |               |      TOP      |
            |               |               |               |
            +---------------X---------------X---------------+
            |               |               |               |
            |    CENTER     X     inner     X    CENTER     |
            |               |               |               |
            +---------------X---------------X---------------+
            |               |               |               |
            |    BOTTOM     |               |    BOTTOM     |
            |               |               |               |
            +---------------+               +---------------+
    
    
            +---------------+---------------+---------------+
            |               |               |               |
            |     LEFT      |    CENTER     |     RIGHT     | TOP
            |               |               |               |
            +---------------X-------X-------X---------------+
                            |               |
                            |     inner     |
                            |               |
            +---------------X-------X-------X---------------+
            |               |               |               |
            |     LEFT      |    CENTER     |     RIGHT     | BOTTOM
            |               |               |               |
            +---------------+---------------+---------------+
    
     

    These cells are shown in their nominal placement locations (where they touch the inner bounds, marked with an X). However we will shift these locations by particular amounts so that these locations still fit within the outer bounds. For instance, if we allow the BOTTOM cell on the LEFT edge to be shifted up far enough such that it fits the lower edge of the outer bounds, we limit this shift if it reaches the nominal placement of another specified cell (CENTER or TOP) on that edge. If a solution is not found before the limit is reached, the placement fails.

    If the chosen cell is a CENTER cell, then it could shift up or down, depending on the circumstances and the parameters applied.

    These placements and shifts are controlled by specifying the major and minorBegin and minorEnd Locations. The major Location specifies the edge for an PopupWindowPlacer.EdgePopupPlacer and the minorBegin Location specifies the placement cell on this edge and the minorEnds specifies the last cell (amount of shift allowed), starting from the minorBegin Location. For a CENTER minorBeing Location, the minorEnd cell may be any of the three allowed Locations on that major edge as well as null, representing that a shift is allowed in either direction. When the minorEnd Location is set to the minorBegin Location, then no shift is permitted.

    Combinations of these placement attempts can be put together to create more complex strategies. See PopupWindowPlacerBuilder for examples of these.

    There are also PopupWindowPlacer.LeastOverlapCornerPopupWindowPlacer and PopupWindowPlacer.ThrowsAssertExceptionPlacer, for instance, that do not follow the same cell scheme. The first of these tries to make the placement at each of the corners of the inner bounds, but shifts these placements to fit the outer bounds in such a way that the inner bounds area may be occluded. The placement on the corner which overlaps the least amount of the inner bounds area is chosen. The second of these placers automatically throws an AssertException. It is intended to be used in a builder model in which a sequence of placement attempts are made until good solution is found or until a null value is returned. This last placer, when chosen, serves as an assert condition, which is helpful in circumstances where the developer believes such an assertion is not possible, such as when allowing an overlapping placement solution.

    See Also:
    PopupWindowPlacerBuilder
    • Constructor Summary

      Constructors 
      Constructor Description
      PopupWindowPlacer()
      Constructor only for classes that do not use placement preferences
      PopupWindowPlacer​(Location major, Location minorBegin, Location minorEnd)
      Constructor only for classes that specify major edge and minor begin and end location on that edge.
    • Method Summary

      All Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      protected int getCenterLocation​(int contextLocation, int contextLength, int placementLength)
      Determines the placementLocation such that the midpoint of the context and the midpoint of the placement are at the same point.
      protected int getGreaterBoundedLocation​(int placementLocation, int placementLength, int boundLocation, int boundLength)
      With all inputs on a line (one-dimensional), returns a location that is shifted enough from the placementLocation such that the greater end of bounds specified by boundLocation is not exceeded (i.e., the new location is not bigger than #boundLocation).
      protected int getGreaterLocation​(int contextLocation, int contextLength, int placementLength)
      Returns the placement on a line (one-dimensional) on the greater end of the context area.
      protected int getLesserBoundedLocation​(int placementLocation, int boundLocation)
      With all inputs on a line (one-dimensional), returns a location that is shifted enough from the placementLocation such that the lesser end of bounds specified by boundLocation is not exceeded (i.e., the new location is not smaller than boundLocation).
      protected int getLesserLocation​(int contextLocation, int contextLength, int placementLength)
      Returns the placement on a line (one-dimensional) on the lesser end of the context area.
      protected abstract java.awt.Rectangle getMyPlacement​(java.awt.Dimension toBePlaced, java.awt.Rectangle innerBounds, java.awt.Rectangle outerBounds)  
      protected docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle getPlacement​(docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle result, docking.widgets.shapes.PopupWindowPlacer.PositionableDimension toBePlaced, docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle context, docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle outer)
      Returns a Rectangle solution for the placement of a toBePlaced Dimension.
      java.awt.Rectangle getPlacement​(java.awt.Dimension toBePlaced, java.awt.Rectangle innerBounds, java.awt.Rectangle outerBounds)
      Returns the placement Rectangle of toBePlaced Dimension for this PopupWindowPlacer.
      java.lang.String toString()  
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • PopupWindowPlacer

        public PopupWindowPlacer()
        Constructor only for classes that do not use placement preferences
      • PopupWindowPlacer

        public PopupWindowPlacer​(Location major,
                                 Location minorBegin,
                                 Location minorEnd)
        Constructor only for classes that specify major edge and minor begin and end location on that edge.
        Parameters:
        major - edge
        minorBegin - start location on edge
        minorEnd - end location on edge
        See Also:
        PopupWindowPlacerBuilder
    • Method Detail

      • getPlacement

        public java.awt.Rectangle getPlacement​(java.awt.Dimension toBePlaced,
                                               java.awt.Rectangle innerBounds,
                                               java.awt.Rectangle outerBounds)
        Returns the placement Rectangle of toBePlaced Dimension for this PopupWindowPlacer. If it cannot find a solution, it tries the next PopupWindowPlacer and so forth until there are no others available, upon which null is returned if there is no solution.
        Parameters:
        toBePlaced - the Dimension
        innerBounds - the inner bounds Rectangle
        outerBounds - the out bounds in which the final result must fit
        Returns:
        the placement Rectangle or null if extends outside the outerBounds
      • getMyPlacement

        protected abstract java.awt.Rectangle getMyPlacement​(java.awt.Dimension toBePlaced,
                                                             java.awt.Rectangle innerBounds,
                                                             java.awt.Rectangle outerBounds)
      • getPlacement

        protected docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle getPlacement​(docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle result,
                                                                                              docking.widgets.shapes.PopupWindowPlacer.PositionableDimension toBePlaced,
                                                                                              docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle context,
                                                                                              docking.widgets.shapes.PopupWindowPlacer.PositionableRectangle outer)
        Returns a Rectangle solution for the placement of a toBePlaced Dimension.

        When dealing with solutions for the top or bottom edge, we are considering vertical to be the major axis with y/height values representing that axis, and horizontal to be the minor axis with x/width values representing that axis. When dealing with solutions for the left and right edge, these major and minor axes are switched.

        Parameters:
        result - the new instance of the resulting class type to be returned
        toBePlaced - the wrapped toBePlaced Dimension
        context - the wrapped context Rectangle
        outer - the wrapped outer boundsRectangle
        Returns:
        the resultant wrapped Rectangle
      • getGreaterBoundedLocation

        protected int getGreaterBoundedLocation​(int placementLocation,
                                                int placementLength,
                                                int boundLocation,
                                                int boundLength)
        With all inputs on a line (one-dimensional), returns a location that is shifted enough from the placementLocation such that the greater end of bounds specified by boundLocation is not exceeded (i.e., the new location is not bigger than #boundLocation).
        Parameters:
        placementLocation - starting location that gets shifted
        placementLength - the length of the to-be-placed dimension on the (one-dimensional) line
        boundLocation - the bounds on the line that must not be exceeded to the greater side
        boundLength - the length of the outer bounds dimension on the (one-dimensional) line
        Returns:
        the shifted result
      • getLesserBoundedLocation

        protected int getLesserBoundedLocation​(int placementLocation,
                                               int boundLocation)
        With all inputs on a line (one-dimensional), returns a location that is shifted enough from the placementLocation such that the lesser end of bounds specified by boundLocation is not exceeded (i.e., the new location is not smaller than boundLocation).
        Parameters:
        placementLocation - starting location that gets shifted
        boundLocation - the bounds on the line that must not be exceeded to the lesser side
        Returns:
        the shifted result
      • getGreaterLocation

        protected int getGreaterLocation​(int contextLocation,
                                         int contextLength,
                                         int placementLength)
        Returns the placement on a line (one-dimensional) on the greater end of the context area.
        Parameters:
        contextLocation - the context location on the line
        contextLength - the context length on the line
        placementLength - the length of the to-be-place dimension on that line
        Returns:
        the resultant placement on the line
      • getLesserLocation

        protected int getLesserLocation​(int contextLocation,
                                        int contextLength,
                                        int placementLength)
        Returns the placement on a line (one-dimensional) on the lesser end of the context area.
        Parameters:
        contextLocation - the context location on the line
        contextLength - the context length on the line
        placementLength - the length of the to-be-place dimension on that line
        Returns:
        the resultant placement on the line
      • getCenterLocation

        protected int getCenterLocation​(int contextLocation,
                                        int contextLength,
                                        int placementLength)
        Determines the placementLocation such that the midpoint of the context and the midpoint of the placement are at the same point. Location and Length can either be an x value and width or a y value and height.
        Parameters:
        contextLocation - the x or y value of the context, depending on if we are doing the horizontal or vertical midpoint
        contextLength - the corresponding width (if dealing with x/horizontal midpoint) or height (if dealing with y/vertical midpoint)
        placementLength - the corresponding height or width of the placement
        Returns:
        the placement location (again x or y value)
      • toString

        public java.lang.String toString()
        Overrides:
        toString in class java.lang.Object