Class PopupWindowPlacerBuilder

java.lang.Object
docking.widgets.shapes.PopupWindowPlacerBuilder

public class PopupWindowPlacerBuilder extends Object
This class builds a PopWindowPlacer that can have subsequent PopWindowPlacers.

General categories of placers available are edge placers, overlapped-corner placers, and a clean-up assert placer. Additionally, there are rotational placers that are composed of edge placers.



Edge Placers

The edge placers are the leftEdge, rightEdge, topEdge, and bottomEdge methods that take Location arguments that one can think of as "cells" for optimal placement, but which have some flexibility in making the placement. One such cell is the TOP Location of the rightEdge, specified by rightEdge(Location.TOP). If the placement does not quite fit this cell because the optimal placement extend above the top of the screen, the placement may be shifted down by a allowed amount so that it still fits. If more than the allowed amount is needed, the placement fails.

Each edge placer takes a variable number of Location arguments. These arguments work in the same way for each method, though some arguments are not valid for some edges; for instance, Location.TOP is only valid for left and right edges.

Two or More Location Arguments

When two or more arguments are used, the first argument specifies the nominal placement cell and the second argument specifies how far the solution is allowed to shift. If a solution is not found and if there are more than two arguments, another placement attempt is made where the second argument specifies the nominal placement cell and the third argument specifies how far the solution is allowed to shift. To specify a "no-shift" solution, one specifies the same placement cell twice (e.g., rightEdge(Location.TOP, Location.TOP)).

One Location Argument

When one argument is used, the solution is the same as when two arguments are specified except that the second argument is automatically set to the nearest neighboring cell. Thus, rightEdge(Location.TOP) is the same as rightEdge(Location.TOP, Location.CENTER). When the single argument is Location.CENTER, two attempts are built, the first being the BOTTOM or RIGHT cell and the second being the TOP or LEFT cell.

No Arguments

When no arguments are specified, two arguments to the underlying placer are automatically set to BOTTOM or RIGHT for the first and TOP or LEFT for the second.

Examples

Builds a placer that first attempts a placement at the bottom of the right edge with no shift, then tries the top of the right edge with no shift, then top center with no shift:

    PopupWindowPlacer placer =
        new PopupWindowPlacerBuilder()
            .rightEdge(Location.BOTTOM,Location.BOTTOM)
            .rightEdge(Location.TOP, Location.TOP)
            .topEdge(Location.CENTER, Location.CENTER)
            .build();
Builds a placer that attempts a placement on the right edge from bottom to top, followed by the top edge from center to right, then center to left:
    PopupWindowPlacer placer =
        new PopupWindowPlacerBuilder()
            .rightEdge()
            .topEdge(Location.CENTER);
            .build();



Rotational Placers

There are clockwise and counter-clockwise rotational placers that built up from edge placers. These are:

    rotateClockwise(Location major, Location minor)
    rotateCounterClockwise(Location major, Location minor)
    thenRotateClockwise()
    thenRotateCounterClockwise()
The first two of these take two Location arguments the specify the starting cell. For instance, rotateClockwise(Location.BOTTOM, Location.RIGHT). This specifies a set of edge placers that attempt placement starting from the specified cell, and making attempt in a clockwise fashion until the starting cell is revisited, at which time the attempt fails if a viable placement has not been found. The rotateCounterClockwise placer works the same, but in a counter-clockwise fashion. The thenRotateClockwise and thenRotateCounterClockwise placers are the same as the previous two placers except that they start at the "beginning" cell where the most previous placer had left off. If there was not a previous placer, then the BOTTOM RIGHT cell is chosen as the starting cell.



Overlapping Corner Placer

There is one corner placer, leastOverlapCorner(). This placer tries to make a placement at each of the corners of the context area and shifts into the context region as much as necessary to fit the screen bounds. The corner that overlaps the context area the least is chosen as the solution placement corner. In case of a tie (e.g., no overlap on some corners), the placement order chosen in this preference order: bottom right, bottom left, top right, and top left. Unless ill-constructed (sized of context area, screen, and pop-up dimension), this placer should always find a solution.



Assert Placer

The throwsAssertException() placer is available, which automatically throws an AssertException. This placer is only intended to be used by the client in such as case when it is believed that a placement should have already been found, such as after the leastOverlapCorner() placer. This just throws an exception instead of returning the null return value that would be returned from previous placement attempts.



Composite Placer

Builds a placer that first attempts a placement at the right edge from bottom to top, then left edge from bottom to top, then top edge from right to left, then bottom edge from right to left, followed by a least-overlap-corner solution, followed by a failure assert:

    PopupWindowPlacer placer =
        new PopupWindowPlacerBuilder()
            .rightEdge()
            .leftEdge()
            .topEdge()
            .bottomEdge()
            .leastOverlapCorner()
            .throwsAssertException()
            .build();

Builds a placer that first attempts each of the four major corners in a specific order, with no shifting, followed by an assertion failure:

    PopupWindowPlacer placer =
        new PopupWindowPlacerBuilder()
            .rightEdge(Location.BOTTOM, Location.BOTTOM)
            .leftEdge(Location.TOP, Location.TOP)
            .rightEdge(Location.TOP, Location.TOP)
            .leftEdge(Location.BOTTOM, Location.BOTTOM)
            .throwsAssertException()
            .build();

Builds a placer that attempt to make a placement at the bottom right corner, first shifting up to the center location then shifting left to the center location, then failing only with a null return:

    PopupWindowPlacer placer =
        new PopupWindowPlacerBuilder()
            .rightEdge(Location.BOTTOM)
            .bottomEdge(Location.RIGHT)
            .build();

