001: package com.xoetrope.swing;
002:
003: import com.xoetrope.swing.animation.AnimationStep;
004: import com.xoetrope.swing.animation.AnimationThread;
005: import com.xoetrope.swing.animation.XAnimationContext;
006: import com.xoetrope.swing.animation.XAnimationSurface;
007: import java.awt.AlphaComposite;
008: import java.awt.Color;
009:
010: import java.awt.Dimension;
011: import java.awt.Font;
012: import java.awt.FontMetrics;
013: import java.awt.GradientPaint;
014: import java.awt.Graphics2D;
015: import java.awt.Point;
016: import java.awt.Shape;
017: import java.awt.font.FontRenderContext;
018: import java.awt.font.TextLayout;
019: import java.awt.geom.AffineTransform;
020: import java.awt.geom.Point2D;
021: import java.awt.geom.Rectangle2D;
022:
023: /**
024: * Displays text by scrolling/animating its position across the controls width.
025: * Not all the text need be visible at once. The animation can be one-off or a
026: * loop
027: *
028: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
029: * the GNU Public License (GPL), please see license.txt for more details. If
030: * you make commercial use of this software you must purchase a commercial
031: * license from Xoetrope.</p>
032: * <p> $Revision: 1.18 $</p>
033: */
034: public class XMarqueeText extends XAnimationSurface //implements AnimationStep, XAnimationContext
035: {
036: protected int fade;
037: protected int loopLength;
038: protected int ascent;
039: protected int maxExtent;
040:
041: // Debugging/diagnostic code variables
042: //private static int frames;
043: //private static long startTime;
044: protected TextLayout layout;
045:
046: /**
047: * Create a new marquee
048: */
049: public XMarqueeText() {
050: fade = 0;
051: maxExtent = 1000;
052: increment = 300;
053: setDoubleBuffered(true);
054: setLoopTime(60000);
055: setSleepTime(32);
056: }
057:
058: /**
059: * Attempts to load and reference the associated view/datastore.
060: */
061: public void init() {
062: Point p = getLocation();
063: Dimension size = getSize();
064: oX = p.x;
065: oY = p.y;
066: oW = size.width;
067: oH = size.height;
068: inc = oW;
069: }
070:
071: /**
072: * This method will receive all of the timing events from an Animator
073: * during an animation. The fraction is the percent elapsed (0 to 1)
074: * of the current animation cycle.
075: * @param fraction the fraction of completion between the start and
076: * end of the current cycle. Note that on reversing cycles
077: * ({@link Animator.Direction#BACKWARD}) the fraction decreases
078: * from 1.0 to 0 on backwards-running cycles. Note also that animations
079: * with a duration of {@link Animator#INFINITE INFINITE} will call
080: * timingEvent with an undefined value for fraction, since there is
081: * no fraction that makes sense if the animation has no defined length.
082: * @see Animator.Direction
083: */
084: public void timingEvent(float fraction) {
085: timingFraction = fraction;
086: repaint();
087: }
088:
089: //=========================================================================
090: // Rendering
091: //=========================================================================
092:
093: /**
094: * All classes that extend JAnimationSurface must implement this routine...
095: * @param w the width
096: * @param h the height
097: * @param g2 the graphics context
098: */
099: public void drawObjects(int w, int h, Graphics2D g2) {
100: if ((label == null) || (label.length() <= 0))
101: return;
102:
103: //inc = (int)((long)oW - animationThread.getStepPosition() % maxExtent );
104: inc = (int) ((long) oW - (timingFraction * maxExtent));
105:
106: Color bkColor = getBackground();
107: g2.setColor(bkColor);
108: g2.fillRect(0, 0, oW, oH);
109: g2.setColor(getForeground());
110: if (layout == null) {
111: Font font = getFont();
112: FontMetrics fm = g2.getFontMetrics(font);
113: FontRenderContext frc = g2.getFontRenderContext();
114:
115: Point2D.Double pen = new Point2D.Double(0, 0);
116: layout = new TextLayout(label, font, frc);
117: //layoutShape = layout.getOutline( null );
118: ascent = fm.getAscent();
119: }
120:
121: AffineTransform at = AffineTransform.getTranslateInstance(inc,
122: (oH + ascent) / 2);
123: Shape s = layout.getOutline(at);// at.createTransformedShape( layoutShape );
124:
125: // Paint the full/new version
126: g2.fill(s);
127:
128: if (fade > 0) {
129: int fadeWidth = (oW * fade) / 100;
130:
131: // Fade out the start
132: GradientPaint painter = new GradientPaint(0.0F, 0.0F,
133: new Color(bkColor.getRed(), bkColor.getGreen(),
134: bkColor.getBlue(), 255), fadeWidth, 0.0F,
135: new Color(bkColor.getRed(), bkColor.getGreen(),
136: bkColor.getBlue(), 0), false);
137: g2.setPaint(painter);
138: g2.fill(new Rectangle2D.Double(0, 0, fadeWidth, oH));
139:
140: // Fade out the end
141: GradientPaint painter2 = new GradientPaint(oW - fadeWidth,
142: 0.0F, new Color(bkColor.getRed(), bkColor
143: .getGreen(), bkColor.getBlue(), 0), oW,
144: 0.0F, new Color(bkColor.getRed(), bkColor
145: .getGreen(), bkColor.getBlue(), 255), false);
146: g2.setPaint(painter2);
147: g2.fill(new Rectangle2D.Double(oW - fadeWidth, 0,
148: fadeWidth, oH));
149: }
150:
151: maxExtent = ((int) s.getBounds().getWidth()) + increment;
152: }
153:
154: //=========================================================================
155: // Access Functions
156: //=========================================================================
157: /**
158: * Set the percentage of the width over which to fade the ends in and out.
159: * By default the fade is set to zero for no fade.
160: * @param percentage the new fade percentage
161: */
162: public void setFade(int percentage) {
163: fade = percentage;
164: }
165:
166: /**
167: * Get the percentage of the width over which to fade the ends in and out.
168: * By default the fade is set to zero for no fade.
169: * @return the new fade percentage
170: */
171: public int getFade() {
172: return fade;
173: }
174:
175: public void setRampUp(int rampUp) {
176:
177: }
178:
179: /**
180: * Set one or more attributes of the component.
181: * @param attribName the name of the attribute
182: * <ul>
183: * <li>fade - the percentage of the width by which to fade each end of the marquee</li>
184: * </ul>
185: * @param attribValue the value of the attribute
186: * @return 0 for success, non zero otherwise
187: */
188: public int setAttribute(String attribName, Object attribValue) {
189: String attribNameLwr = attribName.toLowerCase();
190: String attribValueStr = (String) attribValue;
191: if (attribNameLwr.equals("fade"))
192: setFade(Integer.parseInt(attribValueStr));
193: else
194: super .setAttribute(attribName, attribValue);
195:
196: return 0;
197: }
198:
199: private int inc = 0;
200: protected int oX, oY, oW, oH;
201: }
|