com.hdcookbook.grin.features
Class FixedImage

java.lang.Object
  extended by com.hdcookbook.grin.Feature
      extended by com.hdcookbook.grin.features.FixedImage
All Implemented Interfaces:
Node, SetupClient
Direct Known Subclasses:
SEFixedImage

public class FixedImage
extends Feature
implements Node, SetupClient

Represents a fixed image.

Author:
Bill Foote (http://jovial.com)

Field Summary
protected  java.lang.String fileName
           
protected  ManagedImage image
           
protected  java.awt.Rectangle placement
           
protected  java.awt.Rectangle scaledBounds
           
protected  InterpolatedModel scalingModel
           
 
Fields inherited from class com.hdcookbook.grin.Feature
name, show
 
Constructor Summary
FixedImage(Show show)
           
 
Method Summary
 void addDisplayAreas(RenderContext context)
          Add all of the areas that are displayed for this feature with the current frame.
protected  Feature createClone(java.util.HashMap clones)
          This is an implementation method that should not be called direction by applications; applications should call cloneSubgraph().
 void destroy()
          Free any resources held by this feature.
 void doSomeSetup()
          Do some (or all) of the setup work needed for this client.
 ManagedImage getImage()
          Get the underlying image that we display.
 java.awt.Rectangle getMutablePlacement()
          Get the placement of this image, that is, the x, y, position, the width and the height.
 int getX()
          Get the upper-left hand corner of this feature as presently displayed.
 int getY()
          Get the upper-left hand corner of this feature as presently displayed Return Integer.MAX_VALUE if this feature has no visible representation.
 void initialize()
          Initialize this feature.
protected  void initializeClone(Feature original, java.util.HashMap clones)
          This is an implementation method that should not be called direction by applications; it is called from cloneSubgraph().
 void markDisplayAreasChanged()
          Mark the display areas of this feature as modified for the next call to addDisplayAreas.
 boolean needsMoreSetup()
          This is where the feaure says whether or not it needs more setup.
 void nextFrame()
          Called from Segment with the Show lock held, to advance us to the state we should be in for the next frame.
 void paintFrame(java.awt.Graphics2D gr)
          Paint the current state of this feature to gr.
 void readInstanceData(GrinDataInputStream in, int length)
          Reads in this node information from the binary file format.
 void replaceImage(ManagedImage newImage)
          Set the image being displayed by this FixedImage.
protected  void setActivateMode(boolean mode)
          Change the activated mode of this feature.
 void setImageSizeChanged()
          Notify us that our image size has changed.
protected  int setSetupMode(boolean mode)
          Change the setup mode of this feature.
 
Methods inherited from class com.hdcookbook.grin.Feature
activate, addSubgraph, cloneCommands, clonedReference, cloneSubgraph, deactivate, destroyClonedSubgraph, getName, isSetup, makeNewClone, resetFeature, sendFeatureSetup, setName, setup, toString, unsetup
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

placement

protected java.awt.Rectangle placement

fileName

protected java.lang.String fileName

scalingModel

protected InterpolatedModel scalingModel

scaledBounds

protected java.awt.Rectangle scaledBounds

image

protected ManagedImage image
Constructor Detail

FixedImage

public FixedImage(Show show)
Method Detail

createClone

protected Feature createClone(java.util.HashMap clones)
This is an implementation method that should not be called direction by applications; applications should call cloneSubgraph(). New subclasses of Feature that wish to support cloning must override this method.

Create a new clone of this feature. This method creates a new instance of this feature, and creates new instances of any sub-features, but it does not initialize the feature. This method is called from Feature.makeNewClone().

See the documentation of cloneSubgraph() for a list of runtime exceptions this method can throw. Subclasses that wish to support cloning must override this method.

Overrides:
createClone in class Feature
Parameters:
clones - A map from original feature to cloned feature. Entries are added by Feature.makeNewClone().
See Also:
Feature.makeNewClone(java.util.HashMap), Feature.cloneSubgraph(java.util.HashMap)

initializeClone

protected void initializeClone(Feature original,
                               java.util.HashMap clones)
This is an implementation method that should not be called direction by applications; it is called from cloneSubgraph(). New subclasses of Feature may override this method.

Initialize this cloned feature from its original. This is called after the entire subgraph has been cloned, so the HashMap containing the set of clones will be complete. See the documentation of cloneSubgraph() for a list of runtime exceptions this method can throw. Subclasses that wish to support cloning must override this method.

If this feature doesn't need initialization it's OK for a feature to not implement it; the default version of this method does nothing. Typically, you only need to implement this for features that have references to other features that aren't sub-features, or that have commands that might have references to other features.

Overrides:
initializeClone in class Feature
See Also:
Feature.cloneSubgraph(java.util.HashMap)

initialize

public void initialize()
Initialize this feature. This is called on show initialization. A show will initialize all of its features after it initializes the segments.

Specified by:
initialize in class Feature

getX

public int getX()
Get the upper-left hand corner of this feature as presently displayed. Return Integer.MAX_VALUE if this feature has no visible representation.

Specified by:
getX in class Feature
Returns:
the x coordinate

getY

public int getY()
Get the upper-left hand corner of this feature as presently displayed Return Integer.MAX_VALUE if this feature has no visible representation.

Specified by:
getY in class Feature
Returns:
the y coordinate

getMutablePlacement

public java.awt.Rectangle getMutablePlacement()
Get the placement of this image, that is, the x, y, position, the width and the height. You can modify these values, so long as you do so in a thread-safe manner, e.g. with the Show lock held. Usually, this means modifying them from a Show command.

If you change the width or height, you must call setImageSizeChanged().

See Also:
setImageSizeChanged()

setImageSizeChanged

public void setImageSizeChanged()
Notify us that our image size has changed. It can be changed by setting the width or height of our placement. If this is done, setImageSizeChanged() must be called, to guarantee that the now-modified image will get drawn to the screen.

See Also:
getMutablePlacement()

getImage

public ManagedImage getImage()
Get the underlying image that we display. Neither the reference count nor the prepare count are adjusted.


replaceImage

public void replaceImage(ManagedImage newImage)
Set the image being displayed by this FixedImage. The old image will be de-referenced (and, if needed, unprepared) by FixedImage, and the new image will be referenced (and, if needed, prepared) by FixedImage. If this FixedImage feature is set up, then the new image must have been loaded. If it isn't, an IllegalStateException will be thrown.

Note that if you have a ManagedImage instance that you want to forget about after you give it to FixedImage, if you've prepared it you'll have to call ManagedImage.unprepare() after giving FixedImage the instance (because FixedImage itself calls prepare()). Similarly, you'll need to call ImageManager.ungetImage() after giving FixedImage the instance. In other words, when give FixedImage the instance, it increments the reference counts, so you have to decrement the reference counts you added when you first referenced the ManagedImage.

This method must only be called when it is safe to do so, according to the threading model, and with the Show lock held. Usually, this means calling it from a Show command.

Code using this method to swap out an image with one that's to be displayed at a different size might look something like this:

 FixedImage fi = ...  the place you want to put the image
 ManagedImage mi = ... the image you want to put there
 fi.replaceImage(mi);
 Rectangle r = fi.getMutablePlacement();
 r.x, r.y = the upper-left hand corner where you want it to be
 r.width, r.height = the values you want (which can be taken
                        from mi.getWidth() and mi.getHeight()
 fi.setImageSizeChanged();
Code that gets a new image from the ImageManager and swaps it into a new image to FixedImage instance that isn't set up is fairly straightforward: { FixedImage fi = ... the feature URL url = ... the place the image comes from ManagedImage mi = ImageManager.getImage(url); fi.replaceImage(mi); ImageManager.ungetImage(mi); // mi goes out of scope }

Throws:
java.lang.IllegalStateException - if this feature is set up, and newImage has not been loaded. Also thrown if newImage.isReferenced() is false.

destroy

public void destroy()
Free any resources held by this feature. It is the opposite of initialize().

It's possible an active segment may be destroyed. For example, the last segment a show is in when the show is destroyed will probably be active (and it will probably be an empty segment too!).

Specified by:
destroy in class Feature

setActivateMode

protected void setActivateMode(boolean mode)
Change the activated mode of this feature. The new mode will always be different than the old. Clients of the GRIN framework should never call this method directly. Custom feature extensions must implement this method.

Specified by:
setActivateMode in class Feature

setSetupMode

protected int setSetupMode(boolean mode)
Change the setup mode of this feature. The new mode will always be different than the old. Clients of the GRIN framework should never call this method directly. Custom feature extensions must implement this method.

This method must return a guaranteed lower bound for the number of times it will send a feature setup command as a result of this call. That is, it must send at least as many feature setup commands to the segment as the number returned; sending an accurate number makes the setup process more efficient, since the time it takes to process a command scales with the number of features in a segment. When mode is false, 0 should be returned.

Specified by:
setSetupMode in class Feature

doSomeSetup

public void doSomeSetup()
Do some (or all) of the setup work needed for this client. This might be called when setup is no longer required; in this case, the client should just return.

Specified by:
doSomeSetup in interface SetupClient

needsMoreSetup

public boolean needsMoreSetup()
This is where the feaure says whether or not it needs more setup. Calls to this are synchronized within the init manager to avoid race conditions. The implementation of this method must not call outside code or call any animation manager methods. For a given setup cycle, this method is called only after setup(). Clients of the GRIN framework should never call this method directly. Custom feature extensions must implement this method.

Specified by:
needsMoreSetup in interface SetupClient
Specified by:
needsMoreSetup in class Feature
See Also:
SetupClient.needsMoreSetup()

paintFrame

public void paintFrame(java.awt.Graphics2D gr)
Paint the current state of this feature to gr. Clients of the GRIN framework should not call this method directly. Feature subclasses must implement this method.

Specified by:
paintFrame in class Feature
Parameters:
gr - The place to paint to.

markDisplayAreasChanged

public void markDisplayAreasChanged()
Mark the display areas of this feature as modified for the next call to addDisplayAreas. This can be called by a parent node on its children, e.g. when the parent is deactivated. This is necessary because a parent node might modify the drawing of its children (e.g. by setting an alpha value), and a parent might be taken out of a render tree when its children are not.

See also Issue 121

Specified by:
markDisplayAreasChanged in class Feature
See Also:
Feature.addDisplayAreas(com.hdcookbook.grin.animator.RenderContext)

addDisplayAreas

public void addDisplayAreas(RenderContext context)
Add all of the areas that are displayed for this feature with the current frame. This will be called exactly once per frame displayed on each activated feature.

A feature that displays something needs to maintain a record of it in a DrawRecord. The animation framework uses this to track what needs to be erased and drawn from frame to frame.

Clients of the GRIN framework should not call this method directly. Feature subclasses must implement this method.

Specified by:
addDisplayAreas in class Feature
Parameters:
context - The context for tracking rendering state
See Also:
DrawRecord

nextFrame

public void nextFrame()
Called from Segment with the Show lock held, to advance us to the state we should be in for the next frame.

Specified by:
nextFrame in class Feature

readInstanceData

public void readInstanceData(GrinDataInputStream in,
                             int length)
                      throws java.io.IOException
Description copied from interface: Node
Reads in this node information from the binary file format.

An implementation of this method is recommended to call in.readSuperClassData(this) as the first line of the method to read in information that is defined in the base class of this Node type.

This should only be called while initializing this object.

Specified by:
readInstanceData in interface Node
Parameters:
in - InputStream to read data from.
length - the number of bytes that this node's information occupies in the InputStream. The implementation of this method is expected to read exactly this number of bytes from the stream. This can be used for a debugging purpose.
Throws:
java.io.IOException - if error occurs.
See Also:
GrinDataInputStream.readSuperClassData(Feature), GrinDataInputStream.readSuperClassData(RCHandler), GrinDataInputStream.readSuperClassData(Segment), GrinDataInputStream.readSuperClassData(Command)