001: /*
002: * Copyright (c) 2001-2006 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.animation.tutorial.component;
032:
033: import java.awt.Color;
034: import java.awt.Font;
035: import java.awt.event.ActionEvent;
036:
037: import javax.swing.*;
038:
039: import com.jgoodies.animation.Animation;
040: import com.jgoodies.animation.AnimationAdapter;
041: import com.jgoodies.animation.AnimationEvent;
042: import com.jgoodies.animation.Animator;
043: import com.jgoodies.animation.animations.BasicTextAnimation;
044: import com.jgoodies.animation.components.BasicTextLabel;
045: import com.jgoodies.animation.tutorial.TutorialUtils;
046: import com.jgoodies.binding.adapter.BasicComponentFactory;
047: import com.jgoodies.binding.adapter.BoundedRangeAdapter;
048: import com.jgoodies.binding.beans.BeanAdapter;
049: import com.jgoodies.binding.beans.Model;
050: import com.jgoodies.binding.beans.PropertyAdapter;
051: import com.jgoodies.binding.value.ConverterFactory;
052: import com.jgoodies.binding.value.ValueModel;
053: import com.jgoodies.forms.builder.ButtonBarBuilder;
054: import com.jgoodies.forms.builder.PanelBuilder;
055: import com.jgoodies.forms.layout.CellConstraints;
056: import com.jgoodies.forms.layout.FormLayout;
057:
058: /**
059: * Demonstrates the features of the {@link BasicTextLabel}.
060: * Consists of a preview panel that displays a BasicTextLabel,
061: * and a tool panel for configuration the label's properties
062: * and for running default animations on that label.
063: *
064: * @author Karsten Lentzsch
065: * @version $Revision: 1.10 $
066: *
067: * @see com.jgoodies.animation.animations.BasicTextAnimation
068: * @see com.jgoodies.animation.animations.BasicTextAnimations
069: * @see com.jgoodies.animation.renderer.BasicTextRenderer
070: */
071: public final class BasicTextExample extends Model {
072:
073: private static final String PROPERTYNAME_DURATION = "duration";
074:
075: private static final String INITIAL_TEXT = "BasicTextLabel";
076:
077: private BasicTextLabel textLabel;
078:
079: private JComponent textField;
080: private JSlider alphaSlider;
081: private JSlider scaleSlider;
082: private JSlider spaceSlider;
083:
084: private int duration;
085: private JComponent durationField;
086: private Action fadeAction;
087: private Action scaleAction;
088: private Action spaceAction;
089:
090: // Self Starter ***********************************************************
091:
092: public static void main(String[] args) {
093: try {
094: UIManager
095: .setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
096: } catch (Exception e) {
097: // Likely PlasticXP is not in the class path; ignore.
098: }
099: JFrame frame = new JFrame();
100: frame.setTitle("Animation Tutorial :: Basic Text");
101: frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
102: JComponent panel = new BasicTextExample().buildPanel();
103: frame.getContentPane().add(panel);
104: frame.pack();
105: TutorialUtils.locateOnOpticalScreenCenter(frame);
106: frame.setVisible(true);
107: }
108:
109: // Instance Creation ******************************************************
110:
111: public BasicTextExample() {
112: duration = 4000;
113: initComponents();
114: }
115:
116: // Bound Properties *******************************************************
117:
118: public int getDuration() {
119: return duration;
120: }
121:
122: public void setDuration(int newDuration) {
123: int oldDuration = getDuration();
124: duration = newDuration;
125: firePropertyChange(PROPERTYNAME_DURATION, oldDuration,
126: newDuration);
127: }
128:
129: // Component Creation and Initialization **********************************
130:
131: /**
132: * Creates the text label, sliders and animation Actions.
133: * Binds sliders to bound properties of the text label.
134: */
135: private void initComponents() {
136: // Setup a BasicTextLabel with dark gray, bold Tahoma 24 pt.
137: textLabel = new BasicTextLabel(INITIAL_TEXT);
138: textLabel.setFont(new Font("Tahoma", Font.BOLD, 24));
139: textLabel.setColor(Color.DARK_GRAY);
140:
141: // Create a bean adapter that vends property adapters.
142: BeanAdapter beanAdapter = new BeanAdapter(textLabel, true);
143:
144: // Create a text field bound to the label's text.
145: textField = BasicComponentFactory
146: .createTextField(
147: beanAdapter
148: .getValueModel(BasicTextLabel.PROPERTYNAME_TEXT),
149: false);
150:
151: // Create a slider for the color alpha value.
152: alphaSlider = new JSlider();
153: ValueModel colorAdapter = beanAdapter
154: .getValueModel(BasicTextLabel.PROPERTYNAME_COLOR);
155: alphaSlider.setModel(new BoundedRangeAdapter(
156: new AlphaConverter(colorAdapter), 0, 0, 255));
157:
158: // Create a slider for the text label's scale in interval [0.5, 3].
159: scaleSlider = new JSlider();
160: ValueModel scaleAdapter = beanAdapter
161: .getValueModel(BasicTextLabel.PROPERTYNAME_SCALE);
162: scaleSlider.setModel(new BoundedRangeAdapter(ConverterFactory
163: .createFloatToIntegerConverter(scaleAdapter, 100), 0,
164: 50, 300));
165:
166: // Create a slider for the text glyph space in interval [-10, 20].
167: spaceSlider = new JSlider();
168: ValueModel spaceAdapter = beanAdapter
169: .getValueModel(BasicTextLabel.PROPERTYNAME_SPACE);
170: spaceSlider.setModel(new BoundedRangeAdapter(ConverterFactory
171: .createFloatToIntegerConverter(spaceAdapter, 100), 0,
172: -1000, 2000));
173:
174: // Create a text field bound to the duration.
175: durationField = BasicComponentFactory
176: .createIntegerField(new PropertyAdapter(this ,
177: PROPERTYNAME_DURATION));
178:
179: // Create Actions for three default animations
180: fadeAction = new FadeAction();
181: scaleAction = new ScaleAction();
182: spaceAction = new SpaceAction();
183: }
184:
185: // Building *************************************************************
186:
187: /**
188: * Builds and returns a panel with the preview in the top
189: * and the tool panel in the bottom.
190: *
191: * @return the built panel
192: */
193: private JComponent buildPanel() {
194: FormLayout layout = new FormLayout("fill:pref:grow",
195: "fill:pref:grow, p, p");
196:
197: PanelBuilder builder = new PanelBuilder(layout);
198: CellConstraints cc = new CellConstraints();
199: builder.add(buildPreviewPanel(), cc.xy(1, 1));
200: builder.addSeparator("", cc.xy(1, 2));
201: builder.add(buildToolsPanel(), cc.xy(1, 3));
202:
203: return builder.getPanel();
204: }
205:
206: public JComponent buildPreviewPanel() {
207: FormLayout layout = new FormLayout("fill:200dlu:grow",
208: "fill:100dlu:grow");
209: JPanel panel = new JPanel(layout);
210: panel.setBackground(Color.WHITE);
211: panel.add(textLabel, new CellConstraints());
212: return panel;
213: }
214:
215: public JComponent buildToolsPanel() {
216: FormLayout layout = new FormLayout("pref, 25dlu, pref",
217: "fill:pref");
218: //layout.setColumnGroups(new int[][]{{1, 3}});
219:
220: PanelBuilder builder = new PanelBuilder(layout);
221: builder.setDefaultDialogBorder();
222: CellConstraints cc = new CellConstraints();
223: builder.add(buildPropertiesPanel(), cc.xy(1, 1));
224: builder.add(buildAnimationsPanel(), cc.xy(3, 1));
225: return builder.getPanel();
226: }
227:
228: private JComponent buildPropertiesPanel() {
229: FormLayout layout = new FormLayout(
230: "right:pref, 3dlu, right:pref, 2dlu, 60dlu, 2dlu, right:pref",
231: "p, 6dlu, p, 6dlu, p, 6dlu, p, 6dlu, p");
232:
233: PanelBuilder builder = new PanelBuilder(layout);
234: CellConstraints cc = new CellConstraints();
235: builder.addSeparator("Properties", cc.xyw(1, 1, 7));
236: builder.addLabel("Text:", cc.xy(1, 3));
237: builder.add(textField, cc.xyw(3, 3, 5));
238:
239: addSlider(builder, 5, "Alpha:", alphaSlider, "0", "255");
240: addSlider(builder, 7, "Scale:", scaleSlider, "0.5", "3");
241: addSlider(builder, 9, "Space:", spaceSlider, "-10", "20");
242:
243: return builder.getPanel();
244: }
245:
246: private JComponent buildAnimationsPanel() {
247: FormLayout layout = new FormLayout(
248: "right:pref, 3dlu, 40dlu, 0:grow",
249: "p, 6dlu, p, 9dlu, p:grow");
250:
251: PanelBuilder builder = new PanelBuilder(layout);
252: CellConstraints cc = new CellConstraints();
253: builder.addSeparator("Animations", cc.xyw(1, 1, 4));
254: builder.addLabel("Duration:", cc.xy(1, 3));
255: builder.add(durationField, cc.xy(3, 3));
256: builder.add(buildButtonBar(), cc.xyw(1, 5, 4, "fill, bottom"));
257: return builder.getPanel();
258: }
259:
260: private JComponent buildButtonBar() {
261: ButtonBarBuilder builder = new ButtonBarBuilder();
262: builder.addGridded(new JButton(fadeAction));
263: builder.addRelatedGap();
264: builder.addGridded(new JButton(scaleAction));
265: builder.addRelatedGap();
266: builder.addGridded(new JButton(spaceAction));
267: return builder.getPanel();
268: }
269:
270: private void addSlider(PanelBuilder builder, int row, String title,
271: JSlider slider, String leftText, String rightText) {
272: CellConstraints cc = new CellConstraints();
273: builder.addLabel(title, cc.xy(1, row));
274: builder.addLabel(leftText, cc.xy(3, row));
275: builder.add(slider, cc.xy(5, row));
276: builder.addLabel(rightText, cc.xy(7, row));
277: }
278:
279: // Animation Actions ************************************************************
280:
281: private void setActionsEnabled(boolean enabled) {
282: fadeAction.setEnabled(enabled);
283: scaleAction.setEnabled(enabled);
284: spaceAction.setEnabled(enabled);
285: }
286:
287: private abstract class AnimationAction extends AbstractAction {
288:
289: private AnimationAction(String text) {
290: super (text);
291: }
292:
293: public void actionPerformed(ActionEvent e) {
294: Animation animation = createAnimation();
295: int fps = 30;
296: animation.addAnimationListener(new StartStopHandler());
297: new Animator(animation, fps).start();
298: }
299:
300: abstract Animation createAnimation();
301:
302: }
303:
304: private final class FadeAction extends AnimationAction {
305:
306: private FadeAction() {
307: super ("Fade");
308: }
309:
310: public Animation createAnimation() {
311: return BasicTextAnimation
312: .defaultFade(textLabel, getDuration(), textLabel
313: .getText(), Color.DARK_GRAY);
314: }
315:
316: }
317:
318: private final class ScaleAction extends AnimationAction {
319: private ScaleAction() {
320: super ("Scale");
321: }
322:
323: public Animation createAnimation() {
324: return BasicTextAnimation
325: .defaultScale(textLabel, getDuration(), textLabel
326: .getText(), Color.DARK_GRAY);
327: }
328:
329: }
330:
331: private final class SpaceAction extends AnimationAction {
332:
333: private SpaceAction() {
334: super ("Space");
335: }
336:
337: public Animation createAnimation() {
338: return BasicTextAnimation
339: .defaultSpace(textLabel, getDuration(), textLabel
340: .getText(), Color.DARK_GRAY);
341: }
342: }
343:
344: /**
345: * Disables the actions at animation start and enables them
346: * when the animation stopped. Also restores the text label's text.
347: */
348: private final class StartStopHandler extends AnimationAdapter {
349:
350: private String text;
351:
352: public void animationStarted(AnimationEvent e) {
353: setActionsEnabled(false);
354: text = textLabel.getText();
355: }
356:
357: public void animationStopped(AnimationEvent e) {
358: setActionsEnabled(true);
359: textLabel.setText(text);
360: }
361: }
362: }
|