| Used by BasicTabDisplayerUI and its subclasses.
Tracks and manages the state of tabs, mainly which one currently contains the
mouse, if the mouse is in the close button, if the tab is adjacent to a
selected tab, if it is leftmost, rightmost, active, etc. This class hides
most of the complexity of deciding what mouse events should trigger a repaint
of what areas in an optimized way. It provides setters which a mouse
listener can call to indicate that the mouse has, say, moved into a tab, or
from one tab to another, or the selection has changed, etc.
Essentially, this class is fed indices of tabs that have various states (selected,
contains mouse, etc.), figures out if this affects one tab, two tabs (a different
tab had the state, such as the mouse moving from one tab to another) or all tabs (activated). It determines
a change type, and consults a repaint policy (an integer bitmask) to decide
if one, both, all or no tabs should be repainted.
The typical use case is to implement a subclass, and override getState() to
mix in bitmasks for things like whether a tab is clipped, etc. - things the
base implementation can't know about.
Subclasses implement the repaintTab() method to do the actual
repainting, and implement getRepaintPolicy() . The repainting will be
called if an event happens that changes the state in a way that the repaint policy
bitmask indicates should cause a repaint.
BasicTabDisplayerUI implements a mouse listener which will call the appropriate
methods when the mouse enters/exits tabs, etc.
Details
State is composed as an integer bitmask which covers all of the supported
states of a tab that may affect the way they paint. These are also the values that
are passed to the methods of a TabCellRenderer to tell it how to
paint itself. Two other integer
bitmasks are used: The changeType , which indicates whether a
change was from one tab to another tab, one tab to no tab (i.e. selection set
to -1), one tab to the same tab (i.e. the mouse moved out of the tab control,
and so the tab with the mouse in it is now no tab). RepaintPolicy is an integer
bitmask composed of conditions under which the control should repaint one or all
tabs, and determines what types of changes actually trigger repaints.
Subclasses are expected to override getState() to provide
information about non-mouse-or-focus related states, such as clipping of
scrollable tabs. Predefined states for tabs are: CLIP_RIGHT, CLIP_LEFT,
ARMED, PRESSED, SELECTED, ACTIVE, NOT_ONSCREEN, LEFTMOST, RIGHTMOST,
CLOSE_BUTTON_ARMED, BEFORE_SELECTED, AFTER_SELECTED, MOUSE_IN_TABS_AREA,
MOUSE_PRESSED_IN_CLOSE_BUTTON. Subclasses must handle returning the following
states if they wish to, which are not handled directly in TabState: LEFTMOST,
RIGHTMOST, CLIP_LEFT, CLIP_RIGHT, NOT_ONSCREEN.
Most of the states are fairly self-explanatory; NOT_ONSCREEN is useful as an
optimization so that no work is done for events that would try to produce a
repaint for something not visible; CLIP_* refers to the case in scrollable
tab UIs, in which a tab may only be partially visible;
MOUSE_PRESSED_IN_CLOSE_BUTTON is distinct because the CLOSE_BUTTON_ARMED
state will be reset if the mouse moves out of the close button area, but UIs
should perform a close action if the mouse was pressed over the close button,
moved away from the close button and then back to it, so this state preserves
the information that the originating location of a mouse press was in the
close button.
|