Builds a placer that attempts a placement at the top, left corner, the tries to make a placement in a clockwise fashion, followed by a failure assert:

    PopupWindowPlacer placer =
        new PopupWindowPlacerBuilder()
            .topEdge(Location.LEFT, Location.LEFT)
            .thenRotateClockwise()
            .throwsAssertException()
            .build();
See Also:
  • Constructor Details

    • PopupWindowPlacerBuilder

      public PopupWindowPlacerBuilder()
  • Method Details

    • build

      public PopupWindowPlacer build()
      Builds the final PopupWindowPlacer.
      Returns:
      the PopupWindowPlacer
    • rightEdge

      public PopupWindowPlacerBuilder rightEdge(Location... minors)
      Set the next PopupWindowPlacer to be one that tries to make the placement at the right edge of the inner bounds (context) without exceeding outer bounds (screen), using an ordered, preferred placements on that edge. Invalid values will error.
      Parameters:
      minors - the ordered, preferred placements on the edge. If not specified, goes from greater-valued end of the edge to the lesser-valued end of the edge.
      Returns:
      this builder
    • leftEdge

      public PopupWindowPlacerBuilder leftEdge(Location... minors)
      Set the next PopupWindowPlacer to be one that tries to make the placement at the left edge of the inner bounds (context) without exceeding outer bounds (screen), using an ordered, preferred placements on that edge. Invalid values will error.
      Parameters:
      minors - the ordered, preferred placements on the edge. If not specified, goes from greater-valued end of the edge to the lesser-valued end of the edge.
      Returns:
      this builder
    • bottomEdge

      public PopupWindowPlacerBuilder bottomEdge(Location... minors)
      Set the next PopupWindowPlacer to be one that tries to make the placement at the bottom edge of the inner bounds (context) without exceeding outer bounds (screen), using an ordered, preferred placements on that edge. Invalid values will error.
      Parameters:
      minors - the ordered, preferred placements on the edge. If not specified, goes from greater-valued end of the edge to the lesser-valued end of the edge.
      Returns:
      this builder
    • topEdge

      public PopupWindowPlacerBuilder topEdge(Location... minors)
      Set the next PopupWindowPlacer to be one that tries to make the placement at the top edge of the inner bounds (context) without exceeding outer bounds (screen), using an ordered, preferred placements on that edge. Invalid values will error.
      Parameters:
      minors - the ordered, preferred placements on the edge. If not specified, goes from greater-valued end of the edge to the lesser-valued end of the edge.
      Returns:
      this builder
    • edge

      public PopupWindowPlacerBuilder edge(Location major, Location... minors)
      Set the next PopupWindowPlacer to be one that tries to make the placement on the major edge of the inner bounds (context) without exceeding outer bounds (screen), using an ordered, preferred placements on that edge. Invalid values will error.
      Parameters:
      major - the major edge of the context area
      minors - the ordered, preferred placements on the edge. If not specified, goes from greater-valued end of the edge to the lesser-valued end of the edge.
      Returns:
      this builder
    • thenRotateClockwise

      public PopupWindowPlacerBuilder thenRotateClockwise()
      Set the next PopupWindowPlacer to be one that tries to make the placement by starting at the last-used majorBegin and minorBegin and continues clockwise to find a solution. If there was no last-used location set, then BOTTOM, RIGHT is used.
      Returns:
      this builder
    • rotateClockwise

      public PopupWindowPlacerBuilder rotateClockwise(Location majorBegin, Location minorBegin)
      Set the next PopupWindowPlacer to be one that tries to make the placement by starting at a point specified by majorBegin and minorBegin and continues clockwise to find a solution.
      Parameters:
      majorBegin - the major coordinate location of the starting point
      minorBegin - the minor coordinate location of the starting point
      Returns:
      this builder
    • thenRotateCounterClockwise

      public PopupWindowPlacerBuilder thenRotateCounterClockwise()
      Set the next PopupWindowPlacer to be one that tries to make the placement by starting at the last-used majorBegin and minorBegin and continues counter-clockwise to find a solution. If there was no last-used location set, then RIGHT, BOTTOM is used.
      Returns:
      this builder
    • rotateCounterClockwise

      public PopupWindowPlacerBuilder rotateCounterClockwise(Location majorBegin, Location minorBegin)
      Set the next PopupWindowPlacer to be one that tries to make the placement by starting at a point specified by majorBegin and minorBegin and continues counter-clockwise to find a solution.
      Parameters:
      majorBegin - the major coordinate location of the starting point
      minorBegin - the minor coordinate location of the starting point
      Returns:
      this builder
    • leastOverlapCorner

      public PopupWindowPlacerBuilder leastOverlapCorner()
      Set the next PopupWindowPlacer to be one that tries to make the placement that is allowed to overlap the inner bounds, but with the least overlap area. Tie-breaker order is first in this order: Bottom Right, Bottom Left, Top Right, Top Left.

      Should never return null, except if using impractical parameters, such as using outer bounds that are smaller than inner bounds.

      Returns:
      this builder
    • throwsAssertException

      public PopupWindowPlacerBuilder throwsAssertException()
      Set the next PopupWindowPlacer that throws an AssertException because no solution has been found by the time this placer is tried. This is intended to be used when the coder has already guaranteed that there is a solution (i.e., the leastOverlapCorner() placer has been used and the pop-up area will fit within the outer bounds).
      Returns:
      this builder
    • useRectangle

      public PopupWindowPlacerBuilder useRectangle(Rectangle r)
      A method that allows clients to specify an exact rectangle to be used. This method can be used to hardcode a rectangle to use when the placement algorithm specified earlier in the builder chain has failed.
      Parameters:
      r - the rectangle
      Returns:
      this builder