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

Quick Search    Search Deep

Source code: com/virtuosotechnologies/asaph/maingui/PaneManagerImpl.java


1   /*
2   ================================================================================
3   
4     FILE:  PaneManagerImpl.java
5     
6     PROJECT:
7     
8       Asaph
9     
10    CONTENTS:
11    
12      Implementation of the pane manager
13    
14    PROGRAMMERS:
15    
16      Daniel Azuma (DA)  <dazuma@kagi.com>
17    
18    COPYRIGHT:
19    
20      Copyright (C) 2003  Daniel Azuma  (dazuma@kagi.com)
21      
22      This program is free software; you can redistribute it and/or
23      modify it under the terms of the GNU General Public License as
24      published by the Free Software Foundation; either version 2
25      of the License, or (at your option) any later version.
26      
27      This program is distributed in the hope that it will be useful,
28      but WITHOUT ANY WARRANTY; without even the implied warranty of
29      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30      GNU General Public License for more details.
31      
32      You should have received a copy of the GNU General Public
33      License along with this program; if not, write to
34        Free Software Foundation, Inc.
35        59 Temple Place, Suite 330
36        Boston, MA 02111-1307 USA
37  
38  ================================================================================
39  */
40  
41  
42  package com.virtuosotechnologies.asaph.maingui;
43  
44  
45  import java.beans.PropertyVetoException;
46  import java.util.Set;
47  import java.util.HashSet;
48  import java.awt.Dimension;
49  import javax.swing.JDesktopPane;
50  import javax.swing.JComponent;
51  import javax.swing.JInternalFrame;
52  import javax.swing.WindowConstants;
53  import javax.swing.event.InternalFrameAdapter;
54  import javax.swing.event.InternalFrameEvent;
55  
56  import com.virtuosotechnologies.lib.base.ConstrainedKey;
57  import com.virtuosotechnologies.lib.command.CommandNode;
58  import com.virtuosotechnologies.lib.command.CommandEvent;
59  import com.virtuosotechnologies.lib.basiccommand.BasicCommandNode;
60  import com.virtuosotechnologies.lib.basiccommand.BasicItemCommandNode;
61  import com.virtuosotechnologies.lib.basiccommand.BasicContainerCommandNode;
62  import com.virtuosotechnologies.lib.basiccommand.swing.CommandNodeMenuBar;
63  import com.virtuosotechnologies.lib.propertyset.PropertySet;
64  import com.virtuosotechnologies.lib.propertyset.PropertySetListener;
65  import com.virtuosotechnologies.lib.propertyset.PropertySetEvent;
66  import com.virtuosotechnologies.lib.propertyset.BasicPropertySet;
67  
68  
69  /**
70   * Implementation of the pane manager
71   */
72  /*package*/ class PaneManagerImpl
73  implements PaneManager
74  {
75    private JDesktopPane desktop_;
76    private int lastPaneX_;
77    private int lastPaneY_;
78    private Set openPanes_;
79    private BasicCommandNode windowsMenuNode_;
80    private ListsImpl listsImpl_;
81    
82    
83    /*package*/ PaneManagerImpl(
84      ListsImpl listsImpl)
85    {
86      desktop_ = new JDesktopPane();
87      openPanes_ = new HashSet();
88      lastPaneX_ = 1000000;
89      lastPaneY_ = 1000000;
90      listsImpl_ = listsImpl;
91    }
92    
93    
94    /*package*/ void setCommandManager(
95      CommandManagerImpl commandManager)
96    {
97      windowsMenuNode_ = commandManager.getWindowsMenuNode();
98    }
99    
100   
101   /*package*/ JComponent getJComponent()
102   {
103     return desktop_;
104   }
105   
106   
107   /**
108    * Open a pane in the main gui. Depending on how the main gui is
109    * implemented, this pane may show up as a tab in a tabbed pane, or an
110    * internal frame, or in some other similar fashion.
111    *
112    * @param component Component representing the pane
113    * @param title initial title for the pane
114    * @param commands CommandNode for creating a menu bar, or null for no menu bar
115    * @param handler a PaneHandler for handling pane events
116    * @return A PaneController that will manipulate this pane
117    */
118   public PaneController createPane(
119     JComponent component,
120     String title,
121     CommandNode commands,
122     final PaneHandler handler)
123   {
124     final JInternalFrame frame = new JInternalFrame(title, true, true, true, true);
125     frame.setContentPane(component);
126     
127     if (commands != null)
128     {
129       BasicCommandNode container = new BasicContainerCommandNode();
130       container.addChild(commands);
131       CommandNodeMenuBar menuBar = new CommandNodeMenuBar(container);
132       frame.setJMenuBar(menuBar);
133     }
134     
135     // Setup controller
136     final PaneControllerImpl controller = new PaneControllerImpl(
137       frame, handler);
138     openPanes_.add(controller);
139     
140     // Setup menu
141     PaneCommandNode node = new PaneCommandNode(controller);
142     windowsMenuNode_.addChild(node);
143     controller.setCommandNode(node);
144     
145     // What to do on close
146     frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
147     frame.addInternalFrameListener(
148       new InternalFrameAdapter()
149       {
150         public void internalFrameClosing(
151           InternalFrameEvent ev)
152         {
153           if (handler.handlePaneClosing())
154           {
155             controller.close();
156           }
157         }
158       });
159     
160     // Add to desktop
161     desktop_.add(frame);
162     frame.pack();
163     int desktopWidth = desktop_.getWidth();
164     int desktopHeight = desktop_.getHeight();
165     Dimension dim = frame.getSize();
166     dim.width += 10;
167     dim.width = Math.min(dim.width, desktopWidth-25);
168     dim.height = Math.min(dim.height, desktopHeight-25);
169     frame.setSize(dim);
170     int x = lastPaneX_+20;
171     int y = lastPaneY_+20;
172     if (x+dim.width > desktopWidth) x = 2;
173     if (y+dim.height > desktopHeight) y = 2;
174     frame.setLocation(x, y);
175     lastPaneX_ = x;
176     lastPaneY_ = y;
177     frame.setVisible(true);
178     
179     return controller;
180   }
181   
182   
183   /*package*/ boolean shutDown()
184   {
185     while (!openPanes_.isEmpty())
186     {
187       PaneControllerImpl controller = (PaneControllerImpl)openPanes_.iterator().next();
188       if (!controller.getHandler().handlePaneClosing())
189       {
190         return false;
191       }
192       controller.close();
193     }
194     return true;
195   }
196   
197   
198   private class PaneCommandNode
199   extends BasicItemCommandNode
200   {
201     private PaneControllerImpl controller_;
202     
203     /*package*/ PaneCommandNode(
204       PaneControllerImpl controller)
205     {
206       controller_ = controller;
207       setNameProperty((String)controller_.getValue(PaneController.TITLE_KEY));
208     }
209     
210     public void commandInvoked(
211       CommandEvent ev)
212     {
213       controller_.grabFocus();
214     }
215   }
216   
217   
218   private class PaneControllerImpl
219   extends BasicPropertySet
220   implements
221     PaneController,
222     PropertySetListener
223   {
224     private JInternalFrame frame_;
225     private PaneHandler handler_;
226     private boolean isOpen_ = true;
227     private BasicCommandNode paneCommandNode_;
228     
229     
230     /*package*/ PaneControllerImpl(
231       JInternalFrame frame,
232       PaneHandler handler)
233     {
234       frame_ = frame;
235       putValue(TITLE_KEY, frame_.getTitle());
236       putValue(WINDOW_MODIFIED_KEY, Boolean.FALSE);
237       handler_ = handler;
238       addPropertySetListener(this);
239     }
240     
241     
242     /*package*/ PaneHandler getHandler()
243     {
244       return handler_;
245     }
246     
247     
248     /*package*/ void setCommandNode(
249       BasicCommandNode node)
250     {
251       paneCommandNode_ = node;
252     }
253     
254     
255     /**
256      * Returns true if the pane is still open. That is, if it hasn't had its
257      * close() method called yet. If this returns false, this PaneController is
258      * defunct and cannot have any other methods invoked.
259      *
260      * @return true if the pane is still open.
261      */
262     public boolean isOpen()
263     {
264       return isOpen_;
265     }
266     
267     
268     /**
269      * Close the pane in the main gui. Once the pane is closed, this handle
270      * will go defunct and cannot be used again, except to query isOpen().
271      *
272      * @exception IllegalStateException pane already closed.
273      */
274     public void close()
275     {
276       if (!isOpen_)
277       {
278         throw new IllegalStateException();
279       }
280       openPanes_.remove(this);
281       isOpen_ = false;
282       frame_.dispose();
283       desktop_.remove(frame_);
284       for (int i=windowsMenuNode_.getNumChildren()-1; i>=0; --i)
285       {
286         if (windowsMenuNode_.getNthChild(i) == paneCommandNode_)
287         {
288           windowsMenuNode_.removeNthChild(i);
289           break;
290         }
291       }
292       listsImpl_.requestFocus();
293     }
294     
295     
296     /**
297      * Returns true if this pane has focus. Focus means the internal frame
298      * or tab is in front and has keyboard focus.
299      *
300      * @return true if the pane has focus.
301      * @exception IllegalStateException pane is closed.
302      */
303     public boolean isFocused()
304     {
305       if (!isOpen_)
306       {
307         throw new IllegalStateException();
308       }
309       return frame_.isSelected();
310     }
311     
312     
313     /**
314      * Cause this pane to grab focus. Focus means the internal frame or tab
315      * is in front and has keyboard focus.
316      *
317      * @exception IllegalStateException pane is closed.
318      */
319     public void grabFocus()
320     {
321       if (!isOpen_)
322       {
323         throw new IllegalStateException();
324       }
325       try
326       {
327         frame_.setSelected(true);
328       }
329       catch (PropertyVetoException ex)
330       {
331       }
332     }
333     
334     
335     public void propertySetChanged(
336       PropertySetEvent ev)
337     {
338       ConstrainedKey key = ev.getKey();
339       if (key == TITLE_KEY)
340       {
341         String title = (String)ev.getNewValue();
342         frame_.setTitle(title);
343         paneCommandNode_.setNameProperty(title);
344       }
345       else if (key == WINDOW_MODIFIED_KEY)
346       {
347         frame_.putClientProperty("windowModified", ev.getNewValue());
348       }
349     }
350   }
351 }