Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: novaworx/swing/XPopup.java


1   /*
2   Novaworx Development Environment
3   Copyright (C) 2000-2003 Mark Soderquist
4   
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9   
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU General Public License for more details.
14  
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to:
17  
18  Free Software Foundation, Inc.
19  59 Temple Place, Suite 330
20  Boston, MA 02111-1307 USA
21  */
22  
23  package novaworx.swing;
24  
25  import java.awt.*;
26  import java.awt.event.*;
27  import java.awt.image.*;
28  import java.util.*;
29  import javax.swing.*;
30  import javax.swing.event.*;
31  import novaworx.swing.event.*;
32  
33  /**
34  The <code>XPopup</code> class allows backgrounds to be drawn
35  for non-opaque components that are transparent or semi-transparent.
36  Popup components are intended to be displayed over the top of other
37  components in the popup layer of a <code>JLayeredPane</code>.
38  */
39  public class XPopup extends JComponent {
40  
41    private static transient XPopup moPopup;
42  
43    private static transient PopupHider moHider;
44  
45    private transient Vector mvListeners;
46  
47    private transient JLayeredPane moLayeredPane;
48  
49    private transient Image moBackgroundImage;
50  
51    static {
52      moHider = new PopupHider();
53    }
54  
55    /**
56    Construct an <code>XPopup</code>.
57    */
58    public XPopup() {
59      super();
60  
61      mvListeners = new Vector();
62  
63      setOpaque( false );
64      setBackground( new Color( 0, 0, 0, 0 ) );
65    }
66  
67    /**
68    Lays out the container so that it uses the minimum space
69    needed to display its contents.
70    */
71    public void pack() {
72      //
73    }
74  
75    /**
76    Show the popup at the specified location relative to the specified
77    component.
78    */
79    public void show( JComponent aoComponent, int aiX, int aiY ) {
80      moPopup = this;
81      Dimension oSize = getSize();
82      XWallpaper oWallpaper = getWallpaper( aoComponent );
83  
84      if( oWallpaper == null ) {
85        // Set the background color opaque.
86        //setBackground( new XColor( getBackground(), 255 ) );
87      } else {
88        // Use the wallpaper to paint the background.
89        Point oLocation = SwingUtilities.convertPoint( aoComponent, aiX, aiY, oWallpaper );
90        moBackgroundImage = oWallpaper.getSubimage( oLocation.x, oLocation.y, oSize.width, oSize.height );
91        //setOpaque( true );
92      }
93  
94      // Get the layered pane to add the popup to.
95      moLayeredPane = aoComponent.getRootPane().getLayeredPane();
96  
97      // Adjust the point of origin.
98      if( aoComponent != null ) {
99        Point oOrigin = new Point( aiX, aiY );
100       Point oLocation = SwingUtilities.convertPoint( aoComponent, oOrigin, moLayeredPane );
101       setLocation( oLocation );
102     } else {
103       setLocation( aiX, aiY );
104     }
105 
106     // Grab the containers.
107     moHider.grab( aoComponent );
108 
109     moLayeredPane.add( this, JLayeredPane.POPUP_LAYER );
110 
111     // Show the popup.
112     setVisible( true );
113   }
114 
115   /**
116   Show the popup at the specified location relative to the specified
117   component.
118   */
119   /*
120   public void show( JComponent aoComponent, int aiX, int aiY, XWallpaper aoWallpaper ) {
121     setOpaque( true );
122     Dimension oSize = getSize();
123 
124     // Create an image the size of the popup.
125     moBackgroundImage = aoWallpaper.getSubimage( oLocation.x, oLocation.y, oSize.width, oSize.height );
126 
127     show( aoComponent, aiX, aiY );
128   }
129   */
130 
131   /**
132   Hide the popup.
133   */
134   public void cancel() {
135     setVisible( false );
136     moLayeredPane.remove( this );
137     moHider.ungrab();
138     moPopup = null;
139   }
140 
141   /**
142   Only need to override the paint method.
143   */
144   public void paint( Graphics aoGraphics ) {
145     // Draw the background.
146     if( moBackgroundImage == null ) {
147       aoGraphics.setColor( getBackground() );
148       aoGraphics.fillRect( 0, 0, getWidth(), getHeight() );
149     } else {
150       aoGraphics.drawImage( moBackgroundImage, 0, 0, this );
151       aoGraphics.setColor( getBackground() );
152       aoGraphics.fillRect( 0, 0, getWidth(), getHeight() );
153     }
154 
155     super.paint( aoGraphics );
156   }
157 
158   /**
159   Go up the component hierarchy and find an <code>XWallpaper</code>component.
160   */
161   private static XWallpaper getWallpaper( Component aoParent ) {
162     while( aoParent != null && !( aoParent instanceof XWallpaper ) ) aoParent = aoParent.getParent();
163     return (XWallpaper)aoParent;
164   }
165 
166   /**
167   Add a <code>PopupListener</code>.
168   */
169   public void addPopupListener( PopupListener aoListener ) {
170     mvListeners.add( aoListener );
171   }
172 
173   /**
174   Remove a <code>PopupListener</code>.
175   */
176   public void removePopupListener( PopupListener aoListener ) {
177     mvListeners.remove( aoListener );
178   }
179 
180   /**
181   Fire a selection made event.
182   */
183   protected void fireSelectionMade( Object aoSelection ) {
184     PopupEvent oEvent = new PopupEvent( this, aoSelection );
185     int iCount = mvListeners.size();
186     for( int iIndex = 0; iIndex < iCount; iIndex++ ) {
187       ((PopupListener)mvListeners.get( iIndex )).selectionMade( oEvent );
188     }
189   }
190 
191   /**
192   Handles events to hide the popup.
193   */
194   private static class PopupHider implements MouseListener, MouseMotionListener, MouseWheelListener, WindowListener, ComponentListener {
195 
196     Vector mvGrabbed = new Vector();
197 
198     public PopupHider() {}
199 
200     void grab( Component aoCompnent ) {
201       grabContainer( getWindow( aoCompnent ), moPopup );
202     }
203 
204     void ungrab() {
205       ungrabContainers();
206     }
207 
208     void cancelPopup() {
209       if( moPopup != null ) moPopup.cancel();
210     }
211 
212     void grabContainer( Container aoContainer, Component aoExcluded ) {
213       if( aoContainer == aoExcluded ) return;
214 
215       if( aoContainer instanceof Window ) {
216         ((Window)aoContainer).addWindowListener( this );
217         ((Window)aoContainer).addComponentListener( this );
218         mvGrabbed.addElement( aoContainer );
219       }
220 
221       synchronized( aoContainer.getTreeLock() ) {
222         int iComponentCount = aoContainer.getComponentCount();
223         Component[] aComponents = aoContainer.getComponents();
224         for( int iIndex = 0; iIndex < iComponentCount; iIndex++ ) {
225           Component oComponent = aComponents[ iIndex ];
226           if( !oComponent.isVisible() ) continue;
227           oComponent.addMouseListener( this );
228           oComponent.addMouseMotionListener( this );
229           oComponent.addMouseWheelListener( this );
230           mvGrabbed.addElement( oComponent );
231 
232           if( oComponent instanceof Container ) {
233             Container oContainer = (Container)oComponent;
234             grabContainer( oContainer, aoExcluded );
235           }
236         }
237       }
238     }
239 
240     void ungrabContainers() {
241       Component oComponent;
242 
243       int iCount = mvGrabbed.size();
244       for( int iIndex = 0; iIndex < iCount; iIndex++ ) {
245         oComponent = (Component)mvGrabbed.elementAt( 0 );
246         if( oComponent instanceof Window ) {
247           ((Window)oComponent).removeWindowListener( this );
248           ((Window)oComponent).removeComponentListener( this );
249         } else {
250           oComponent.removeMouseListener( this );
251           oComponent.removeMouseMotionListener( this );
252           oComponent.removeMouseWheelListener( this );
253         }
254       }
255       mvGrabbed = new Vector();
256     }
257 
258     private static Window getWindow( Component aoComponent ) {
259       Component oWindow = aoComponent;
260 
261       while( !( oWindow instanceof Window ) && ( oWindow != null ) ) {
262         oWindow = oWindow.getParent();
263       }
264 
265       return (Window)oWindow;
266     }
267 
268     public void mousePressed(MouseEvent e) {
269       cancelPopup();
270     }
271 
272     public void mouseReleased(MouseEvent e) {}
273 
274     public void mouseEntered(MouseEvent e) {}
275 
276     public void mouseExited(MouseEvent e) {}
277 
278     public void mouseMoved(MouseEvent e) {}
279 
280     public void mouseDragged(MouseEvent e) {}
281 
282     public void mouseClicked(MouseEvent e) {}
283 
284     public void mouseWheelMoved(MouseWheelEvent e) {
285       cancelPopup();
286     }
287 
288     public void componentResized(ComponentEvent e) {
289       cancelPopup();
290     }
291 
292     public void componentMoved(ComponentEvent e) {
293       cancelPopup();
294     }
295 
296     public void componentShown(ComponentEvent e) {
297       cancelPopup();
298     }
299 
300     public void componentHidden(ComponentEvent e) {
301       cancelPopup();
302     }
303 
304     public void windowOpened(WindowEvent e) {}
305 
306     public void windowClosing(WindowEvent e) {
307       cancelPopup();
308     }
309 
310     public void windowClosed(WindowEvent e) {
311       cancelPopup();
312     }
313 
314     public void windowIconified(WindowEvent e) {
315       cancelPopup();
316     }
317 
318     public void windowDeiconified(WindowEvent e) {}
319 
320     public void windowActivated(WindowEvent e) {}
321 
322     public void windowDeactivated(WindowEvent e) {}
323   }
324 
325 }