📄 fadecomponent.java
字号:
/* * FadeComponent.java * * Created on December 21, 2004, 3:21 PM */package hysun.util;import java.awt.AlphaComposite;import java.awt.Graphics;import java.awt.Graphics2D;import javax.swing.JComponent;/** * <pre> * <b>Fields:</b> * // usage explained in demo 4 * protected boolean animating; * * // usage explained in demo 4 * protected Thread animator; * * <b>Constructors:</b> * // default constructor * public FadeComponent(); * * // constructor with all parameters specified. * // Explanation of each parameter explained in "Bean method" part * public FadeComponent(String pattern, int loops, int steps, int precision); * * <b>Bean Methods:</b> (NOTE: mainly for integration into IDE for fast development purpose.) * // elements of pattern are character 'i' or 'o' or a positive integer. * // each pattern string has at least one element. multiple elements are separated by '_'. * // 'i'/'o' means fade in/out respectively; int specifies a delay time in milliseconds. * // e.g. "i_500_o_500" means fade in first, followed by a delay of 500ms, * // then fade out, and followed by another delay of 500 ms. * // chars other than 'i' and 'o', or negative or 0 delay, or missing '_' will cause * // IllegalArgumentException be thrown from the set method. * // default value is "i", i.e. fade in * set/getPattern(String pattern); * * // number of times to repeat the above pattern. * // 0 or negative value means loop forever. * // default value is 1, i.e. loop once. * set/getLoops(int loops); * * // number of steps to go from 100% transparent to 0% transparent (fade in) or * // 0% transparent to 100% transparent (fade out). * // each step will change the transparent value by 100%/step percent. * // default value is 100. * set/getSteps(int steps); * * // number of milliseconds between two consecutive steps. * // default value is 50 (ms) * // NOTE: total time take to complete a "fade in" or a "fade out" = step * precision (ms) * set/getPrecision(int precision); * * <b>Animation Control Methods:</b> * // start animation as specified by the parameters. * // synchronized is used to make sure only one control thread is running at any time. * // if animation is already running (not yet terminated), call to this method simply returns. * public synchronized void startAnimation(); * * // checks whether animation is running * public boolean isAnimating()? * * <b>Methods that shouldn't be overriden by subclasses:</b> * // this is implementation of the "run" method of the Runnable interface. * // animation are controlled by this method. * public void run(); * * // overrides the paintComponent method of JComponent. alpha value is set by this method * // to realize fadeing effect. * protected void paintComponent(java.awt.Graphics g); * * <b>Replacement for paintComponent method:</b> * // subclasses that want to customize their graphics should override this method. * // this is analogy to normal subclasses of JComponent overrides the paintComponent method. * // implementation of this method is empty. * protected void paintContext(java.awt.Graphics2D g); * </pre> * * @author hysun */public class FadeComponent extends JComponent implements Runnable { /** -1 for fade in, 0 for fade out, +ve number for delay */ private int[] ptnArray = {-1}; //default to "i" private int loops = 1; //default to 1 private int steps = 100; //default to 100 private int precision = 50; //default to 50 private float alpha = 0.0f; // allow subclass to access. mainly to support "suspend/resume/stop animation" protected boolean animating = false; protected Thread animator; /** Default Constructor */ public FadeComponent() { super(); } /** Constructor with all attributes specified */ public FadeComponent(String pattern, int loops, int steps, int precision) { super(); setPattern(pattern); setLoops(loops); setSteps(steps); setPrecision(precision); } public void setPattern(String pattern) { if (pattern == null || pattern.equals("")) { throw new IllegalArgumentException("pattern must be an non-empty string."); } String[] frags = pattern.split("_"); int[] tmpArray = new int[frags.length]; for (int i=0; i<frags.length; i++) { try { tmpArray[i] = Integer.parseInt(frags[i]); if (tmpArray[i] <= 0) throw new IllegalArgumentException("syntax error in pattern string"); } catch (NumberFormatException nfe) { if (frags[i].length() != 1) throw new IllegalArgumentException("syntax error in pattern string"); char c = frags[i].charAt(0); if (c == 'i') tmpArray[i] = -1; else if (c == 'o') tmpArray[i] = 0; else throw new IllegalArgumentException("syntax error in pattern string"); } // end try } // end for ptnArray = new int[frags.length]; for (int i=0; i<frags.length; i++) ptnArray[i] = tmpArray[i]; } public String getPattern() { StringBuffer ptn = new StringBuffer(8); for (int i=0; i<ptnArray.length; i++) { if (ptnArray[i] == -1) ptn.append('i'); else if (ptnArray[i] == 0) ptn.append('o'); else ptn.append(ptnArray[i]); if (i != ptnArray.length - 1) ptn.append('_'); } return ptn.toString(); } public void setLoops(int loops) { this.loops = loops; } public int getLoops() { return loops; } public void setSteps(int steps) { if (steps <= 0) { throw new IllegalArgumentException("steps must be a positive number."); } this.steps = steps; } public int getSteps() { return steps; } public void setPrecision(int precision) { if (precision <= 0) { throw new IllegalArgumentException("precision must be a positive number."); } this.precision = precision; } public int getPrecision() { return precision; } /** * Call this method to start animation. * If there is already an animation thread running, the method simply * returns to the caller. * <code>synchronized</code> keyword is used to ensure mutual exclusive * access to the <code>animating</code> variable. */ public synchronized void startAnimation() { if (animating) { return; } animator = new Thread(this); animating = true; animator.start(); } /** Get animation status */ public boolean isAnimating() { return animating; } /** The control of the animation goes here. Subclasses, do NOT override. */ public void run() { try { int cnt = 0; while (loops <= 0 || cnt++ < loops) { for (int i=0; i<ptnArray.length; i++) { if (ptnArray[i] == -1) { fadein(); } else if (ptnArray[i] == 0) { fadeout(); } else { Thread.sleep(ptnArray[i]); } // end if } // end for } // end while } catch (InterruptedException ie) { System.err.println("FadeComponent: Sorry, not my fault. " + "Somebody else interrupted me."); } // Animation ends here. reset animating to false animating = false; } private void fadein() throws InterruptedException { for (int i=1; i<=steps; i++) { alpha = ((float) i) / steps; Thread.sleep(precision); repaint(); } } private void fadeout() throws InterruptedException { for (int i=steps-1; i>=0; i--) { alpha = ((float) i) / steps; Thread.sleep(precision); repaint(); } } /** * Override <code>paintComponent</code> method of <code>JComponent</code> * to paint with transparency settings. Subclasses, do NOT override. */ protected void paintComponent(Graphics g) { Graphics2D g2d = (Graphics2D) g; AlphaComposite comp = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha); g2d.setComposite(comp); paintContext(g2d); } /** * Empty implementation. * Subclasses, override to customize the graphics of the component. */ protected void paintContext(Graphics2D g) { } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -