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