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

Quick Search    Search Deep

Source code: com/imagero/gui/flowin/FloatingWindowManager.java


1   /*
2    * Copyright (c) imagero Andrey Kuznetsov. All Rights Reserved.
3    * http://jgui.imagero.com
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, or (at your option)
8    * 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 the Free Software
17   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18   */
19  
20  package com.imagero.gui.flowin;
21  
22  import com.imagero.gui.swing.SCheckBoxMenuItem;
23  import com.imagero.gui.swing.SelectableAction;
24  
25  import javax.swing.*;
26  import java.awt.event.ActionEvent;
27  import java.awt.event.ActionListener;
28  import java.awt.*;
29  import java.beans.PropertyChangeEvent;
30  import java.beans.PropertyChangeListener;
31  import java.util.ArrayList;
32  import java.util.Hashtable;
33  
34  /**
35   * <pre>
36   * FloatinWindowManager creates and keeps up to date menu
37   * (for JMenuBar) and popup menu (for FloatingWindow's title bar)
38   * and helps also to manage properties of FloatingWindow.
39   * </pre>
40   *
41   * @author Andrei Kouznetsov
42   * Date: 17.08.2004
43   * Time: 08:38:10
44   */
45  public class FloatingWindowManager {
46  
47      ArrayList windows = new ArrayList();
48      JPopupMenu popup;
49      JMenu menu;
50  
51      JCheckBoxMenuItem magnetic;
52      JCheckBoxMenuItem followsOwner;
53      JCheckBoxMenuItem staysOnScreen;
54      final JSeparator separator = new JSeparator();
55  
56      boolean showMagnetic = true;
57      boolean showFollowOwner = true;
58      boolean showRestrictToScreen = true;
59  
60      Hashtable popupItems = new Hashtable();
61  
62      FloatingWindow active, drag;
63  
64      PropertyChangeListener focusListener;
65      Timer t;
66  
67  
68      /**
69       * create FloatingWindowManager
70       */
71      public FloatingWindowManager() {
72          this(null);
73      }
74  
75      /**
76       * create FloatingWindowManager
77       * @param label menu label
78       * @see #getMenu
79       */
80      public FloatingWindowManager(String label) {
81          popup = new JPopupMenu(label);
82          magnetic = new JCheckBoxMenuItem("magnetic");
83          followsOwner = new JCheckBoxMenuItem("follow owner frame");
84          staysOnScreen = new JCheckBoxMenuItem("stay on screen");
85  
86          popup.add(magnetic);
87          popup.add(followsOwner);
88          popup.add(staysOnScreen);
89          popup.add(separator);
90  
91          menu = new JMenu(label);
92  
93          magnetic.addActionListener(new ActionListener() {
94              public void actionPerformed(ActionEvent e) {
95                  setMagneticImpl();
96              }
97          });
98          followsOwner.addActionListener(new ActionListener() {
99              public void actionPerformed(ActionEvent e) {
100                 setFollowImpl();
101             }
102         });
103         staysOnScreen.addActionListener(new ActionListener() {
104             public void actionPerformed(ActionEvent e) {
105                 setRectrictedImpl();
106             }
107         });
108 
109         t = new Timer(50, new ActionListener() {
110             public void actionPerformed(ActionEvent e) {
111                 if (drag != null) {
112                     setActiveWindow(drag);
113                     return;
114                 }
115 
116                 KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
117                 Component component = kfm.getFocusOwner();
118                 if (lastDrag != null) {
119                     setActiveWindow(lastDrag);
120                     lastDrag = null;
121                 }
122                 else {
123                     if (component != null) {
124                         Container parent = component.getParent();
125                         while (parent != null) {
126                             if (parent instanceof ContentPane) {
127                                 ContentPane contentPane = (ContentPane) parent;
128                                 contentPane.getContainer().firePropertyChange(ContentPane.GOT_FOCUS, false, true);
129                                 contentPane.setLastFocusOwner(component);
130                                 break;
131                             }
132                             parent = parent.getParent();
133                         }
134                         if (parent == null) {
135                             if (active != null) {
136                                 setActiveWindow(null);
137                             }
138                         }
139                     }
140                 }
141             }
142         });
143         t.setRepeats(false);
144 
145         focusListener = new PropertyChangeListener() {
146             public void propertyChange(PropertyChangeEvent e) {
147                 t.restart();
148             }
149         };
150         KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
151         kfm.addPropertyChangeListener(focusListener);
152 
153         UIManager.addPropertyChangeListener(new PropertyChangeListener() {
154             public void propertyChange(PropertyChangeEvent evt) {
155                 SwingUtilities.updateComponentTreeUI(popup);
156             }
157         });
158     }
159 
160     private void setRectrictedImpl() {
161         for (int i = 0; i < windows.size(); i++) {
162             FloatingWindow fw = (FloatingWindow) windows.get(i);
163             fw.setStaysOnScreen(staysOnScreen.isSelected());
164         }
165     }
166 
167     private void setFollowImpl() {
168         for (int i = 0; i < windows.size(); i++) {
169             FloatingWindow fw = (FloatingWindow) windows.get(i);
170             fw.setFollowOwner(followsOwner.isSelected());
171         }
172     }
173 
174     private void setMagneticImpl() {
175         for (int i = 0; i < windows.size(); i++) {
176             FloatingWindow fw = (FloatingWindow) windows.get(i);
177             fw.setMagnetic(magnetic.isSelected());
178         }
179     }
180 
181     public int getDragOverAction() {
182         return ((FloatingWindow) windows.get(0)).getDragOverAction();
183     }
184 
185     public void setDragOverAction(int dragOverAction) {
186         for (int i = 0; i < windows.size(); i++) {
187             FloatingWindow fw = (FloatingWindow) windows.get(i);
188             fw.setDragOverAction(dragOverAction);
189         }
190     }
191 
192     public int getDockDelay() {
193         return ((FloatingWindow) windows.get(0)).getDockDelay();
194     }
195 
196     public void setDockDelay(int dockDelay) {
197         for (int i = 0; i < windows.size(); i++) {
198             FloatingWindow fw = (FloatingWindow) windows.get(i);
199             fw.setDockDelay(dockDelay);
200         }
201     }
202 
203     /**
204      * add FloatingWindow to FloatingWindowManager's list
205      * @param fw FloatingWindow
206      */
207     public void add(final FloatingWindow fw) {
208         if (fw != null && !windows.contains(fw)) {
209             windows.add(fw);
210 
211             final SelectableAction action = new SelectableAction(fw.getTitle()) {
212                 public void actionPerformed(ActionEvent e) {
213                     fw.setVisible(isSelected());
214                 }
215             };
216             SCheckBoxMenuItem popupItem = new SCheckBoxMenuItem(action);
217             SCheckBoxMenuItem menuItem = new SCheckBoxMenuItem(action);
218 
219             Helper helper = new Helper();
220             helper.popupItem = popupItem;
221             helper.menuItem = menuItem;
222             helper.action = action;
223             helper.savedShowPopupMenu = fw.isShowPopupMenu();
224 
225             popupItems.put(fw, helper);
226             popup.add(popupItem);
227             action.setSelected(fw.isVisible());
228             menu.add(menuItem);
229             fw.setShowPopupMenu(true);
230             fw.setPopup(popup);
231             fw.propertyChangeManager.addPropertyChangeListener(new PropertyChangeListener() {
232                 public void propertyChange(PropertyChangeEvent evt) {
233                     if (evt.getPropertyName().equals("isActive")) {
234                         if (evt.getNewValue() == Boolean.TRUE) {
235                             setActiveWindow(fw);
236                         }
237                     }
238                     else if (evt.getPropertyName() == (FloatingWindow.PROPERTY_NAME)) {
239                         if (fw.isDragging()) {
240                             drag = fw;
241                         }
242                         else {
243                             if (drag == fw) {
244                                 lastDrag = drag;
245                                 drag = null;
246                             }
247                         }
248                         updateActions(fw);
249                     }
250                 }
251             });
252         }
253     }
254 
255     FloatingWindow lastDrag;
256 
257     /**
258      * update state of Action(s)
259      * @param fw FloatingWindow
260      */
261     private void updateActions(FloatingWindow fw) {
262         Helper helper = (Helper) popupItems.get(fw);
263         if (helper != null) {
264             helper.action.setSelected(fw.isVisible());
265         }
266     }
267 
268     /**
269      * removes FloatingWindow from FloatingWindowManager's list
270      * @param fw FloatingWindow
271      * @return true if FloatingWindow was successfully removed
272      */
273     public boolean remove(FloatingWindow fw) {
274         if (fw != null) {
275             Helper helper = (Helper) popupItems.remove(fw);
276             if (helper != null) {
277                 popup.remove(helper.popupItem);
278                 menu.remove(helper.menuItem);
279                 fw.setShowPopupMenu(helper.savedShowPopupMenu);
280             }
281             fw.setPopup(null);
282             return windows.remove(fw);
283         }
284         return false;
285     }
286 
287     /**
288      * get JMenu created by FloatingWindowManager
289      * @return JMenu
290      */
291     public JMenu getMenu() {
292         return menu;
293     }
294 
295     /**
296      * @return true if 'magnetic' menu item is shown (popup menu only)
297      */
298     public boolean isShowMagnetic() {
299         return showMagnetic;
300     }
301 
302     /**
303      * @param showMagnetic if true then 'magnetic' menu item is shown
304      */
305     public void setShowMagnetic(boolean showMagnetic) {
306         this.showMagnetic = showMagnetic;
307         magnetic.setVisible(showMagnetic);
308         checkSeparator();
309     }
310 
311     /**
312      * @return if true then 'follow owner' menu item is shown
313      */
314     public boolean isShowFollowOwner() {
315         return showFollowOwner;
316     }
317 
318     /**
319      * @param showFollowOwner boolean - if true then 'follow owner' menu item is shown
320      */
321     public void setShowFollowOwner(boolean showFollowOwner) {
322         this.showFollowOwner = showFollowOwner;
323         followsOwner.setVisible(showFollowOwner);
324         checkSeparator();
325     }
326 
327     /**
328      * @return boolean - if true then 'restrict to screen' menu item is shown
329      */
330     public boolean isShowStayOnScreen() {
331         return showRestrictToScreen;
332     }
333 
334     /**
335      * @param showRestrictToScreen - if true then 'restrict to screen' menu item is shown
336      */
337     public void setShowStayOnScreen(boolean showRestrictToScreen) {
338         this.showRestrictToScreen = showRestrictToScreen;
339         staysOnScreen.setVisible(showRestrictToScreen);
340         checkSeparator();
341     }
342 
343     public boolean isMagnetic() {
344         return magnetic.isSelected();
345     }
346 
347     public void setMagnetic(boolean magnetic) {
348         this.magnetic.setSelected(magnetic);
349         setMagneticImpl();
350     }
351 
352     public boolean isFollowsOwner() {
353         return followsOwner.isSelected();
354     }
355 
356     public void setFollowsOwner(boolean followsOwner) {
357         this.followsOwner.setSelected(followsOwner);
358         setFollowImpl();
359     }
360 
361     public boolean isStaysOnScreen() {
362         return staysOnScreen.isSelected();
363     }
364 
365     public void setStaysOnScreen(boolean stayOnScreen) {
366         this.staysOnScreen.setSelected(stayOnScreen);
367         setRectrictedImpl();
368     }
369 
370     /**
371      * separator should be visible if one of build in menu items (follow owner/magnetic/restrict to screen) is shown
372      */
373     protected void checkSeparator() {
374         if (showFollowOwner | showMagnetic | showRestrictToScreen) {
375             separator.setVisible(true);
376         }
377         else {
378             separator.setVisible(false);
379         }
380     }
381 
382     public void setActiveWindow(FloatingWindow fw) {
383         if (active != fw) {
384             if (active != null) {
385                 active.setActive(false);
386             }
387             if (fw != null) {
388                 fw.setActive(true);
389             }
390             this.active = fw;
391         }
392     }
393 
394     public FloatingWindow getActiveWindow() {
395         return active;
396     }
397 
398     private static class Helper {
399         SCheckBoxMenuItem menuItem, popupItem;
400         SelectableAction action;
401         boolean savedShowPopupMenu;
402     }
403 }