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

Quick Search    Search Deep

Source code: org/progeeks/meta/swing/MetaPanel.java


1   /*
2    * $Id: MetaPanel.java,v 1.2 2003/08/27 03:47:09 pspeed Exp $
3    *
4    * Copyright (c) 2001-2002, Paul Speed
5    * All rights reserved.
6    *
7    * Redistribution and use in source and binary forms, with or without
8    * modification, are permitted provided that the following conditions
9    * are met:
10   *
11   * 1) Redistributions of source code must retain the above copyright notice,
12   *    this list of conditions and the following disclaimer.
13   * 2) Redistributions in binary form must reproduce the above copyright
14   *    notice, this list of conditions and the following disclaimer in the
15   *    documentation and/or other materials provided with the distribution.
16   * 3) Neither the names "Progeeks", "Meta-JB", nor the names of its contributors
17   *    may be used to endorse or promote products derived from this software
18   *    without specific prior written permission.
19   *
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23   * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30   * POSSIBILITY OF SUCH DAMAGE.
31   */
32  
33  package org.progeeks.meta.swing;
34  
35  import java.awt.*;
36  import java.util.*;
37  import javax.swing.*;
38  
39  import org.progeeks.meta.*;
40  import org.progeeks.meta.format.*;
41  import org.progeeks.util.log.*;
42  
43  /**
44   *  A JPanel implementation that provides additional container
45   *  methods for adding MetaObjects and PropertyMutators as if they
46   *  were actual UI components.
47   *
48   *  @version   $Revision: 1.2 $
49   *  @author    Paul Speed
50   */
51  public class MetaPanel extends JPanel
52  {
53      static Log log = Log.getLog( MetaPanel.class );
54  
55      private FactoryRegistry     factories;
56      private boolean             editable;
57  
58      private ArrayList           mutators = new ArrayList();
59      private ArrayList           uis = new ArrayList();
60  
61      /**
62       *  Creates aa MetaPanel with a default factory registry and layout manager.
63       */
64      public MetaPanel()
65      {
66          this( new FactoryRegistry(), new BorderLayout(), true );
67      }
68  
69      /**
70       *  Creates an empty MetaColumnPanel with a default layout manager.
71       */
72      public MetaPanel( FactoryRegistry factories )
73      {
74          this( factories, new BorderLayout(), true );
75      }
76  
77      /**
78       *  Creates a meta-panel with the specified factory and layout manager.
79       */
80      public MetaPanel( FactoryRegistry factories, LayoutManager layout )
81      {
82          this( factories, layout, true );
83      }
84  
85      /**
86       *  Creates a meta-panel with the specified factory and layout manager.
87       */
88      public MetaPanel( FactoryRegistry factories, LayoutManager layout, boolean editable )
89      {
90          super( layout );
91          this.factories = factories;
92          this.editable = editable;
93      }
94  
95      /**
96       *  Creates a meta-property UI for the specified mutator
97       *  and added the UI to the appropriate data structures.
98       */
99      protected MetaPropertyUI createUI( PropertyMutator mutator, int index )
100     {
101         PropertyInfo info = mutator.getPropertyInfo();
102         MetaPropertyUI ui = null;
103         if( info.isWritable() && editable )
104             {
105             ui = factories.createPropertyEditor( info.getPropertyType() );
106             }
107         else
108             {
109             ui = factories.createPropertyRenderer( info.getPropertyType() );
110             }
111         ui.setPropertyMutator( mutator );
112         if( index >= 0 )
113             {
114             mutators.add( index, mutator );
115             uis.add( index, ui );
116             }
117         else
118             {
119             mutators.add( mutator );
120             uis.add( ui );
121             }
122 
123         return( ui );
124     }
125 
126     /**
127      *  Inserts an empty space into the data structures that
128      *  map mutators to components.  This helps keep the mutator
129      *  list in synch with the container's component list.
130      */
131     protected void addBlank( int index )
132     {
133         if( index >= 0 )
134             {
135             mutators.add( index, null );
136             uis.add( index, null );
137             }
138         else
139             {
140             mutators.add( null );
141             uis.add( null );
142             }
143     }
144 
145     /**
146      *  Releases a meta-property UI and removes it from the
147      *  appropriate data structures.
148      */
149     protected void removeSlot( int index )
150     {
151         mutators.remove( index );
152         uis.remove( index );
153     }
154 
155     /**
156      *  Returns the index of the specified component.
157      */
158     protected int getComponentIndex( Component comp )
159     {
160         int count = getComponentCount();
161         for( int i = 0; i < count; i++ )
162             {
163             if( comp.equals( getComponent(i) ) )
164                 return( i );
165             }
166         return( -1 );
167     }
168 
169     /**
170      *  Adds the specified PropertyMutator to this container by
171      *  creating a component as appropriate for its type.
172      *
173      *  @param the mutator for which a component will be created.
174      */
175     public MetaPropertyUI add( PropertyMutator mutator )
176     {
177         return( add( mutator, null, -1 ) );
178     }
179 
180     /**
181      *  Adds the specified PropertyMutator to this container by
182      *  creating a component as appropriate for its type.
183      *
184      *  @param the mutator for which a component will be created.
185      *  @param an object expressing layout contraints for the mutator's UI component
186      *  @param the position at which to insert the mutator, or -1 to
187      *         append the mutator to the end
188      */
189     public MetaPropertyUI add( PropertyMutator mutator, int index )
190     {
191         return( add( mutator, null, index ) );
192     }
193 
194     /**
195      *  Adds the specified PropertyMutator to this container by
196      *  creating a component as appropriate for its type.  The
197      *  constraints are passed when the component is added and
198      *  are specific to the type of layout manager being used.
199      *
200      *  @param The mutator for which a component will be created.
201      *  @param an object expressing layout contraints for the mutator's UI component
202      */
203     public MetaPropertyUI add( PropertyMutator mutator, Object constraints )
204     {
205         return( add( mutator, constraints, -1 ) );
206     }
207 
208     /**
209      *  Adds the specified PropertyMutator to this container by
210      *  creating a component as appropriate for its type.  The
211      *  constraints are passed when the component is added and
212      *  are specific to the type of layout manager being used.
213      *
214      *  @param The mutator for which a component will be created.
215      *  @param the position at which to insert the mutator, or -1 to
216      *         append the mutator to the end
217      */
218     public MetaPropertyUI add( PropertyMutator mutator, Object constraints, int index )
219     {
220         MetaPropertyUI ui = createUI( mutator, index );
221         super.add( ui.getUIComponent(), constraints, index );
222         return( ui );
223     }
224 
225     public void add( Component comp, Object constraints, int index )
226     {
227         // Overridden so that we can keep track of the empty spaces
228         super.add( comp, constraints, index );
229         addBlank( index );
230     }
231 
232     /**
233      *  Returns the mutator at the specified index or null if no
234      *  mutator exists at the specified position, ie: it's a component
235      *  that was added manually.
236      */
237     public PropertyMutator getMutator( int index )
238     {
239         return( (PropertyMutator)mutators.get( index ) );
240     }
241 
242     /**
243      *  Could have a method that would replace a meta-object.  It
244      *  could do this by finding all mutators associated with a
245      *  specified object and replacing them with like mutators from
246      *  a new object.  Useful?
247      */
248 
249     /**
250      *  Returns the meta-property UI for the specified index or null
251      *  if no meta-property UI exists at the specified position.
252      */
253     public MetaPropertyUI getMetaPropertyUI( int index )
254     {
255         return( (MetaPropertyUI)uis.get( index ) );
256     }
257 
258     /**
259      *  Removes the first component associated with the specified mutator.
260      */
261     public void remove( PropertyMutator mutator )
262     {
263         // The mutator may exist more than once in the panel.
264         // We need to find the right one.  We grab the first.
265         int index = mutators.indexOf( mutator );
266         if( index < 0 )
267             throw new RuntimeException( "Mutator not found." );  // probably a bit harsh
268         remove( index );
269     }
270 
271     /**
272      *  Removes the component and mutator at the specified index.
273      */
274     public void remove( int index )
275     {
276         super.remove( index );
277 
278         MetaPropertyUI ui = (MetaPropertyUI)uis.get( index );
279 
280         // Remove the UI component associated with the mutator.
281         super.remove( ui.getUIComponent() );
282 
283         removeSlot( index );
284 
285         // Release any listeners associatd with the UI
286         ui.release();
287     }
288 
289     /**
290      *  Removes all components and mutators from this container.
291      */
292     public void removeAll()
293     {
294         super.removeAll();
295 
296         // Release all of the UIs
297         for( Iterator i = uis.iterator(); i.hasNext(); )
298             {
299             Object obj = i.next();
300             if( obj instanceof MetaPropertyUI )
301                 {
302                 ((MetaPropertyUI)obj).release();
303                 }
304             }
305 
306         // Clear the lists
307         mutators.clear();
308         uis.clear();
309     }
310 }
311