/** * Copyright (c) 2009 - 2010 AppWork UG(haftungsbeschränkt) <e-mail@appwork.org> * * This file is part of org.appwork.utils.swing * * This software is licensed under the Artistic License 2.0, * see the LICENSE file or http://www.opensource.org/licenses/artistic-license-2.0.php * for details */ package org.appwork.utils.swing; import java.awt.AWTException; import java.awt.AlphaComposite; import java.awt.Composite; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Point; import java.awt.Rectangle; import java.awt.Robot; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import java.awt.image.BufferedImage; import java.awt.image.ConvolveOp; import java.awt.image.Kernel; import java.util.HashMap; import java.util.logging.Level; import javax.swing.BorderFactory; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JTextArea; import javax.swing.JWindow; import javax.swing.Timer; import net.miginfocom.swing.MigLayout; import org.appwork.resources.AWUTheme; import org.appwork.utils.ImageProvider.ImageProvider; import org.appwork.utils.logging.Log; /** * @author Unknown * */ public class LockPanel extends JPanel { /** * */ private static final long serialVersionUID = -2262534550090971819L; private final JFrame frame; private final Robot robot; private BufferedImage screen; private BufferedImage gray; private Timer fadeTimer; private int fadeCounter; private double steps; private final JWindow waitingPanel; private JTextArea text; // if there are different lockpanels for the same frame, the fade animations // may lock private static final HashMap<JFrame, LockPanel> CACHE = new HashMap<JFrame, LockPanel>(); /** * @param parentOwner * @throws AWTException */ public synchronized static LockPanel create(final JFrame parentOwner) throws AWTException { LockPanel ret = LockPanel.CACHE.get(parentOwner); if (ret == null) { ret = new LockPanel(parentOwner); LockPanel.CACHE.put(parentOwner, ret); } return ret; } private float alpha = 0.1f; /** * @param frame * @throws AWTException */ private LockPanel(final JFrame frame) throws AWTException { this.frame = frame; this.robot = new Robot(); this.waitingPanel = new JWindow(); frame.addWindowListener(new WindowListener() { public void windowActivated(final WindowEvent e) { if (LockPanel.this.waitingPanel.isVisible()) { LockPanel.this.waitingPanel.toFront(); } } public void windowClosed(final WindowEvent e) { } public void windowClosing(final WindowEvent e) { } public void windowDeactivated(final WindowEvent e) { } public void windowDeiconified(final WindowEvent e) { } public void windowIconified(final WindowEvent e) { } public void windowOpened(final WindowEvent e) { } }); final JPanel p; this.waitingPanel.setContentPane(p = new JPanel()); p.setLayout(new MigLayout("ins 10", "[][fill,grow]", "[fill,grow]")); p.add(new JLabel(AWUTheme.I().getIcon("wait", 32))); p.add(this.text = new JTextArea(), "spanx,aligny center"); p.setBorder(BorderFactory.createLineBorder(p.getBackground().darker().darker())); JProgressBar bar; p.add(bar = new JProgressBar(), "growx,pushx,spanx,newline"); bar.setIndeterminate(true); this.text.setBorder(null); this.text.setBackground(null); this.addMouseListener(new MouseAdapter() { }); } /** * @return */ private BufferedImage createScreenShot() { this.frame.toFront(); final boolean top = this.frame.isAlwaysOnTop(); try { return new EDTHelper<BufferedImage>() { @Override public BufferedImage edtRun() { try { if (LockPanel.this.frame.isShowing()) { LockPanel.this.frame.setAlwaysOnTop(true); final Rectangle captureSize = new Rectangle(LockPanel.this.frame.getContentPane().getSize()); final Point loc = LockPanel.this.frame.getContentPane().getLocationOnScreen(); captureSize.x = loc.x; captureSize.y = loc.y; return LockPanel.this.robot.createScreenCapture(captureSize); } else { return null; } } catch (final Throwable e) { /* * to catch component must be showing on the screen to * determine its location */ Log.exception(Level.WARNING, e); return null; } } }.getReturnValue(); } finally { this.frame.setAlwaysOnTop(top); } } public synchronized void fadeIn(final int time) { this.fadeCounter++; this.steps = 50 * 1.0 / time; if (this.fadeTimer != null) { this.fadeTimer.stop(); this.fadeTimer = null; } this.fadeTimer = new Timer(50, new ActionListener() { public void actionPerformed(final ActionEvent e) { final Timer timer = LockPanel.this.fadeTimer; LockPanel.this.alpha += LockPanel.this.steps; if (LockPanel.this.alpha >= 1.0) { LockPanel.this.alpha = 1.0f; if (timer != null) { LockPanel.this.fadeTimer.stop(); } } LockPanel.this.repaint(); } }); this.fadeTimer.setRepeats(true); this.fadeTimer.setInitialDelay(0); this.fadeTimer.start(); } public synchronized void fadeOut(final int time) { this.screen = this.createScreenShot(); this.fadeCounter--; this.steps = 50 * 1.0 / time; if (this.fadeCounter > 0) { return; } if (this.fadeTimer != null) { this.fadeTimer.stop(); this.fadeTimer = null; } this.fadeTimer = new Timer(50, new ActionListener() { public void actionPerformed(final ActionEvent e) { final Timer timer = LockPanel.this.fadeTimer; LockPanel.this.alpha -= LockPanel.this.steps; System.out.println(LockPanel.this.alpha); if (LockPanel.this.alpha <= 0.0) { LockPanel.this.alpha = 0.0f; if (timer != null) { timer.stop(); } LockPanel.this.setWaitingPanelText(null); LockPanel.this.frame.getGlassPane().setVisible(false); } LockPanel.this.repaint(); } }); this.fadeTimer.setRepeats(true); this.fadeTimer.setInitialDelay(0); this.fadeTimer.start(); } /** * @return the text */ public JTextArea getText() { return this.text; } /** * @param time */ public void lock(final int time) { this.frame.getGlassPane().setVisible(false); this.screen = this.createScreenShot(); this.frame.getGlassPane().setVisible(true); if (this.screen != null) { this.gray = ImageProvider.convertToGrayScale(this.screen); final float data[] = { 0.0625f, 0.125f, 0.0625f, 0.125f, 0.25f, 0.125f, 0.0625f, 0.125f, 0.0625f }; final Kernel kernel = new Kernel(3, 3, data); final ConvolveOp convolve = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null); final BufferedImage dest = new BufferedImage(this.gray.getWidth(), this.gray.getHeight(), BufferedImage.TYPE_BYTE_GRAY); this.gray = convolve.filter(this.gray, dest); this.frame.setGlassPane(this); this.frame.getGlassPane().setVisible(true); this.fadeIn(time); } } @Override protected void paintComponent(final Graphics g) { final Composite comp = ((Graphics2D) g).getComposite(); ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); g.drawImage(this.screen, 0, 0, null); ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, this.alpha)); g.drawImage(this.gray, 0, 0, null); ((Graphics2D) g).setComposite(comp); } public void setWaitingPanelText(final String wait) { if (wait == null) { this.waitingPanel.setVisible(false); } else { this.text.setText(wait); this.waitingPanel.pack(); this.waitingPanel.setLocation(SwingUtils.getCenter(this.frame, this.waitingPanel)); this.waitingPanel.setVisible(true); } } /** * @param i */ public void unlock(final int i) { this.fadeOut(i); } }