com.threerings.media
Class MediaPanel

java.lang.Object
  extended by java.awt.Component
      extended by java.awt.Container
          extended by javax.swing.JComponent
              extended by com.threerings.media.MediaPanel
All Implemented Interfaces:
FrameParticipant, MediaConstants, MediaHost, ImageObserver, MenuContainer, Serializable
Direct Known Subclasses:
VirtualMediaPanel

public class MediaPanel
extends JComponent
implements FrameParticipant, MediaConstants, MediaHost

Provides a useful extensible framework for rendering animated displays that use sprites and animations. Sprites and animations can be added to this panel and they will automatically be ticked and rendered (see addSprite(com.threerings.media.sprite.Sprite) and addAnimation(com.threerings.media.animation.Animation)).

To facilitate optimized sprite and animation rendering, the panel provides a dirty region manager which is used to only repaint dirtied regions on each frame. Derived classes can add dirty regions to the scene and/or augment the dirty regions created by moving sprites and changing animations.

Sprite and animation rendering is done in two layers: front and back. Callbacks are provided to render behind the back layer (paintBehind(java.awt.Graphics2D, java.awt.Rectangle)), in between front and back (paintBetween(java.awt.Graphics2D, java.awt.Rectangle)) and in front of the front layer (paintInFront(java.awt.Graphics2D, java.awt.Rectangle)).

The animated panel automatically registers with the FrameManager to participate in the frame tick. It only does so while it is a visible part of the UI hierarchy, so animations and sprites are paused while the animated panel is hidden.

See Also:
Serialized Form

Nested Class Summary
protected  class MediaPanel.ActionSpriteHandler
          Handles ActionSprite/HoverSprite/ArmingSprite manipulation.
static interface MediaPanel.Obscurer
           
 
Nested classes/interfaces inherited from class javax.swing.JComponent
JComponent.AccessibleJComponent
 
Nested classes/interfaces inherited from class java.awt.Container
Container.AccessibleAWTContainer
 
Nested classes/interfaces inherited from class java.awt.Component
Component.AccessibleAWTComponent, Component.BaselineResizeBehavior, Component.BltBufferStrategy, Component.FlipBufferStrategy
 
Field Summary
protected  MediaPanel.ActionSpriteHandler _actionHandler
          The action sprite handler, or null for none.
protected  int _actionSpriteCount
          The number of action/hover sprites being managed.
protected  AnimationManager _animmgr
          Legacy reference to avoid breaking children in the wild.
protected  MetaMediaManager _metamgr
          Handles most of our heavy lifting.
