/* * Copyright 2004 - 2008 Christian Sprajc. All rights reserved. * * This file is part of PowerFolder. * * PowerFolder 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. * * PowerFolder 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 PowerFolder. If not, see <http://www.gnu.org/licenses/>. * * $Id$ */ package de.dal33t.powerfolder.ui.notification; import java.awt.Dimension; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JComponent; import javax.swing.JWindow; import javax.swing.Timer; import de.dal33t.powerfolder.Constants; import de.dal33t.powerfolder.ui.util.UIUtil; /** * Creates an animated view that slides out of the bottom-right corner of the * screen. The user of this class supplies the contents for sliding. Also, the * view automatically closes itself after predetermined amount of time, which is * currently set to 10 seconds.<br> * This class is based on code and ideas from <i>Swing Hacks</i> book by Joshua * Marinacci and Chris Adamson.<br> * If the Java version is high enough, it fades the window instead of sliding * it. * * @author <a href="mailto:magapov@gmail.com">Maxim Agapov</a> * @version $Revision: 1.2 $ */ public class Slider { /** * Default delay between animation frames, 5ms */ public static final int ANIMATION_DELAY = 5; private int displaySeconds; private Window owner; private JWindow window; private JComponent contents; private Timer animateUpTimer; private Timer dismissTimer; private Timer animateDownTimer; private int translucencyPercentage; private boolean displayLeft; /** * Constructor * * @param contents * @param displaySeconds * @param translucencyPercentage * @param displayLeft */ public Slider(JComponent contents, int displaySeconds, int translucencyPercentage, boolean displayLeft) { this(contents, null, displaySeconds, translucencyPercentage, displayLeft); } /** * Constructor * * @param contents * @param displaySeconds * @param translucencyPercentage * @param displayLeft */ public Slider(JComponent contents, Window owner, int displaySeconds, int translucencyPercentage, boolean displayLeft) { this.contents = contents; this.displaySeconds = displaySeconds; this.translucencyPercentage = translucencyPercentage; this.displayLeft = displayLeft; this.owner = owner; } public JComponent getContents() { return contents; } /* * Query graphics environment for maximum window bounds. */ private static Rectangle initDesktopBounds() { return GraphicsEnvironment.getLocalGraphicsEnvironment() .getMaximumWindowBounds(); } /** * Create a window with an animating sheet copy over its contents from the * temp window animate it when done, remove animating sheet and add real * contents. */ public void show() { if (window != null) { return; } window = new JWindow(owner); window.setAlwaysOnTop(true); if (Constants.OPACITY_SUPPORTED) { UIUtil.applyTranslucency(window, 0.0f); } // Initial boundaries. Dimension contentsSize = contents.getPreferredSize(); Rectangle desktopBounds = initDesktopBounds(); int showX = displayLeft ? 10 : desktopBounds.width - contentsSize.width - 10; int startY = desktopBounds.y + desktopBounds.height - 10; window.getContentPane().add(contents); window.pack(); window.setLocation(showX, startY - window.getHeight()); window.setVisible(true); // Timer to animate the sheet down. animateDownTimer = new Timer(ANIMATION_DELAY, new ActionListener() { private int percentage = 99; public void actionPerformed(ActionEvent e) { animate(percentage); if (percentage-- <= 0) { animateDownTimer.stop(); } } }); // Timer to pause for the user to read. dismissTimer = new Timer(1000 * displaySeconds, new ActionListener() { public void actionPerformed(ActionEvent e) { animateDownTimer.start(); } }); dismissTimer.setRepeats(false); // Timer to animate the sheet up. animateUpTimer = new Timer(ANIMATION_DELAY, new ActionListener() { private int percentage = 1; public void actionPerformed(ActionEvent e) { animate(percentage); if (percentage++ >= 100) { animateUpTimer.stop(); dismissTimer.start(); } } }); animateUpTimer.start(); } /** * Close and dispose the animated window. */ public void close() { // stop the timers if (animateUpTimer != null && animateUpTimer.isRunning()) { animateUpTimer.stop(); } if (animateDownTimer != null && animateDownTimer.isRunning()) { animateDownTimer.stop(); } if (dismissTimer != null && dismissTimer.isRunning()) { dismissTimer.stop(); } // close the window if (window != null) { window.dispose(); window = null; } } /** * Show the correct percentage of the size. * * @param percentage */ public void animate(long percentage) { if (window == null) { // Huh? return; } if (Constants.OPACITY_SUPPORTED) { // Opacity = 1 - translucency. float opacity = 1.0f - translucencyPercentage / 100.0f; UIUtil.applyTranslucency(window, opacity * percentage / 100.0f); } if (percentage <= 0) { close(); } } }