diff options
Diffstat (limited to 'src/proguard/gui/splash/SplashPanel.java')
-rw-r--r-- | src/proguard/gui/splash/SplashPanel.java | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/proguard/gui/splash/SplashPanel.java b/src/proguard/gui/splash/SplashPanel.java new file mode 100644 index 0000000..23a9ce4 --- /dev/null +++ b/src/proguard/gui/splash/SplashPanel.java @@ -0,0 +1,235 @@ +/* + * ProGuard -- shrinking, optimization, obfuscation, and preverification + * of Java bytecode. + * + * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +package proguard.gui.splash; + +import proguard.gui.SwingUtil; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.lang.reflect.InvocationTargetException; + +/** + * This JPanel renders an animated Sprite. + * + * @author Eric Lafortune + */ +public class SplashPanel extends JPanel +{ + private final MyAnimator animator = new MyAnimator(); + private final MyRepainter repainter = new MyRepainter(); + + private final Sprite sprite; + private final double sleepFactor; + + private long startTime = Long.MAX_VALUE; + private final long stopTime; + + private volatile Thread animationThread; + + + /** + * Creates a new SplashPanel with the given Sprite, which will be animated + * indefinitely. + * @param sprite the Sprite that will be animated. + * @param processorLoad the fraction of processing time to be spend on + * animating the Sprite (between 0 and 1). + */ + public SplashPanel(Sprite sprite, double processorLoad) + { + this(sprite, processorLoad, (long)Integer.MAX_VALUE); + } + + + /** + * Creates a new SplashPanel with the given Sprite, which will be animated + * for a limited period of time. + * @param sprite the Sprite that will be animated. + * @param processorLoad the fraction of processing time to be spend on + * animating the Sprite (between 0 and 1). + * @param stopTime the number of milliseconds after which the + * animation will be stopped automatically. + */ + public SplashPanel(Sprite sprite, double processorLoad, long stopTime) + { + this.sprite = sprite; + this.sleepFactor = (1.0-processorLoad) / processorLoad; + this.stopTime = stopTime; + + // Restart the animation on a mouse click. + addMouseListener(new MouseAdapter() + { + public void mouseClicked(MouseEvent e) + { + SplashPanel.this.start(); + } + }); + } + + + /** + * Starts the animation. + */ + public void start() + { + // Go to the beginning of the animation. + startTime = System.currentTimeMillis(); + + // Make sure we have an animation thread running. + if (animationThread == null) + { + animationThread = new Thread(animator); + animationThread.start(); + } + } + + + /** + * Stops the animation. + */ + public void stop() + { + // Go to the end of the animation. + startTime = 0L; + + // Let the animation thread stop itself. + animationThread = null; + + // Repaint the SplashPanel one last time. + try + { + SwingUtil.invokeAndWait(repainter); + } + catch (InterruptedException ex) + { + // Nothing. + } + catch (InvocationTargetException ex) + { + // Nothing. + } + } + + + // Implementation for JPanel. + + public void paintComponent(Graphics graphics) + { + super.paintComponent(graphics); + + sprite.paint(graphics, System.currentTimeMillis() - startTime); + } + + + /** + * This Runnable makes sure its SplashPanel gets repainted regularly, + * depending on the targeted processor load. + */ + private class MyAnimator implements Runnable + { + public void run() + { + try + { + while (animationThread != null) + { + // Check if we should stop the animation. + long time = System.currentTimeMillis(); + if (time > startTime + stopTime) + { + animationThread = null; + } + + // Do a repaint and time it. + SwingUtil.invokeAndWait(repainter); + + // Sleep for a proportional while. + long repaintTime = System.currentTimeMillis() - time; + long sleepTime = (long)(sleepFactor * repaintTime); + if (sleepTime < 10L) + { + sleepTime = 10L; + } + + Thread.sleep(sleepTime); + } + } + catch (InterruptedException ex) + { + // Nothing. + } + catch (InvocationTargetException ex) + { + // Nothing. + } + } + } + + + /** + * This Runnable repaints its SplashPanel. + */ + private class MyRepainter implements Runnable + { + public void run() + { + SplashPanel.this.repaint(); + } + } + + + /** + * A main method for testing the splash panel. + */ + public static void main(String[] args) + { + JFrame frame = new JFrame(); + frame.setTitle("Animation"); + frame.setSize(800, 600); + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + Dimension frameSize = frame.getSize(); + frame.setLocation((screenSize.width - frameSize.width) / 2, + (screenSize.height - frameSize.height) / 2); + + Sprite sprite = + new ClipSprite( + new ConstantColor(Color.white), + new ConstantColor(Color.lightGray), + new CircleSprite(true, + new LinearInt(200, 600, new SineTiming(2345L, 0L)), + new LinearInt(200, 400, new SineTiming(3210L, 0L)), + new ConstantInt(150)), + new ColorSprite(new ConstantColor(Color.gray), + new FontSprite(new ConstantFont(new Font("sansserif", Font.BOLD, 90)), + new TextSprite(new ConstantString("ProGuard"), + new ConstantInt(200), + new ConstantInt(300))))); + + SplashPanel panel = new SplashPanel(sprite, 0.5); + panel.setBackground(Color.white); + + frame.getContentPane().add(panel); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setVisible(true); + + panel.start(); + } +} |