KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > common > component > UIPanel


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.web.ui.common.component;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import javax.faces.component.NamingContainer;
23 import javax.faces.component.UICommand;
24 import javax.faces.component.UIComponent;
25 import javax.faces.component.UIForm;
26 import javax.faces.context.FacesContext;
27 import javax.faces.context.ResponseWriter;
28 import javax.faces.el.MethodBinding;
29 import javax.faces.el.ValueBinding;
30 import javax.faces.event.AbortProcessingException;
31 import javax.faces.event.ActionEvent;
32 import javax.faces.event.FacesEvent;
33
34 import org.alfresco.web.ui.common.PanelGenerator;
35 import org.alfresco.web.ui.common.Utils;
36 import org.alfresco.web.ui.common.WebResources;
37
38 /**
39  * @author kevinr
40  */

41 public class UIPanel extends UICommand
42 {
43    // ------------------------------------------------------------------------------
44
// Component Impl
45

46    /**
47     * Default constructor
48     */

49    public UIPanel()
50    {
51       setRendererType(null);
52    }
53    
54    /**
55     * @see javax.faces.component.UIComponent#getFamily()
56     */

57    public String JavaDoc getFamily()
58    {
59       return "org.alfresco.faces.Controls";
60    }
61    
62    /**
63     * Return the UI Component to be displayed on the right of the panel title area
64     *
65     * @return UIComponent
66     */

67    public UIComponent getTitleComponent()
68    {
69       UIComponent titleComponent = null;
70       
71       // attempt to find a component with the specified ID
72
String JavaDoc facetsId = getFacetsId();
73       if (facetsId != null)
74       {
75          UIForm parent = Utils.getParentForm(FacesContext.getCurrentInstance(), this);
76          UIComponent facetsComponent = parent.findComponent(facetsId);
77          if (facetsComponent != null)
78          {
79             // get the 'title' facet from the component
80
titleComponent = facetsComponent.getFacet("title");
81          }
82       }
83       
84       return titleComponent;
85    }
86
87    /**
88     * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
89     */

90    public void encodeBegin(FacesContext context) throws IOException JavaDoc
91    {
92       if (isRendered() == false)
93       {
94          return;
95       }
96       
97       ResponseWriter out = context.getResponseWriter();
98       
99       // determine if we have a component on the header
100
UIComponent titleComponent = getTitleComponent();
101       
102       // determine whether we have any adornments
103
String JavaDoc label = getLabel();
104       if (label != null || isProgressive() == true || titleComponent != null)
105       {
106          this.hasAdornments = true;
107       }
108       
109       // make sure we have a default background color for the content area
110
String JavaDoc bgcolor = getBgcolor();
111       if (bgcolor == null)
112       {
113          bgcolor = PanelGenerator.BGCOLOR_WHITE;
114       }
115       
116       // determine if we have a bordered title area, note, we also need to have
117
// the content area border defined as well
118
if ((getTitleBgcolor() != null) && (getTitleBorder() != null) &&
119           (getBorder() != null) && this.hasAdornments)
120       {
121          this.hasBorderedTitleArea = true;
122       }
123       
124       // output first part of border table
125
if (this.hasBorderedTitleArea)
126       {
127          PanelGenerator.generatePanelStart(
128                out,
129                context.getExternalContext().getRequestContextPath(),
130                getTitleBorder(),
131                getTitleBgcolor());
132       }
133       else if (getBorder() != null)
134       {
135          PanelGenerator.generatePanelStart(
136                out,
137                context.getExternalContext().getRequestContextPath(),
138                getBorder(),
139                bgcolor);
140       }
141
142       if (this.hasAdornments)
143       {
144          // start the containing table if we have any adornments
145
out.write("<table border='0' cellspacing='0' cellpadding='0' width='100%'><tr><td>");
146       }
147
148       // output progressive disclosure icon in appropriate state
149
// TODO: manage state of this icon via component Id!
150
if (isProgressive() == true)
151       {
152          out.write("<a HREF='#' onclick=\"");
153          String JavaDoc value = getClientId(context) + NamingContainer.SEPARATOR_CHAR + Boolean.toString(!isExpanded());
154          out.write(Utils.generateFormSubmit(context, this, getHiddenFieldName(), value));
155          out.write("\">");
156          
157          if (isExpanded() == true)
158          {
159             out.write(Utils.buildImageTag(context, WebResources.IMAGE_EXPANDED, 11, 11, ""));
160          }
161          else
162          {
163             out.write(Utils.buildImageTag(context, WebResources.IMAGE_COLLAPSED, 11, 11, ""));
164          }
165          
166          out.write("</a>&nbsp;&nbsp;");
167       }
168       
169       // output textual label
170
if (label != null)
171       {
172          out.write("<span");
173          Utils.outputAttribute(out, getAttributes().get("style"), "style");
174          Utils.outputAttribute(out, getAttributes().get("styleClass"), "class");
175          out.write('>');
176          
177          out.write(Utils.encode(label));
178          
179          out.write("</span>");
180       }
181
182       if (this.hasAdornments)
183       {
184          out.write("</td>");
185       }
186       
187       // render the title component if supplied
188
if (titleComponent != null)
189       {
190          out.write("<td align='right'>");
191          Utils.encodeRecursive(context, titleComponent);
192          out.write("</td>");
193       }
194       
195       if (this.hasAdornments)
196       {
197          out.write("</tr></table>");
198       }
199       
200       // if we have the titled border area, output the middle section
201
if (this.hasBorderedTitleArea && isExpanded())
202       {
203          PanelGenerator.generateTitledPanelMiddle(
204                out,
205                context.getExternalContext().getRequestContextPath(),
206                getTitleBorder(),
207                getBorder(),
208                getBgcolor());
209       }
210    }
211
212    /**
213     * @see javax.faces.component.UIComponentBase#encodeEnd(javax.faces.context.FacesContext)
214     */

215    public void encodeEnd(FacesContext context) throws IOException JavaDoc
216    {
217       if (isRendered() == false)
218       {
219          return;
220       }
221       
222       ResponseWriter out = context.getResponseWriter();
223       
224       // output final part of border table
225
if (this.hasBorderedTitleArea && isExpanded() == false)
226       {
227          PanelGenerator.generatePanelEnd(
228                out,
229                context.getExternalContext().getRequestContextPath(),
230                getTitleBorder());
231       }
232       else if (getBorder() != null)
233       {
234          PanelGenerator.generatePanelEnd(
235                out,
236                context.getExternalContext().getRequestContextPath(),
237                getBorder());
238       }
239    }
240    
241    /**
242     * @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
243     */

244    public void decode(FacesContext context)
245    {
246       Map JavaDoc requestMap = context.getExternalContext().getRequestParameterMap();
247       String JavaDoc fieldId = getHiddenFieldName();
248       String JavaDoc value = (String JavaDoc)requestMap.get(fieldId);
249       
250       // we encoded the value to start with our Id
251
if (value != null && value.startsWith(getClientId(context)))
252       {
253          // we were clicked, strip out the value
254
value = value.substring(getClientId(context).length() + 1);
255          
256          // the expand/collapse icon was clicked, so toggle the state
257
ExpandedEvent event = new ExpandedEvent(this, Boolean.parseBoolean(value));
258          queueEvent(event);
259          
260          //
261
// TODO: See http://forums.java.sun.com/thread.jspa?threadID=524925&start=15&tstart=0
262
// Bug/known issue in JSF 1.1 RI
263
// This causes a problem where the View attempts to assign duplicate Ids
264
// to components when createUniqueId() on UIViewRoot is called before the
265
// render phase. This occurs in the Panel tag as it must call getComponent()
266
// early to decide whether to allow the tag to render contents or not.
267
//
268
// context.getViewRoot().setTransient(true);
269
//
270
// The other solution is to explicity give ALL child components of the
271
// panel a unique Id rather than a generated one!
272
}
273    }
274    
275    /**
276     * @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
277     */

278    public void broadcast(FacesEvent event) throws AbortProcessingException
279    {
280       if (event instanceof ExpandedEvent)
281       {
282          // expanded event - we handle this
283
setExpanded( ((ExpandedEvent)event).State );
284          
285          if (getExpandedActionListener() != null)
286          {
287             Utils.processActionMethod(getFacesContext(), getExpandedActionListener(), (ExpandedEvent)event);
288          }
289       }
290       else
291       {
292          super.broadcast(event);
293       }
294    }
295
296    /**
297     * @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
298     */

299    public void restoreState(FacesContext context, Object JavaDoc state)
300    {
301       Object JavaDoc values[] = (Object JavaDoc[])state;
302       // standard component attributes are restored by the super class
303
super.restoreState(context, values[0]);
304       setExpanded( ((Boolean JavaDoc)values[1]).booleanValue() );
305       this.progressive = (Boolean JavaDoc)values[2];
306       this.border = (String JavaDoc)values[3];
307       this.bgcolor = (String JavaDoc)values[4];
308       this.label = (String JavaDoc)values[5];
309       this.titleBgcolor = (String JavaDoc)values[6];
310       this.titleBorder = (String JavaDoc)values[7];
311       this.expandedActionListener = (MethodBinding)values[8];
312       this.facetsId = (String JavaDoc)values[9];
313    }
314    
315    /**
316     * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
317     */

318    public Object JavaDoc saveState(FacesContext context)
319    {
320       Object JavaDoc values[] = new Object JavaDoc[10];
321       // standard component attributes are saved by the super class
322
values[0] = super.saveState(context);
323       values[1] = (isExpanded() ? Boolean.TRUE : Boolean.FALSE);
324       values[2] = this.progressive;
325       values[3] = this.border;
326       values[4] = this.bgcolor;
327       values[5] = this.label;
328       values[6] = this.titleBgcolor;
329       values[7] = this.titleBorder;
330       values[8] = this.expandedActionListener;
331       values[9] = this.facetsId;
332       return values;
333    }
334    
335    
336    // ------------------------------------------------------------------------------
337
// Strongly typed component property accessors
338

339    /**
340     * @param binding The MethodBinding to call when expand/collapse is performed by the user.
341     */

342    public void setExpandedActionListener(MethodBinding binding)
343    {
344       this.expandedActionListener = binding;
345    }
346    
347    /**
348     * @return The MethodBinding to call when expand/collapse is performed by the user.
349     */

350    public MethodBinding getExpandedActionListener()
351    {
352       return this.expandedActionListener;
353    }
354    
355    /**
356     * @return Returns the bgcolor.
357     */

358    public String JavaDoc getBgcolor()
359    {
360       ValueBinding vb = getValueBinding("bgcolor");
361       if (vb != null)
362       {
363          this.bgcolor = (String JavaDoc)vb.getValue(getFacesContext());
364       }
365       
366       return this.bgcolor;
367    }
368    
369    /**
370     * @param bgcolor The bgcolor to set.
371     */

372    public void setBgcolor(String JavaDoc bgcolor)
373    {
374       this.bgcolor = bgcolor;
375    }
376
377    /**
378     * @return Returns the border name.
379     */

380    public String JavaDoc getBorder()
381    {
382       ValueBinding vb = getValueBinding("border");
383       if (vb != null)
384       {
385          this.border = (String JavaDoc)vb.getValue(getFacesContext());
386       }
387       
388       return this.border;
389    }
390
391    /**
392     * @param border The border name to user.
393     */

394    public void setBorder(String JavaDoc border)
395    {
396       this.border = border;
397    }
398    
399    /**
400     * @return Returns the bgcolor of the title area
401     */

402    public String JavaDoc getTitleBgcolor()
403    {
404       ValueBinding vb = getValueBinding("titleBgcolor");
405       if (vb != null)
406       {
407          this.titleBgcolor = (String JavaDoc)vb.getValue(getFacesContext());
408       }
409       
410       return this.titleBgcolor;
411    }
412
413    /**
414     * @param titleBgcolor Sets the bgcolor of the title area
415     */

416    public void setTitleBgcolor(String JavaDoc titleBgcolor)
417    {
418       this.titleBgcolor = titleBgcolor;
419    }
420
421    /**
422     * @return Returns the border style of the title area
423     */

424    public String JavaDoc getTitleBorder()
425    {
426       ValueBinding vb = getValueBinding("titleBorder");
427       if (vb != null)
428       {
429          this.titleBorder = (String JavaDoc)vb.getValue(getFacesContext());
430       }
431       
432       return this.titleBorder;
433    }
434
435    /**
436     * @param titleBorder Sets the border style of the title area
437     */

438    public void setTitleBorder(String JavaDoc titleBorder)
439    {
440       this.titleBorder = titleBorder;
441    }
442
443    /**
444     * @return Returns the label.
445     */

446    public String JavaDoc getLabel()
447    {
448       ValueBinding vb = getValueBinding("label");
449       if (vb != null)
450       {
451          this.label = (String JavaDoc)vb.getValue(getFacesContext());
452       }
453       
454       return this.label;
455    }
456
457    /**
458     * @param label The label to set.
459     */

460    public void setLabel(String JavaDoc label)
461    {
462       this.label = label;
463    }
464
465    /**
466     * @return Returns the progressive display setting.
467     */

468    public boolean isProgressive()
469    {
470       ValueBinding vb = getValueBinding("progressive");
471       if (vb != null)
472       {
473          this.progressive = (Boolean JavaDoc)vb.getValue(getFacesContext());
474       }
475       
476       if (this.progressive != null)
477       {
478          return this.progressive.booleanValue();
479       }
480       else
481       {
482          // return default
483
return false;
484       }
485    }
486    
487    /**
488     * @param progressive The progressive display boolean to set.
489     */

490    public void setProgressive(boolean progressive)
491    {
492       this.progressive = Boolean.valueOf(progressive);
493    }
494    
495    /**
496     * Returns whether the component show allow rendering of its child components.
497     */

498    public boolean isExpanded()
499    {
500       ValueBinding vb = getValueBinding("expanded");
501       if (vb != null)
502       {
503          this.expanded = (Boolean JavaDoc)vb.getValue(getFacesContext());
504       }
505       
506       if (this.expanded != null)
507       {
508          return this.expanded.booleanValue();
509       }
510       else
511       {
512          // return default
513
return true;
514       }
515    }
516    
517    /**
518     * Sets whether the component show allow rendering of its child components.
519     * For this component we change this value if the user indicates to change the
520     * hidden/visible state of the progressive panel.
521     */

522    public void setExpanded(boolean expanded)
523    {
524       this.expanded = Boolean.valueOf(expanded);
525    }
526    
527    /**
528     * Get the facets component Id to use
529     *
530     * @return the facets component Id
531     */

532    public String JavaDoc getFacetsId()
533    {
534       ValueBinding vb = getValueBinding("facets");
535       if (vb != null)
536       {
537          this.facetsId = (String JavaDoc)vb.getValue(getFacesContext());
538       }
539       
540       return this.facetsId;
541    }
542
543    /**
544     * Set the facets component Id to use
545     *
546     * @param facets the facets component Id
547     */

548    public void setFacetsId(String JavaDoc facets)
549    {
550       this.facetsId = facets;
551    }
552    
553    
554    // ------------------------------------------------------------------------------
555
// Private helpers
556

557    /**
558     * We use a hidden field name based on the parent form component Id and
559     * the string "panel" to give a hidden field name that can be shared by all panels
560     * within a single UIForm component.
561     *
562     * @return hidden field name
563     */

564    private String JavaDoc getHiddenFieldName()
565    {
566       UIForm form = Utils.getParentForm(getFacesContext(), this);
567       return form.getClientId(getFacesContext()) + NamingContainer.SEPARATOR_CHAR + "panel";
568    }
569    
570    
571    // ------------------------------------------------------------------------------
572
// Private members
573

574    // component settings
575
private String JavaDoc border = null;
576    private String JavaDoc bgcolor = null;
577    private String JavaDoc titleBorder = null;
578    private String JavaDoc titleBgcolor = null;
579    private Boolean JavaDoc progressive = null;
580    private String JavaDoc label = null;
581    private String JavaDoc facetsId = null;
582    private MethodBinding expandedActionListener = null;
583    
584    // component state
585
private boolean hasAdornments = false;
586    private boolean hasBorderedTitleArea = false;
587    private Boolean JavaDoc expanded = Boolean.TRUE;
588    
589    
590    // ------------------------------------------------------------------------------
591
// Inner classes
592

593    /**
594     * Class representing the an action relevant when the panel is expanded or collapsed.
595     */

596    public static class ExpandedEvent extends ActionEvent
597    {
598       public ExpandedEvent(UIComponent component, boolean state)
599       {
600          super(component);
601          State = state;
602       }
603       
604       public boolean State;
605    }
606 }
607
Popular Tags