|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object com.hdcookbook.grin.Show
public class Show
Represents a show. A show is the top-level node in a scene graph. It is composed of a number of segments. A show progresses by moving through segments; a show has exactly one active segment while it is running. A segment is composed of a number of visual features, plus a set of remote control handlers.
Field Summary | |
---|---|
java.awt.Component |
component
The component we're presented within. |
protected Feature[] |
features
|
protected java.lang.String[] |
fontName
|
protected int[] |
fontStyleSize
|
ShowInitializer |
initializer
An object used to hold state during initializaition of a show. |
protected java.util.Hashtable |
publicFeatures
|
protected java.util.Hashtable |
publicNamedCommands
|
protected java.util.Hashtable |
publicRCHandlers
|
protected java.util.Hashtable |
publicSegments
|
protected RCHandler[] |
rcHandlers
|
protected Segment[] |
segments
|
SetupManager |
setupManager
Our helper that calls into us to load images and such. |
protected Segment |
showTop
This is a dummy segment which contains one feature in its activated feature array, which represents the top of the rendering tree. |
protected Group |
showTopGroup
A group representing a set of activated features in the currently activated Segment. |
protected ManagedImage[] |
stickyImages
This is the set of images that are "sticky". |
Constructor Summary | |
---|---|
Show(Director director)
Create a new show. |
Method Summary | |
---|---|
void |
activateSegment(Segment seg)
Set the current segment. |
void |
activateSegment(Segment seg,
boolean push)
Set the current segment. |
void |
addDisplayAreas(RenderContext context)
Tell the animation manager what areas need to be drawn to for the next frame. |
void |
buildShow(Segment[] segments,
Feature[] features,
RCHandler[] rcHandlers,
java.lang.String[] stickyImages,
Segment showTop,
Group showTopGroup,
java.util.Hashtable publicSegments,
java.util.Hashtable publicFeatures,
java.util.Hashtable publicRCHandlers,
java.util.Hashtable publicNamedCommands,
java.lang.String[] fontName,
int[] fontStyleSize)
This is called to build the show. |
void |
deferNextCommands()
This method, which should ONLY be called from the execute() method of a command, suspends processing of further queued commands until the display of the show has caught up with the screen. |
void |
destroy()
Destroy this animatin client. |
void |
doActivateSegment(Segment newS)
This is called from ActivateSegmentCommand, and should not be called from anywhere else. |
void |
doSegmentDone()
This is called from GrinXHelper(SEGMENT_DONE), and should not be called from anywhere else. |
Segment |
getCurrentSegment()
Get the current segment. |
Director |
getDirector()
Get this show's director. |
java.lang.String[] |
getDrawTargets()
Get the set of draw target names. |
Feature |
getFeature(java.lang.String name)
Look up the given public feature. |
java.awt.Font |
getFont(int index)
Get one of the fonts recorded for this show. |
Command |
getNamedCommand(java.lang.String name)
Look up the given public named command or command list. |
RCHandler |
getRCHandler(java.lang.String name)
Get a public RC handler by name. |
Segment |
getSegment(java.lang.String name)
Look up a public segment. |
int |
getSegmentStackDepth()
Get the depth of the segment stack. |
int |
getXOffset()
Get the x offset that this show was built with. |
int |
getXScale()
Get the x scale factor, in mills. |
int |
getYOffset()
Get the y offset that this show was built with. |
int |
getYScale()
Get the y scale factor, in mills. |
boolean |
handleKeyPressed(int vkCode)
Called by the xlet when a key press is received. |
boolean |
handleKeyReleased(int vkCode)
Called by the xlet when a key release is received. |
boolean |
handleKeyTyped(RCKeyEvent typed)
Called by the xlet when a key typed event is received, or generated (e.g. |
void |
handleMouseClicked(int x,
int y)
Called by the xlet when the mouse is clicked. |
void |
handleMouseMoved(int x,
int y)
Called by the xlet when the mouse moves. |
void |
initialize(java.awt.Component component)
Initialize the animation client. |
void |
internalHandleKeyPressed(RCKeyEvent re,
Show caller)
This is an implementation method, called by RCKeyEvent |
void |
internalHandleKeyReleased(RCKeyEvent re,
Show caller)
This is an implementation method, called by RCKeyEvent |
void |
internalHandleKeyTyped(RCKeyEvent re,
Show caller)
This method is to be called by a subclass of RCKeyEvent that is created by someone extending GRIN to support key typed events. |
void |
mapDrawTargets(java.util.Hashtable targetMap)
Map draw target names into the numeric values that are required by the animation engine. |
void |
nextFrame()
Advance the state of the show to the next frame. |
void |
paintDone()
Called when the animation framework is done painting the current frame. |
void |
paintFrame(java.awt.Graphics2D gr)
Paint the current frame of the animation. |
Segment |
popSegmentStack()
Used by the activate segment command. |
void |
pushCurrentSegment()
Used by the activate segment command. |
void |
runCommand(Command cmd)
Run the given command when we advance to the next frame. |
void |
runCommands(Command[] cmds)
Run the given commands when we advance to the next frame. |
static int |
scale(int value,
int mills)
Scale a value by a scale factor in mills. |
void |
segmentDone()
Signal to the show that the current segment is done. |
void |
setCaughtUp()
Indicate to the animation client that we're not behind in the animation, so that the current frame will actually be displayed. |
void |
setDrawTargets(java.lang.String[] drawTargets)
Used to build the show, or to reinitialize it. |
void |
setScale(int xScale,
int yScale,
int xOffset,
int yOffset)
Sets the scale and offset values for a show. |
void |
setSegmentStackDepth(int depth)
Used to build the show. |
void |
syncDisplay()
Synchronize the display to the current show state. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public SetupManager setupManager
public java.awt.Component component
public ShowInitializer initializer
protected Segment[] segments
protected Feature[] features
protected RCHandler[] rcHandlers
protected java.util.Hashtable publicSegments
protected java.util.Hashtable publicFeatures
protected java.util.Hashtable publicRCHandlers
protected java.util.Hashtable publicNamedCommands
protected ManagedImage[] stickyImages
This array may be null.
protected Segment showTop
protected Group showTopGroup
protected java.lang.String[] fontName
protected int[] fontStyleSize
Constructor Detail |
---|
public Show(Director director)
director
- A Director helper class the xlet can use to control
the show. May be null, in which case a default
direct instance of Director will be assigned.Method Detail |
---|
public Director getDirector()
public void buildShow(Segment[] segments, Feature[] features, RCHandler[] rcHandlers, java.lang.String[] stickyImages, Segment showTop, Group showTopGroup, java.util.Hashtable publicSegments, java.util.Hashtable publicFeatures, java.util.Hashtable publicRCHandlers, java.util.Hashtable publicNamedCommands, java.lang.String[] fontName, int[] fontStyleSize) throws java.io.IOException
java.io.IOException
- if anything goes wrong.public void setScale(int xScale, int yScale, int xOffset, int yOffset)
public java.awt.Font getFont(int index)
public void initialize(java.awt.Component component)
This will be called by the animation framework; clients of the GRIN framework should ensure a show has been built before handing it off to the animation framework.
initialize
in interface AnimationClient
component
- The component this show will eventually be displayed
in. It's used for things like
Component.prepareImage().public void destroy()
Destroy a show. This will be called by the animation framework when the animation engine is destroyed, or when this show is removed from the engine's list of shows.
destroy
in interface AnimationClient
public void setSegmentStackDepth(int depth)
public void setDrawTargets(java.lang.String[] drawTargets)
public java.lang.String[] getDrawTargets()
getDrawTargets
in interface AnimationClient
RenderContext.setTarget(int)
,
mapDrawTargets(Hashtable)
,
SetTarget
public void mapDrawTargets(java.util.Hashtable targetMap)
The total number of different draw targets in an animation should be small, because the algorithm for combining draw targets is of cubic time complexity. One or two different draw targets might be a typical number, and more than four is questionable.
See addDisplayAreas() for a discussion of what a render area target is for.
mapDrawTargets
in interface AnimationClient
targetMap
- A hashtable mapping String names to Integer valuesRenderContext.setTarget(int)
,
AnimationClient.addDisplayAreas(RenderContext)
public Feature getFeature(java.lang.String name)
public Command getNamedCommand(java.lang.String name)
public RCHandler getRCHandler(java.lang.String name)
public Segment getSegment(java.lang.String name)
public int getSegmentStackDepth()
public void activateSegment(Segment seg)
This can be called from any thread; it does not take out the show lock or any other global locks. If the show has been destroyed, calling this method has no effect. It's OK to call this before the show has been initialized.
The current segment is not pushed onto the segment activation stack.
seg
- The segment to activate, or null to pop the
segment activation stack;public void activateSegment(Segment seg, boolean push)
This can be called from any thread; it does not take out the show lock or any other global locks. If the show has been destroyed, calling this method has no effect.
seg
- The segment to activate, or null to pop the
segment activation stack.push
- When true and when the segment is non-null, the
current segment will be pushed onto the
segment activation stack as the show transitions to
the new segment.public void pushCurrentSegment()
public Segment popSegmentStack()
public void syncDisplay()
Note carefully the difference between syncDisplay() and deferNextCommands(). If you're about to queue a command that does something time-consuming, then you should call syncDisplay() first, so the display is guaranteed to be updated. If, however, you're executing within the body of the command and you want to make sure the display gets synchronized before the next command in the queue (which was already there), then you want to call deferNextCommands().
This is equivalent to the sync_display
GRIN command.
deferNextCommands()
public void segmentDone()
This is equivalent to the segment_done
GRIN command.
public void runCommand(Command cmd)
This can be called from any thread; it does not take out the show lock or any other global locks. If the show has been destroyed, calling this method has no effect. It's OK to call this before the show has been initialized.
runCommands(Command[])
public void runCommands(Command[] cmds)
This can be called from any thread; it does not take out the show lock or any other global locks. If the show has been destroyed, calling this method has no effect. It's OK to call this before the show has been initialized.
runCommand(Command)
public void setCaughtUp()
The animation framework calls this method just before calling nextFrame() if the animation loop is caught up. From time to time, pending commands will be deferred until animation has caught up - this is done by the sync_display command. GRIN knows we've caught up when we paint a frame, but calling this method can let it know one frame earlier.
setCaughtUp
in interface AnimationClient
nextFrame()
public void nextFrame() throws java.lang.InterruptedException
This method can be called multiple times before any attempt is made to display the UI state. This happens when animation falls behind; the engine catches up by skipping frames. Animation clients should perform only quick updates in this method; any more time-consuming calculations should be deferred until an object is first painted for a given frame.
nextFrame
in interface AnimationClient
java.lang.InterruptedException
- if the show has been destroyedsetCaughtUp()
public void deferNextCommands()
Doing this can be useful, for example, just before an operation that is time-consuming and CPU-bound on some players, like JMF selection.
syncDisplay()
public void doActivateSegment(Segment newS)
public void doSegmentDone()
public Segment getCurrentSegment()
public void addDisplayAreas(RenderContext context) throws java.lang.InterruptedException
In this call, the client must indicate where it intends to draw by calling methods on RenderContext. Internally, a RenderContext keeps a number of rendering area "targets". Each target will keep track of a bounding rectangle of all of drawing operations that are considered within that target. When the call to addDisplayAreas is complete, the animation manager may merge some of these rendering areas targets, or may leave them seperate; it will then call paintFrame() as many times as it needs to, with a different clip rect each time. These clip rects will never overlap, so you don't need to worry about a Src mode drawing to the same pixel twice in the same frame.
The purpose of these targets is to try to minimize the number of pixels that will be updated on the screen in each frame of animation. Consider, for example, the case where most of the screen isn't changing, but where there's a small animation in the upper-left hand corner, and another small animation in the lower-right hand corner. If those two animations used the same target, the overall bounding rectangle would cover the whole screen. By using two different targets, the screen update can be confined to two small rectangles, one at each corner.
The number of render area targets is set up when an AnimationEngine is created, by calling mapDrawTargets() on each client. During animation, each AnimationClient is passed the same set of targets. If there are multiple AnimationClient instances attached to an AnimationEngine, it is up to the programmer to decide which render area targets should be shared between clients so as to optimize drawing performance. This can be done with appropriate naming of the targets in the mapDrawTargets() call.
Often, an AnimationClient only needs to erase or draw objects that have changed. However, under certain circumstances, the AnimationClient will be asked to redraw everything. This will happen on the first frame drawn, and possibly on others. For example, with repaint draw and platform double-buffering, the platform erases the buffer for each frame, so a full redraw is required. When this happens, the animation enginer automatically adds the full extent of the component to one of the targets. In this case, it still calls this method, so that items we draw have the opportunity to erase themselves if needed.
This method will be called exactly once for each frame displayed. Because paintFrame can be called multiple times per frame, any state maintained by the animation client to optimize display areas should be updated in this method, and not in paintFrame().
addDisplayAreas
in interface AnimationClient
context
- The RenderContext that manages the set of
targets the client can draw to.
java.lang.InterruptedException
- if the thread has been interrupted
(e.g. because the xlet is being killed)RenderContext.setTarget(int)
,
AnimationClient.mapDrawTargets(Hashtable)
public void paintFrame(java.awt.Graphics2D gr) throws java.lang.InterruptedException
The animation client shouldn't erase screen areas in this call. That
can be handled more efficiently (for some drawing styles) via
RenderArea.clearAndAddArea()
Paint the current state of the enhancement. This should be called by the xlet, usually via the animation framework.
paintFrame
in interface AnimationClient
gr
- The graphics context to draw to, set to Src drawing mode
java.lang.InterruptedException
- if the thread has been interrupted
(e.g. because the xlet is being killed)RenderContext.addArea(DrawRecord)
public void paintDone()
paintDone
in interface AnimationClient
public boolean handleKeyPressed(int vkCode)
A key pressis queued and true is returned only if the current segment uses that key press It is possible that the show will have a different current segment by the time the key press is processed, so there's some chance that a key press won't be queued, even if it is of interest to the state the show's about to be in. This should almost always be harmless, but if you wish to capture all key presses in your show, you can populate the needed segments with a key_pressed rc_handler with an empty body that captures all keys.
public void internalHandleKeyPressed(RCKeyEvent re, Show caller)
public boolean handleKeyReleased(int vkCode)
A key release is queued and true is returned only if the current segment uses that key release. It is possible that the show will have a different current segment by the time the key release is processed, so there's some chance that a key release won't be queued, even if it is of interest to the state the show's about to be in. This should almost always be harmless, but if you wish to capture all key releases in your show, you can populate the needed segments with a key_released rc_handler with an empty body that captures all keys.
public void internalHandleKeyReleased(RCKeyEvent re, Show caller)
public boolean handleKeyTyped(RCKeyEvent typed)
A key typed event is queued and true is returned only if the current segment uses that key typed event.
public void internalHandleKeyTyped(RCKeyEvent re, Show caller)
public void handleMouseMoved(int x, int y)
Note that mouse events are handled synchronously, unlike remote control keypresses which are queued within the show. We assume that only fast players (like PC players) support mice.
public void handleMouseClicked(int x, int y)
Note that mouse events are handled synchronously, unlike remote control keypresses which are queued within the show. We assume that only fast players (like PC players) support mice.
public static int scale(int value, int mills)
(value * mills + 500) / 1000No function is provided to recover the original value from the scaled value (and such a function would suffer from loss of precision). In a scaled show, we recommend only setting translation values, and never getting them.
getXScale()
,
getYScale()
public int getXScale()
scale(int, int)
public int getYScale()
scale(int, int)
public int getXOffset()
public int getYOffset()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |