001: package org.zilonis.tool.ext.aerith.animation;
002:
003: import java.awt.Component;
004: import java.awt.Graphics;
005: import java.awt.Graphics2D;
006:
007: import javax.swing.JComponent;
008:
009: import org.zilonis.tool.ext.aerith.effects.ComponentEffect;
010: import org.zilonis.tool.ext.aerith.effects.ComponentState;
011: import org.zilonis.tool.ext.aerith.effects.CompositeEffect;
012: import org.zilonis.tool.ext.aerith.effects.EffectsManager;
013: import org.zilonis.tool.ext.aerith.effects.FadeIn;
014: import org.zilonis.tool.ext.aerith.effects.FadeOut;
015: import org.zilonis.tool.ext.aerith.effects.Move;
016: import org.zilonis.tool.ext.aerith.effects.Scale;
017: import org.zilonis.tool.ext.aerith.effects.Unchanging;
018:
019: /**
020: * This class holds the start and/or end states for a JComponent. It also
021: * determine (at <code>init()</code> time) the Effect to use during the
022: * upcoming transition and calls the appropriate Effect during the
023: * <code>paint()</code> method to cause the correct rendering of the
024: * component during the transition.
025: *
026: * @author Chet Haase
027: */
028: class AnimationState {
029:
030: /**
031: * The component for this AnimationState; there is one component per
032: * state, with either a start, an end, or both states.
033: */
034: private JComponent component;
035:
036: /**
037: * Start/end states for this AnimationState; these may be set to a non-null
038: * value or not, depending on whether the component exists in the
039: * respective screen of the transition.
040: */
041: private ComponentState start, end;
042:
043: /**
044: * Effect used to transition between the start and end states for this
045: * AnimationState. This effect is set during the init() method just
046: * prior to running the transition.
047: */
048: private ComponentEffect effect;
049:
050: /**
051: * Constructs a new AnimationState with either the start
052: * or end state for the component.
053: */
054: AnimationState(JComponent component, boolean isStart) {
055: this .component = component;
056: ComponentState compState = new ComponentState(component);
057: if (isStart) {
058: start = compState;
059: } else {
060: end = compState;
061: }
062: }
063:
064: void setStart(ComponentState compState) {
065: start = compState;
066: }
067:
068: void setEnd(ComponentState compState) {
069: end = compState;
070: }
071:
072: ComponentState getStart() {
073: return start;
074: }
075:
076: ComponentState getEnd() {
077: return end;
078: }
079:
080: Component getComponent() {
081: return component;
082: }
083:
084: /**
085: * Called just prior to running the transition. This method examines the
086: * start and end states as well as the ComponentEffect repository to
087: * determine the appropriate Effect to use during the transition for
088: * this AnimationState. If there is an existing custom effect defined
089: * for the component for this type of transition, we will use that
090: * effect, otherwise we will default to the appropriate effect (fading
091: * in, fading out, or moving/resizing).
092: */
093: void init() {
094: if (start == null) {
095: effect = new FadeIn(end);
096: } else if (end == null) {
097: effect = new FadeOut(start);
098: } else {
099: effect = EffectsManager.getEffect(component,
100: EffectsManager.TransitionType.CHANGING);
101: if (effect == null) {
102: // No custom effect; use move/scale combinations
103: // as appropriate
104: boolean move = false, scale = false;
105: if (start.getX() != end.getX()
106: || start.getY() != end.getY()) {
107: move = true;
108: }
109: if (start.getWidth() != end.getWidth()
110: || start.getHeight() != end.getHeight()) {
111: scale = true;
112: }
113: if (move) {
114: if (scale) {
115: // move/scale
116: ComponentEffect moveEffect = new Move(start,
117: end);
118: ComponentEffect scaleEffect = new Scale(start,
119: end);
120: effect = new CompositeEffect(moveEffect);
121: ((CompositeEffect) effect)
122: .addEffect(scaleEffect);
123: } else {
124: // just move
125: effect = new Move(start, end);
126: }
127: } else {
128: if (scale) {
129: // just scale
130: effect = new Scale(start, end);
131: } else {
132: // Noop
133: effect = new Unchanging(start, end);
134: }
135: }
136: } else {
137: // Custom effect; set it up for this transition
138: effect.setStart(start);
139: effect.setEnd(end);
140: }
141: }
142: }
143:
144: /**
145: * Render this AnimationState into the given Graphics object with the
146: * given elapsed fraction for the transition. This is done by calling
147: * into the effect to first set up the Graphics object given the
148: * transition fraction and then to do the actual rendering using the
149: * Graphics object.
150: */
151: void paint(Graphics g, float fraction) {
152: if (effect != null) {
153: Graphics2D g2d = (Graphics2D) g.create();
154: effect.setup(g2d, fraction);
155: effect.paint(g2d);
156: g2d.dispose();
157: }
158: }
159: }
|