KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > barracuda > core > comp > BList


1 /*
2  * Copyright (C) 2003 Christian Cryder [christianc@granitepeaks.com]
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * $Id: BList.java,v 1.19 2004/02/01 05:16:27 christianc Exp $
19  */

20 package org.enhydra.barracuda.core.comp;
21
22 import java.util.*;
23
24 import org.apache.log4j.*;
25 import org.w3c.dom.*;
26 import org.w3c.dom.html.*;
27
28 import org.enhydra.barracuda.core.comp.model.*;
29 import org.enhydra.barracuda.core.comp.renderer.*;
30 import org.enhydra.barracuda.core.comp.renderer.html.*;
31 import org.enhydra.barracuda.core.comp.renderer.xml.*;
32 import org.enhydra.barracuda.core.util.dom.DOMUtil;
33 import org.enhydra.barracuda.core.view.*;
34 import org.enhydra.barracuda.plankton.*;
35
36 /**
37  * A BList component is used to render list data into a DOM
38  * template. It can be bound to a wide range of markup elements
39  * (see HTMLListRenderer for details).
40  *
41  * <p>In the case of BList, you will ALMOST ALWAYS need to manually
42  * bind it to a View, unless you happen to be returning it from a model
43  * (in which case this will be done for you automatically by cloning
44  * the node which contained the directive)
45  */

46 public class BList extends BComponent {
47
48     //public vars
49
protected static final Logger logger = Logger.getLogger(BList.class.getName());
50     
51     //private vars
52
protected ListModel model = null;
53     private LocalModelListener callback = null;
54
55     //--------------- Constructors -------------------------------
56
/**
57      * Public noargs constructor
58      */

59     public BList() {}
60     
61     /**
62      * Public constructor which creates the component and
63      * binds it to a specific view
64      *
65      * @param imodel the specific model to back this component
66      */

67     public BList(ListModel imodel) {
68         this(imodel, null);
69     }
70     
71     /**
72      * Public constructor which creates the component and
73      * binds it to a specific model. The component is also
74      * bound to the specified view.
75      *
76      * <p>Null values may be passed in for any parameters,
77      * but if you do so you will need manually provide these
78      * values (via the accessor methods) prior to actually
79      * rendering the component
80      *
81      * @param model the specific model to back this component
82      * @param view the View the component should be bound to
83      */

84     BList(ListModel imodel, View iview) {
85         if (imodel!=null) setModel(imodel);
86         if (iview!=null) this.addView(iview);
87     }
88     
89
90
91
92     //--------------- Renderer -----------------------------------
93
/**
94      * Default component renderer factory registrations
95      */

96     static {
97         HTMLRendererFactory rfHTML = new HTMLRendererFactory();
98         installRendererFactory(rfHTML, BList.class, HTMLElement.class);
99         installRendererFactory(rfHTML, BList.class, HTMLDocument.class);
100     }
101
102     /**
103      * HTML RendererFactory
104      */

105     static class HTMLRendererFactory implements RendererFactory {
106         public Renderer getInstance() {return new HTMLListRenderer();}
107     }
108
109
110
111     //--------------- BList -------------------------------
112
/**
113      * Set the model that backs the list. This causes the list to register
114      * as a listener on the model, so any changes to it will be reflected in
115      * the list.
116      *
117      * @param imodel the model that backs the list
118      */

119     public void setModel(ListModel imodel) {
120
121         //deregister if possible
122
if (model!=null && callback!=null) {
123             model.removeModelListener(callback);
124         }
125     
126         //set the model
127
model = imodel;
128         invalidate();
129         
130         //reregister if possible
131
if (model!=null) {
132             if (callback==null) callback = new LocalModelListener();
133             model.addModelListener(callback);
134         }
135         
136         //Q: how does this affect garbage collection? In other words, how do we
137
//ensure that when we're done with this object it will get gc'd since the
138
//model will still have a reference to it? This seems especially problematic
139
//if we had multiple components sharing a model and one of them goes away.
140
//
141
//A: (I think) In the components destroyCycle, make sure the list model
142
//gets set to null
143
}
144     
145     /**
146      * Get the model that backs the list
147      *
148      * @return the model that backs the list
149      */

150     public ListModel getModel() {
151         if (model==null) setModel(new DefaultListModel());
152         return model;
153     }
154     
155     /**
156      * A convenience method that constructs a ListModel from an array of Objects
157      * and then applies setModel to it.
158      *
159      * @param list an array of Objects containing the items to display
160      * in the list
161      */

162     public void setListData(Object JavaDoc[] list) {
163         DefaultListModel lm = new DefaultListModel();
164         if (list!=null) for (int i=0,max=list.length; i<max; i++) {
165             lm.add(list[i]);
166         }
167         setModel(lm);
168     }
169     
170     /**
171      * A convenience method that constructs a ListModel from an Iterator
172      * and then applies setModel to it.
173      *
174      * @param it an iterator of objects to display in the list
175      */

176     public void setListData(Iterator it) {
177         DefaultListModel lm = new DefaultListModel();
178         while (it.hasNext()) {
179             lm.add(it.next());
180         }
181         setModel(lm);
182     }
183     
184     /**
185      * Render a specific view for the component.
186      *
187      * @param view View to be rendered
188      * @param vc ViewContext for the client view
189      * @throws RenderException if the particular View is not supported
190      * @param list a List of all the views for this component
191      */

192 /*
193 //021102.3_csc - removed, because now its in BComponent
194     protected void renderView (View view, ViewContext vc, int depth) throws RenderException {
195         if (logger.isInfoEnabled()) logger.info("rendering comp:"+this.toRef()+" view:"+view);
196
197         //actually render the view according to known interfaces
198         try {
199             Renderer r = getRenderer(view);
200             r.renderComponent(this, view, vc);
201             
202         } catch (DOMException e) {
203             logger.warn("DOM Error:", e);
204             throw new DOMAccessException("Error rendering component in view:"+e, e);
205         }
206     }
207 */

208
209
210
211     //--------------- Lifecycle ----------------------------------
212
/**
213      * Destroy cycle. The component should use this cycle to
214      * perform any special cleanup.
215      */

216     public void destroyCycle() {
217         //default destroy
218
super.destroyCycle();
219     
220         //we set the model to null so that the component can be
221
//garbage collected. If we don't do this, the model retains
222
//a reference back to the component and so the component
223
//will never be freed up...
224
setModel(null);
225     }
226
227
228
229
230     //--------------- Utility ------------------------------------
231
/*
232     class LocalListDataListener implements ListDataListener {
233         //for right now, just invalidate everything. In the future,
234         //we could get a lot smarter and keep track of the ranges
235         //changed and then only redraw those. This would greatly
236         //speed rendering, because we'd only need to redraw the parts
237         //of the DOM that changed...
238         public void intervalAdded(ListDataEvent e) {invalidate();}
239         public void intervalRemoved(ListDataEvent e) {invalidate();}
240         public void contentsChanged(ListDataEvent e) {invalidate();}
241     }
242 */

243     class LocalModelListener implements ModelListener {
244         //get notified when one of the underlying models changes
245
public void modelChanged(Model m) {
246             invalidate();
247         }
248     }
249 }
Popular Tags