protected  ArrayList<MediaPanel.Obscurer> _obscurerList
          Anyone registered as someone who might obscure the media panel (and thus require extra redrawing.
protected  RegionManager _remgr
          Legacy reference to avoid breaking children in the wild.
protected  SpriteManager _spritemgr
          Legacy reference to avoid breaking children in the wild.
protected  boolean _tickPaintPending
          Used to correlate tick()s with paint()s.
 
Fields inherited from class javax.swing.JComponent
accessibleContext, listenerList, TOOL_TIP_TEXT_KEY, ui, UNDEFINED_CONDITION, WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, WHEN_FOCUSED, WHEN_IN_FOCUSED_WINDOW
 
Fields inherited from class java.awt.Component
BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
 
Fields inherited from interface com.threerings.media.MediaConstants
ALL, BACK, FRONT
 
Fields inherited from interface java.awt.image.ImageObserver
ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
 
Constructor Summary
MediaPanel(FrameManager framemgr)
          Constructs a media panel.
 
Method Summary
 void abortAnimation(Animation anim)
          Aborts a currently running animation and removes it from this panel.
 void addAnimation(Animation anim)
          Adds an animation to this panel.
 void addObscurer(MediaPanel.Obscurer obscurer)
          Adds an element that could be obscuring the panel and thus requires extra redrawing.
protected  void addObscurerDirtyRegion(Rectangle region)
          Adds the particular region as dirty.
protected  void addObscurerDirtyRegions(boolean changedOnly)
          Add dirty regions for all our obscurers.
 void addSprite(Sprite sprite)
          Adds a sprite to this panel.
 void clearAnimations()
          Removes all animations from this panel.
 void clearSprites()
          Removes all sprites from this panel.
protected  void clipToDirtyRegion(Graphics2D gfx, Rectangle dirty)
          This is called to clip the rendering output to the supplied dirty region.
protected  void constrainToBounds(Rectangle dirty)
          Called by the main rendering code to constrain this dirty rectangle to the bounds of the media panel.
protected  MediaPanel.ActionSpriteHandler createActionSpriteHandler()
          Creates the mouse listener that will handle action sprites and their variants.
 Graphics2D createGraphics()
          Creates a graphics context for the component underlying this media host.
protected  void didTick(long tickStamp)
          Derived classes can override this method and perform computation subsequent to the ticking of the sprite and animation managers.
protected  void dirtyScreenRect(Rectangle rect)
          Called to mark the specified rectangle (in screen coordinates) as dirty.
 AnimationManager getAnimationManager()
          Returns a reference to the animation manager used by this media panel.
 Component getComponent()
          If a frame participant wishes also to be actively rendered every frame rather than use passive rendering (which for Swing, at least, is hijacked when using the frame manager such that we take care of repainting dirty Swing components every frame into our off-screen buffer), it can return a component here which will have Component.paint(java.awt.Graphics) called on it once per frame with a translated but unclipped graphics object.
 RegionManager getRegionManager()
          Returns a reference to the region manager used by this media panel.
 SpriteManager getSpriteManager()
          Returns a reference to the sprite manager used by this media panel.
 long getTimeStamp()
          Returns a timestamp from the MediaTimer used to track time intervals for this media panel.
 Rectangle getViewBounds()
          Get the bounds of the viewport, in media coordinates.
 boolean isManaged(Animation anim)
           
 boolean isManaged(Sprite sprite)
           
 boolean needsPaint()
          Called immediately prior to FrameParticipant.getComponent() and then Component.paint(java.awt.Graphics) on said component, to determine whether or not this frame participant needs to be painted.
 void paint(Graphics g)
           
protected  void paint(Graphics2D gfx, Rectangle[] dirty)
          Performs the actual painting of the media panel.
protected  void paintBehind(Graphics2D gfx, Rectangle dirtyRect)
          Paints behind all sprites and animations.
protected  void paintBetween(Graphics2D gfx, Rectangle dirtyRect)
          Paints between the front and back layer of sprites and animations.
protected  void paintBits(Graphics2D gfx, int layer, Rectangle dirty)
          Renders the sprites and animations that intersect the supplied dirty region in the specified layer.
protected  void paintDirtyRect(Graphics2D gfx, Rectangle rect)
          Paints all the layers of the specified dirty region.
protected  void paintInFront(Graphics2D gfx, Rectangle dirtyRect)
          Paints in front of all sprites and animations.
 void removeObscurer(MediaPanel.Obscurer obscurer)
          Removes an obscuring element.
 void removeSprite(Sprite sprite)
          Removes a sprite from this panel.
 void repaint(long tm, int x, int y, int width, int height)
           
 void setOpaque(boolean opaque)
           
 void setPaused(boolean paused)
          Pauses the sprites and animations that are currently active on this media panel.
 void tick(long tickStamp)
          This is called on all registered frame participants, one for every frame.
protected  void willTick(long tickStamp)
          Derived classes can override this method and perform computation prior to the ticking of the sprite and animation managers.
 
Methods inherited from class javax.swing.JComponent
addAncestorListener, addNotify, addVetoableChangeListener, computeVisibleRect, contains, createToolTip, disable, enable, firePropertyChange, firePropertyChange, firePropertyChange, fireVetoableChange, getAccessibleContext, getActionForKeyStroke, getActionMap, getAlignmentX, getAlignmentY, getAncestorListeners, getAutoscrolls, getBaseline, getBaselineResizeBehavior, getBorder, getBounds, getClientProperty, getComponentGraphics, getComponentPopupMenu, getConditionForKeyStroke, getDebugGraphicsOptions, getDefaultLocale, getFontMetrics, getGraphics, getHeight, getInheritsPopupMenu, getInputMap, getInputMap, getInputVerifier, getInsets, getInsets, getListeners, getLocation, getMaximumSize, getMinimumSize, getNextFocusableComponent, getPopupLocation, getPreferredSize, getRegisteredKeyStrokes, getRootPane, getSize, getToolTipLocation, getToolTipText, getToolTipText, getTopLevelAncestor, getTransferHandler, getUIClassID, getVerifyInputWhenFocusTarget, getVetoableChangeListeners, getVisibleRect, getWidth, getX, getY, grabFocus, isDoubleBuffered, isLightweightComponent, isManagingFocus, isOpaque, isOptimizedDrawingEnabled, isPaintingForPrint, isPaintingTile, isRequestFocusEnabled, isValidateRoot, paintBorder, paintChildren, paintComponent, paintImmediately, paintImmediately, paramString, print, printAll, printBorder, printChildren, printComponent, processComponentKeyEvent, processKeyBinding, processKeyEvent, processMouseEvent, processMouseMotionEvent, putClientProperty, registerKeyboardAction, registerKeyboardAction, removeAncestorListener, removeNotify, removeVetoableChangeListener, repaint, requestDefaultFocus, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resetKeyboardActions, reshape, revalidate, scrollRectToVisible, setActionMap, setAlignmentX, setAlignmentY, setAutoscrolls, setBackground, setBorder, setComponentPopupMenu, setDebugGraphicsOptions, setDefaultLocale, setDoubleBuffered, setEnabled, setFocusTraversalKeys, setFont, setForeground, setInheritsPopupMenu, setInputMap, setInputVerifier, setMaximumSize, setMinimumSize, setNextFocusableComponent, setPreferredSize, setRequestFocusEnabled, setToolTipText, setTransferHandler, setUI, setVerifyInputWhenFocusTarget, setVisible, unregisterKeyboardAction, update, updateUI
 
Methods inherited from class java.awt.Container
add, add, add, add, add, addContainerListener, addImpl, addPropertyChangeListener, addPropertyChangeListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalKeys, getFocusTraversalPolicy, getLayout, getMousePosition, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, printComponents, processContainerEvent, processEvent, remove, remove, removeAll, removeContainerListener, setComponentZOrder, setFocusCycleRoot, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setLayout, transferFocusBackward, transferFocusDownCycle, validate, validateTree
 
Methods inherited from class java.awt.Component
action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, createImage, createImage, createVolatileImage, createVolatileImage, disableEvents, dispatchEvent, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getBackground, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusCycleRootAncestor, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getForeground, getGraphicsConfiguration, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputContext, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocale, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPeer, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getToolkit, getTreeLock, gotFocus, handleEvent, hasFocus, hide, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isPreferredSizeSet, isShowing, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, postEvent, prepareImage, prepareImage, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processMouseWheelEvent, remove, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, resize, resize, setBounds, setBounds, setComponentOrientation, setCursor, setDropTarget, setFocusable, setFocusTraversalKeysEnabled, setIgnoreRepaint, setLocale, setLocation, setLocation, setName, setSize, setSize, show, show, size, toString, transferFocus, transferFocusUpCycle
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

_metamgr

protected MetaMediaManager _metamgr
Handles most of our heavy lifting.


_animmgr

protected AnimationManager _animmgr
Legacy reference to avoid breaking children in the wild.


_spritemgr

protected SpriteManager _spritemgr
Legacy reference to avoid breaking children in the wild.


_remgr

protected RegionManager _remgr
Legacy reference to avoid breaking children in the wild.


_tickPaintPending

protected boolean _tickPaintPending
Used to correlate tick()s with paint()s.


_actionHandler

protected MediaPanel.ActionSpriteHandler _actionHandler
The action sprite handler, or null for none.


_actionSpriteCount

protected int _actionSpriteCount
The number of action/hover sprites being managed.


_obscurerList

protected ArrayList<MediaPanel.Obscurer> _obscurerList
Anyone registered as someone who might obscure the media panel (and thus require extra redrawing.

Constructor Detail

MediaPanel

public MediaPanel(FrameManager framemgr)
Constructs a media panel.

Method Detail

getViewBounds

public Rectangle getViewBounds()
Get the bounds of the viewport, in media coordinates. For the base MediaPanel, this will always be (0, 0, width, height).


getAnimationManager

public AnimationManager getAnimationManager()
Returns a reference to the animation manager used by this media panel.


getSpriteManager

public SpriteManager getSpriteManager()
Returns a reference to the sprite manager used by this media panel.


getRegionManager

public RegionManager getRegionManager()
Returns a reference to the region manager used by this media panel.


setPaused

public void setPaused(boolean paused)
Pauses the sprites and animations that are currently active on this media panel. Also stops listening to the frame tick while paused.


getTimeStamp

public long getTimeStamp()
Returns a timestamp from the MediaTimer used to track time intervals for this media panel. Note: this should only be called from the AWT thread.


addSprite

public void addSprite(Sprite sprite)
Adds a sprite to this panel.


isManaged

public boolean isManaged(Sprite sprite)
Returns:
true if the sprite is already added to this panel.

removeSprite

public void removeSprite(Sprite sprite)
Removes a sprite from this panel.


clearSprites

public void clearSprites()
Removes all sprites from this panel.


addAnimation

public void addAnimation(Animation anim)
Adds an animation to this panel. Animations are automatically removed when they finish.


isManaged

public boolean isManaged(Animation anim)
Returns:
true if the animation is already added to this panel.

abortAnimation

public void abortAnimation(Animation anim)
Aborts a currently running animation and removes it from this panel. Animations are normally automatically removed when they finish.


clearAnimations

public void clearAnimations()
Removes all animations from this panel.


createGraphics

public Graphics2D createGraphics()
Description copied from interface: MediaHost
Creates a graphics context for the component underlying this media host. This method can return null if the component is not currently displayable. The graphics created must be disposed by the caller.

Specified by:
createGraphics in interface MediaHost

tick

public void tick(long tickStamp)
Description copied from interface: FrameParticipant
This is called on all registered frame participants, one for every frame. Following the tick the interface will be rendered, so participants can prepare themselves for their upcoming render in this method (making use of the timestamp provided for the frame if choreography is desired between different participants).

Specified by:
tick in interface FrameParticipant

needsPaint

public boolean needsPaint()
Description copied from interface: FrameParticipant
Called immediately prior to FrameParticipant.getComponent() and then Component.paint(java.awt.Graphics) on said component, to determine whether or not this frame participant needs to be painted.

Specified by:
needsPaint in interface FrameParticipant

getComponent

public Component getComponent()
Description copied from interface: FrameParticipant
If a frame participant wishes also to be actively rendered every frame rather than use passive rendering (which for Swing, at least, is hijacked when using the frame manager such that we take care of repainting dirty Swing components every frame into our off-screen buffer), it can return a component here which will have Component.paint(java.awt.Graphics) called on it once per frame with a translated but unclipped graphics object.

Because clipping is expensive in terms of rectangle object allocation, frame participants are given the opportunity to do their own clipping because they are likely to want to clip to a more fine grained region than their entire bounds. If a participant does not wish to be actively rendered, it can safely return null.

Specified by:
getComponent in interface FrameParticipant

setOpaque

public void setOpaque(boolean opaque)
Overrides:
setOpaque in class JComponent

repaint

public void repaint(long tm,
                    int x,
                    int y,
                    int width,
                    int height)
Overrides:
repaint in class JComponent

paint

public void paint(Graphics g)
Overrides:
paint in class JComponent

addObscurer

public void addObscurer(MediaPanel.Obscurer obscurer)
Adds an element that could be obscuring the panel and thus requires extra redrawing.


removeObscurer

public void removeObscurer(MediaPanel.Obscurer obscurer)
Removes an obscuring element.


addObscurerDirtyRegions

protected void addObscurerDirtyRegions(boolean changedOnly)
Add dirty regions for all our obscurers.


addObscurerDirtyRegion

protected void addObscurerDirtyRegion(Rectangle region)
Adds the particular region as dirty.


willTick

protected void willTick(long tickStamp)
Derived classes can override this method and perform computation prior to the ticking of the sprite and animation managers.


didTick

protected void didTick(long tickStamp)
Derived classes can override this method and perform computation subsequent to the ticking of the sprite and animation managers.


paint

protected void paint(Graphics2D gfx,
                     Rectangle[] dirty)
Performs the actual painting of the media panel. Derived methods can override this method if they wish to perform pre- and/or post-paint activities or if they wish to provide their own painting mechanism entirely.


paintDirtyRect

protected void paintDirtyRect(Graphics2D gfx,
                              Rectangle rect)
Paints all the layers of the specified dirty region.


constrainToBounds

protected void constrainToBounds(Rectangle dirty)
Called by the main rendering code to constrain this dirty rectangle to the bounds of the media panel. If a derived class is using dirty rectangles that live in some sort of virtual coordinate system, they'll want to override this method and constraint the rectangles properly.


clipToDirtyRegion

protected void clipToDirtyRegion(Graphics2D gfx,
                                 Rectangle dirty)
This is called to clip the rendering output to the supplied dirty region. This should use Graphics.setClip(int, int, int, int) because the clipping region will need to be replaced as we iterate through our dirty regions. By default, a region is assumed to represent screen coordinates, but if a derived class wishes to maintain dirty regions in non-screen coordinates, it can override this method to properly clip to the dirty region.


dirtyScreenRect

protected void dirtyScreenRect(Rectangle rect)
Called to mark the specified rectangle (in screen coordinates) as dirty. The rectangle will be bent, folded and mutilated, so be sure you're not passing a rectangle into this method that is being used elsewhere.

If derived classes wish to convert from screen coordinates to some virtual coordinate system to be used by their repaint manager, this is the place to do it.


paintBehind

protected void paintBehind(Graphics2D gfx,
                           Rectangle dirtyRect)
Paints behind all sprites and animations. The supplied invalid rectangle should be redrawn in the supplied graphics context. Sub-classes should override this method to do the actual rendering for their display.


paintBetween

protected void paintBetween(Graphics2D gfx,
                            Rectangle dirtyRect)
Paints between the front and back layer of sprites and animations. The supplied invalid rectangle should be redrawn in the supplied graphics context. Sub-classes should override this method to do the actual rendering for their display.


paintInFront

protected void paintInFront(Graphics2D gfx,
                            Rectangle dirtyRect)
Paints in front of all sprites and animations. The supplied invalid rectangle should be redrawn in the supplied graphics context. Sub-classes should override this method to do the actual rendering for their display.


paintBits

protected void paintBits(Graphics2D gfx,
                         int layer,
                         Rectangle dirty)
Renders the sprites and animations that intersect the supplied dirty region in the specified layer. Derived classes can override this method if they need to do custom sprite or animation rendering (if they need to do special sprite z-order handling, for example). The clipping region will already be set appropriately.


createActionSpriteHandler

protected MediaPanel.ActionSpriteHandler createActionSpriteHandler()
Creates the mouse listener that will handle action sprites and their variants.