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

Quick Search    Search Deep

Source code: nextapp/echoservlet/ui/TriCellTable.java


1   /* 
2    * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3    * Copyright (C) 2002-2004 NextApp, Inc.
4    *
5    * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6    *
7    * The contents of this file are subject to the Mozilla Public License Version
8    * 1.1 (the "License"); you may not use this file except in compliance with
9    * the License. You may obtain a copy of the License at
10   * http://www.mozilla.org/MPL/
11   *
12   * Software distributed under the License is distributed on an "AS IS" basis,
13   * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14   * for the specific language governing rights and limitations under the
15   * License.
16   *
17   * Alternatively, the contents of this file may be used under the terms of
18   * either the GNU General Public License Version 2 or later (the "GPL"), or
19   * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20   * in which case the provisions of the GPL or the LGPL are applicable instead
21   * of those above. If you wish to allow use of your version of this file only
22   * under the terms of either the GPL or the LGPL, and not to allow others to
23   * use your version of this file under the terms of the MPL, indicate your
24   * decision by deleting the provisions above and replace them with the notice
25   * and other provisions required by the GPL or the LGPL. If you do not delete
26   * the provisions above, a recipient may use your version of this file under
27   * the terms of any one of the MPL, the GPL or the LGPL.
28   */
29  
30  package nextapp.echoservlet.ui;
31  
32  import nextapp.echo.EchoConstants;
33  
34  import nextapp.echoservlet.Connection;
35  import nextapp.echoservlet.LayoutStrut;
36  import nextapp.echoservlet.html.Element;
37  import nextapp.echoservlet.html.ElementNames;
38  
39  /**
40   * Renders an HTML table that has two or three "container" cells and
41   * independently settable margins between them.  These tables are useful for
42   * rendering buttons that have two or three elements (images, text labels, and 
43   * state indicators).  This class supports all possible permutations for
44   * placement of each of the two or three contained components.
45   */
46  class TriCellTable extends Element {
47  
48      static final int INVERTED = 1;
49      static final int VERTICAL = 2;
50      
51      static final int LEFT_RIGHT = 0;
52      static final int RIGHT_LEFT = INVERTED;
53      static final int TOP_BOTTOM = VERTICAL;
54      static final int BOTTOM_TOP = INVERTED | VERTICAL;
55      
56      /**
57       * Translates horizontal and vertical orientation constants from the
58       * <code>nextapp.echo.EchoContstants</code> class into the constants
59       * used by <code>TriCellTable</code>:
60       * <ul>
61       * <li>LEFT_RIGHT</li>
62       * <li>RIGHT_LEFT</li>
63       * <li>TOP_BOTTOM</li>
64       * <li>BOTTOM_TOP</li>
65       * </ul>
66       * @param horizontalOrientation The horizontal orientation desired, one of
67       *        the following values:
68       *        <ul>
69       *        <li>EchoConstants.LEFT</li>
70       *        <li>EchoConstants.CENTER</li>
71       *        <li>EchoConstants.RIGHT</li>
72       *        </ul>
73       * @param verticalOrientation The vertical orientation desired, one of the
74       *        following values:
75       *        <ul>
76       *        <li>EchoConstants.TOP</li>
77       *        <li>EchoConstants.CENTER</li>
78       *        <li>EchoConstants.BOTTOM</li>
79       *        </ul>
80       * @return Am orientation constant from <code>TriCellTable</code> that 
81       *         equates to the orientation parameters provided.
82       */
83      static int getOrientation(int horizontalOrientation, int verticalOrientation) {
84          int tctOrientation;
85      
86          switch (verticalOrientation) {
87          case EchoConstants.TOP:
88              tctOrientation = TriCellTable.TOP_BOTTOM;
89              break;
90          case EchoConstants.BOTTOM:
91              tctOrientation = TriCellTable.BOTTOM_TOP;
92              break;
93          default:
94              if (horizontalOrientation == EchoConstants.LEFT) {
95                  tctOrientation = TriCellTable.LEFT_RIGHT;
96              } else {
97                  tctOrientation = TriCellTable.RIGHT_LEFT;
98              }
99              break;
100         }
101         
102         return tctOrientation;
103     }
104 
105     private Element[] tds;
106     private Element[] marginTds = null;
107     
108     /**
109      * This constructor is called by the non-private constructors to set up 
110      * common properties.
111      */
112     private TriCellTable() {
113         super(ElementNames.TABLE);
114 
115         addAttribute("border", 0);
116         addAttribute("cellpadding", 0);
117         addAttribute("cellspacing", 0);
118     }
119 
120     /**
121      * Creates a two-celled <code>TriCellTable</code>.
122      * 
123      * @param conn The connection which is to render the underlying button 
124      *        object.
125      * @param orientation0_1 The orientation of Element 0 with respect to 
126      *        Element 1, one of the following values:
127      *        <ul>
128      *        <li>LEFT_RIGHT (element 0 is to the left of element 1)</li>
129      *        <li>RIGHT_LEFT (element 1 is to the left of element 0)</li>
130      *        <li>TOP_BOTTOM (element 0 is above element 1)</li>
131      *        <li>BOTTOM_TOP (element 1 is above element 0)</li>
132      *        </ul>
133      * @param margin0_1 The margin size (in pixels) between element 0 and
134      *        element 1.
135      */
136     TriCellTable(Connection conn, int orientation0_1, int margin0_1) {
137         this();
138         
139         marginTds = new Element[1];
140         tds = new Element[2];
141         tds[0] = new Element(ElementNames.TD);
142         tds[0].setWhitespaceRelevant(true);
143         tds[1] = new Element(ElementNames.TD);
144         tds[1].setWhitespaceRelevant(true);
145         
146         if (margin0_1 > 0) {
147             marginTds[0] = new Element(ElementNames.TD);
148             marginTds[0].setWhitespaceRelevant(true);
149             if ((orientation0_1 & VERTICAL) == 0) {
150                 marginTds[0].add(LayoutStrut.createElement(conn, margin0_1, 1));
151             } else {
152                 marginTds[0].add(LayoutStrut.createElement(conn, 1, margin0_1));
153             }
154         }
155                 
156         if ((orientation0_1 & VERTICAL) == 0) {
157             // horizontally oriented
158             Element tr = new Element(ElementNames.TR);
159             if ((orientation0_1 & INVERTED) == 0) {
160                 // normal (left to right)
161                 addColumn(tr, tds[0]);
162                 addColumn(tr, marginTds[0]);
163                 addColumn(tr, tds[1]);
164             } else {
165                 // inverted (right to left)
166                 addColumn(tr, tds[1]);
167                 addColumn(tr, marginTds[0]);
168                 addColumn(tr, tds[0]);
169             }
170             add(tr);
171         } else {
172             // vertically oriented
173             if ((orientation0_1 & INVERTED) == 0) {
174                 // normal (top to bottom)
175                 addRow(tds[0]);
176                 addRow(marginTds[0]);
177                 addRow(tds[1]);
178             } else {
179                 // inverted (bottom to top)
180                 addRow(tds[1]);
181                 addRow(marginTds[0]);
182                 addRow(tds[0]);
183             }
184         }
185     }
186     
187     /**
188      * Creates a three-celled <code>TriCellTable</code>.
189      * 
190      * @param conn The connection which is to render the underlying button 
191      *        object.
192      * @param orientation0_1 The orientation of Element 0 with respect to 
193      *        Element 1, one of the following values:
194      *        <ul>
195      *        <li>LEFT_RIGHT (element 0 is to the left of element 1)</li>
196      *        <li>RIGHT_LEFT (element 1 is to the left of element 0)</li>
197      *        <li>TOP_BOTTOM (element 0 is above element 1)</li>
198      *        <li>BOTTOM_TOP (element 1 is above element 0)</li>
199      *        </ul>
200      * @param margin0_1 The margin size (in pixels) between element 0 and
201      *        element 1.
202      * @param orientation01_2 The orientation of Elements 0 and 1 with 
203      *        respect to Element 2, one of the following values:
204      *        <ul>
205      *        <li>LEFT_RIGHT (elements 0 and 1 are to the left of 
206      *        element 1)</li>
207      *        <li>RIGHT_LEFT (element 2 is to the left of elements 0 and 1)</li>
208      *        <li>TOP_BOTTOM (elements 0 and 1 are above element 2)</li>
209      *        <li>BOTTOM_TOP (element 2 is above elements 0 and 1)</li>
210      *        </ul>
211      * @param margin01_2 The margin size (in pixels) between the combination
212      *        of elements 0 and 1 and element 2.
213      *        element 1.
214      */
215     TriCellTable(Connection conn, int orientation0_1, int margin0_1, int orientation01_2, int margin01_2) {
216         this();
217         
218         Element tr;
219         
220         marginTds = new Element[2];
221         tds = new Element[3];
222         tds[0] = new Element(ElementNames.TD);
223         tds[0].setWhitespaceRelevant(true);
224         tds[1] = new Element(ElementNames.TD);
225         tds[1].setWhitespaceRelevant(true);
226         tds[2] = new Element(ElementNames.TD);
227         tds[2].setWhitespaceRelevant(true);
228 
229         // Create margin cells
230         if (margin0_1 > 0 || margin01_2 > 0) {
231             if (margin0_1 > 0) {
232                 marginTds[0] = new Element(ElementNames.TD);
233                 marginTds[0].setWhitespaceRelevant(true);
234                 if ((orientation0_1 & VERTICAL) == 0) {
235                     marginTds[0].add(LayoutStrut.createElement(conn, margin0_1, 1));
236                 } else {
237                     marginTds[0].add(LayoutStrut.createElement(conn, 1, margin0_1));
238                 }
239             }
240             if (margin01_2 > 0) {
241                 marginTds[1] = new Element(ElementNames.TD);
242                 marginTds[1].setWhitespaceRelevant(true);
243                 if ((orientation01_2 & VERTICAL) == 0) {
244                     marginTds[1].add(LayoutStrut.createElement(conn, margin01_2, 1));
245                 } else {
246                     marginTds[1].add(LayoutStrut.createElement(conn, 1, margin01_2));
247                 }
248             }
249         }
250         
251         if ((orientation0_1 & VERTICAL) == 0) {
252             // horizontally oriented 0/1
253             if ((orientation01_2 & VERTICAL) == 0) {
254                 // horizontally orientated 01/2
255                 tr = new Element(ElementNames.TR);
256                 if ((orientation01_2 & INVERTED) != 0) {
257                     // 2 before 01: render #2 and margin at beginning of TR.
258                     addColumn(tr, tds[2]);
259                     addColumn(tr, marginTds[1]);
260                 }
261                 
262                 // Render 01
263                 if ((orientation0_1 & INVERTED) == 0) {
264                     // normal (left to right)
265                     addColumn(tr, tds[0]);
266                     addColumn(tr, marginTds[0]);
267                     addColumn(tr, tds[1]);
268                 } else {
269                     // inverted (right to left)
270                     addColumn(tr, tds[1]);
271                     addColumn(tr, marginTds[0]);
272                     addColumn(tr, tds[0]);
273                 }
274                 
275                 if ((orientation01_2 & INVERTED) == 0) {
276                     addColumn(tr, marginTds[1]);
277                     addColumn(tr, tds[2]);
278                 }
279                 
280                 add(tr);
281             } else {
282                 // vertically oriented 01/2
283 
284                 // determine and apply column span based on presence of margin between 0 and 1
285                 int columns = margin0_1 > 0 ? 3 : 2;
286                 tds[2].addAttribute("colspan", columns);
287                 if (marginTds[1] != null) {
288                     marginTds[1].addAttribute("colspan", columns);
289                 }
290                 
291                 if ((orientation01_2 & INVERTED) != 0) {
292                     // 2 before 01: render #2 and margin at beginning of TR.
293                     addRow(tds[2]);
294                     addRow(marginTds[1]);
295                 }
296                 
297                 // Render 01
298                 tr = new Element(ElementNames.TR);
299                 if ((orientation0_1 & INVERTED) == 0) {
300                     // normal (left to right)
301                     addColumn(tr, tds[0]);
302                     addColumn(tr, marginTds[0]);
303                     addColumn(tr, tds[1]);
304                 } else {
305                     // inverted (right to left)
306                     addColumn(tr, tds[1]);
307                     addColumn(tr, marginTds[0]);
308                     addColumn(tr, tds[0]);
309                 }
310                 add(tr);
311                 
312                 if ((orientation01_2 & INVERTED) == 0) {
313                     // 01 before 2: render margin and #2 at end of TR.
314                     addRow(marginTds[1]);
315                     addRow(tds[2]);
316                 }
317             }
318         } else {
319             // vertically oriented 0/1
320             if ((orientation01_2 & VERTICAL) == 0) {
321                 // horizontally orientated 01/2
322 
323                 // determine and apply row span based on presence of margin between 0 and 1
324                 int rows = margin0_1 > 0 ? 3 : 2;
325                 tds[2].addAttribute("rowspan", rows);
326                 if (marginTds[1] != null) {
327                     marginTds[1].addAttribute("rowspan", rows);
328                 }
329                 
330                 tr = new Element(ElementNames.TR);
331                 if ((orientation01_2 & INVERTED) != 0) {
332                     addColumn(tr, tds[2]);
333                     addColumn(tr, marginTds[1]);
334                     if ((orientation0_1 & INVERTED) == 0) {
335                         addColumn(tr, tds[0]);
336                     } else {
337                         addColumn(tr, tds[1]);
338                     }
339                 } else {
340                     if ((orientation0_1 & INVERTED) == 0) {
341                         addColumn(tr, tds[0]);
342                     } else {
343                         addColumn(tr, tds[1]);
344                     }
345                     addColumn(tr, marginTds[1]);
346                     addColumn(tr, tds[2]);
347                 }
348                 add(tr);
349                 addRow(marginTds[0]);
350                 if ((orientation0_1 & INVERTED) == 0) {
351                     addRow(tds[1]);
352                 } else {
353                     addRow(tds[0]);
354                 }
355             } else {
356                 // vertically oriented 01/2
357                 if ((orientation01_2 & INVERTED) != 0) {
358                     // 2 before 01: render #2 and margin at beginning of TABLE.
359                     addRow(tds[2]);
360                     addRow(marginTds[1]);
361                 }
362                 
363                 // Render 01
364                 if ((orientation0_1 & INVERTED) == 0) {
365                     // normal (top to bottom)
366                     addRow(tds[0]);
367                     addRow(marginTds[0]);
368                     addRow(tds[1]);
369                 } else {
370                     // inverted (bottom to top)
371                     addRow(tds[1]);
372                     addRow(marginTds[0]);
373                     addRow(tds[0]);
374                 }
375                 
376                 if ((orientation01_2 & INVERTED) == 0) {
377                     // 01 before 2: render margin and #2 at end of TABLE.
378                     addRow(marginTds[1]);
379                     addRow(tds[2]);
380                 }
381             }
382         }
383     }
384     
385     /**
386      * Adds an cell element to a table row.  The element will not be added
387      * if null is provided for the value of <code>td</code>.
388      * 
389      * @param tr The table row to which the cell element is to be added.
390      * @param td The cell element to be added (if not null).
391      */
392     private void addColumn(Element tr, Element td) {
393         if (td != null) {
394             tr.add(td);
395         }
396     }
397     
398     /**
399      * Adds an attribute to every table cell in the rendered table.
400      *
401      * @param name The name of the attribute.
402      * @param value The value of the attribute.
403      */
404     public void addGlobalAttribute(String name, String value) {
405         for (int index = 0; index < tds.length; ++index) {
406             tds[index].addAttribute(name, value);
407         }
408         if (marginTds != null) {
409             for (int index = 0; index < marginTds.length; ++index) {
410                 if (marginTds[index] != null) {
411                     marginTds[index].addAttribute(name, value);
412                 }
413             }
414         }
415     }
416     
417     /**
418      * Adds a row containing a single column element to a table.
419      * The row will not be added if <code>td</code> is null.
420      *
421      * @param td The cell element to be added.
422      */
423     private void addRow(Element td) {
424         if (td != null) {
425             Element tr = new Element(ElementNames.TR);
426             tr.add(td);
427             add(tr);
428         }
429     }
430     
431     /**
432      * Returns the specified container element.
433      *
434      * @param index The index of the table element to return.  For two-celled tables,
435      *        legitimate values are 0 and 1.  For three-celled tables, 
436      *        legitimate values are 0, 1, and 2.
437      * @return The specified container element.
438      */
439     Element getTdElement(int index) {
440         return tds[index];
441     }
442     
443     /**
444      * Returns the specified margin element.
445      *
446      * @param index The index of the table element to return.  Index 0 is the margin
447      *        element between container cells 0 and 1.  Index 1 is the margin
448      *        element between container cells 0/1 and 2.
449      * @return The specified margin element.  Returns null if the margin is zero
450      *         pixels.
451      */
452     Element getMarginTdElement(int index) {
453         return marginTds[index];
454     }
455 }