1 /*
2  * aTunes
3  * Copyright (C) Alex Aranda, Sylvain Gaudard and contributors
4  *
5  * See http://www.atunes.org/wiki/index.php?title=Contributing for information about contributors
6  *
7  * http://www.atunes.org
8  * http://sourceforge.net/projects/atunes
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  */
20 
21 package net.sourceforge.atunes.gui;
22 
23 import java.awt.BorderLayout;
24 import java.awt.Component;
25 import java.awt.Dialog;
26 
27 import javax.swing.JComponent;
28 import javax.swing.JWindow;
29 import javax.swing.Popup;
30 import javax.swing.border.Border;
31 
32 import net.sourceforge.atunes.model.ILookAndFeel;
33 
34 /**
35  * Based on a fading popup with shadow border by Kirill Grouchnikov.
36  */
37 final class FadingPopup extends Popup {
38 
39 	private final JWindow popupWindow;
40 	private final WindowFader windowFader;
41 
42 	/**
43 	 * Instantiates a new fading popup.
44 	 *
45 	 * @param contents
46 	 * @param ownerX
47 	 * @param ownerY
48 	 * @param shadowBorder
49 	 * @param lookAndFeel
50 	 */
FadingPopup(final Component contents, final int ownerX, final int ownerY, final boolean shadowBorder, final ILookAndFeel lookAndFeel)51 	FadingPopup(final Component contents, final int ownerX, final int ownerY,
52 			final boolean shadowBorder, final ILookAndFeel lookAndFeel) {
53 		// create a new heavyweighht window
54 		this.popupWindow = new JWindow();
55 
56 		// Solution for the problem
57 		// "java.lang.IllegalStateException: Trying to unblock window blocked by another dialog"
58 		// in Linux
59 		this.popupWindow
60 				.setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE);
61 
62 		// determine the popup location
63 		this.popupWindow.setLocation(ownerX, ownerY);
64 		// add the contents to the popup
65 		this.popupWindow.getContentPane().add(contents, BorderLayout.CENTER);
66 		contents.invalidate();
67 		JComponent parent = (JComponent) contents.getParent();
68 		// set the shadow border
69 		if (shadowBorder) {
70 			Border shadow = lookAndFeel.getShadowBorder();
71 			if (shadow != null) {
72 				parent.setBorder(shadow);
73 			}
74 		}
75 		this.windowFader = new WindowFader(this.popupWindow, 40) {
76 			@Override
77 			protected void fadeOutFinished() {
78 				FadingPopup.this.popupWindow.removeAll();
79 				super.fadeOutFinished();
80 			}
81 		};
82 	}
83 
84 	@Override
show()85 	public void show() {
86 		// mark the popup with 0% opacity
87 		GuiUtils.setWindowOpacity(this.popupWindow, 0.0f);
88 
89 		this.popupWindow.setVisible(true);
90 		this.popupWindow.pack();
91 
92 		// mark the window as non-opaque, so that the
93 		// shadow border pixels take on the per-pixel
94 		// translucency
95 		GuiUtils.setWindowOpaque(this.popupWindow, false);
96 
97 		// start fading in
98 		this.windowFader.fadeIn();
99 	}
100 
101 	@Override
hide()102 	public void hide() {
103 		// start fading out
104 		this.windowFader.fadeOut();
105 	}
106 }
107