KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > plaf > css > TreeCG


1 /*
2  * $Id: TreeCG.java,v 1.22 2005/06/07 12:55:59 neurolabs Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings.plaf.css;
15
16
17 import org.wings.*;
18 import org.wings.io.Device;
19 import org.wings.plaf.CGManager;
20 import org.wings.session.SessionManager;
21 import org.wings.tree.SDefaultTreeSelectionModel;
22 import org.wings.tree.STreeCellRenderer;
23
24 import javax.swing.tree.TreeModel JavaDoc;
25 import javax.swing.tree.TreePath JavaDoc;
26 import java.io.IOException JavaDoc;
27
28 public class TreeCG extends AbstractComponentCG implements
29         org.wings.plaf.TreeCG {
30     private SIcon collapseControlIcon;
31     private SIcon emptyFillIcon;
32     private SIcon expandControlIcon;
33     private SIcon hashMark;
34     private SIcon leafControlIcon;
35     
36     /**
37      * Initialize properties from config
38      */

39     public TreeCG() {
40         final CGManager manager = SessionManager.getSession().getCGManager();
41
42         setCollapseControlIcon((SIcon) manager.getObject("TreeCG.collapseControlIcon", SIcon.class));
43         setEmptyFillIcon((SIcon) manager.getObject("TreeCG.emptyFillIcon", SIcon.class));
44         setExpandControlIcon((SIcon) manager.getObject("TreeCG.expandControlIcon", SIcon.class));
45         setHashMark((SIcon) manager.getObject("TreeCG.hashMark", SIcon.class));
46         setLeafControlIcon((SIcon) manager.getObject("TreeCG.leafControlIcon", SIcon.class));
47     }
48
49
50     public void installCG(final SComponent comp) {
51         super.installCG(comp);
52         final STree component = (STree) comp;
53         final CGManager manager = component.getSession().getCGManager();
54         Object JavaDoc value;
55         value = manager.getObject("STree.cellRenderer", STreeCellRenderer.class);
56         if (value != null) {
57             component.setCellRenderer((STreeCellRenderer) value);
58         }
59         value = manager.getObject("STree.nodeIndentDepth", Integer JavaDoc.class);
60         if (value != null) {
61             component.setNodeIndentDepth(((Integer JavaDoc) value).intValue());
62         }
63     }
64
65 //--- code from common area in template.
66
private final boolean isLastChild(TreeModel JavaDoc model, TreePath JavaDoc path, int i) {
67         if (i == 0)
68             return true;
69         Object JavaDoc node = path.getPathComponent(i);
70         Object JavaDoc parent = path.getPathComponent(i - 1);
71         return node.equals(model.getChild(parent, model.getChildCount(parent) - 1));
72     }
73
74     private void writeIcon(Device device, SIcon icon, int width, int height) throws IOException JavaDoc {
75
76         device.print("<img");
77         Utils.optAttribute(device, "src", icon.getURL());
78         Utils.optAttribute(device, "width", icon.getIconWidth());
79         Utils.optAttribute(device, "height", icon.getIconHeight());
80         device.print(" alt=\"");
81         device.print(icon.getIconTitle());
82         device.print("\"/>");
83     }
84
85     private void writeIcon(Device device, SIcon icon, boolean nullBorder) throws IOException JavaDoc {
86         if (icon == null) return;
87
88         device.print("<img");
89         Utils.optAttribute(device, "src", icon.getURL());
90         Utils.optAttribute(device, "width", icon.getIconWidth());
91         Utils.optAttribute(device, "height", icon.getIconHeight());
92         device.print(" alt=\"");
93         device.print(icon.getIconTitle());
94         device.print("\"/>");
95     }
96
97     private void writeTreeNode(STree component, Device device, int row, int depth)
98             throws IOException JavaDoc {
99         boolean childSelectorWorkaround = !component.getSession().getUserAgent().supportsCssChildSelector();
100         final TreePath JavaDoc path = component.getPathForRow(row);
101
102         final Object JavaDoc node = path.getLastPathComponent();
103         final STreeCellRenderer cellRenderer = component.getCellRenderer();
104
105         final boolean isLeaf = component.getModel().isLeaf(node);
106         final boolean isExpanded = component.isExpanded(path);
107         final boolean isSelected = component.isPathSelected(path);
108
109         final boolean isSelectable = (component.getSelectionModel() != SDefaultTreeSelectionModel.NO_SELECTION_MODEL);
110
111         SComponent cellComp = cellRenderer.getTreeCellRendererComponent(component, node,
112                 isSelected,
113                 isExpanded,
114                 isLeaf, row,
115                 false);
116
117         /*
118          * now, write the component.
119          */

120         device.print("<li");
121
122         if (isSelected) {
123             device.print(" selected=\"true\"");
124             if (childSelectorWorkaround)
125                 Utils.optAttribute(device, "class", "selected");
126         }
127         device.print(">");
128
129         /*
130         * in most applications, the is no need to render a control icon for a
131         * leaf. So in that case, we can avoid writing the sourrounding
132         * table, that will speed up things in browsers.
133         */

134         final boolean renderControlIcon = !(isLeaf && leafControlIcon == null);
135
136         if (renderControlIcon) {
137             /*
138              * This table has to be here so that block level elements can be
139              * nodes. I just can't think around it. So it won...
140              */

141             device.print("<table border=\"0\" class=\"SLayout\"><tr><td class=\"SLayout\">");
142
143             if (isLeaf) {
144                 writeIcon(device, leafControlIcon, false);
145             } else {
146                 if (component.getShowAsFormComponent()) {
147                     writeButtonStart(component, device, component.getExpansionParameter(row, false));
148                     device.print(" type=\"submit\" name=\"");
149                     Utils.write(device, Utils.event(component));
150                     device.print("\" value=\"");
151                     Utils.write(device, component.getExpansionParameter(row, false));
152                     device.print("\"");
153                 } else {
154                     RequestURL selectionAddr = component.getRequestURL();
155                     selectionAddr.addParameter(Utils.event(component),
156                             component.getExpansionParameter(row, false));
157
158                     device.print("<a HREF=\"");
159                     Utils.write(device, selectionAddr.toString());
160                     device.print("\"");
161                 }
162                 device.print(">");
163
164                 if (isExpanded) {
165                     if (collapseControlIcon == null) {
166                         device.print("-");
167                     } else {
168                         writeIcon(device, collapseControlIcon, true);
169                     }
170                 } else {
171                     if (expandControlIcon == null) {
172                         device.print("+");
173                     } else {
174                         writeIcon(device, expandControlIcon, true);
175                     }
176                 }
177                 if (component.getShowAsFormComponent())
178                     device.print("</button>");
179                 else
180                     device.print("</a>");
181             }
182             /*
183              * closing layout td
184              */

185             device.print("</td><td class=\"SLayout\">");
186
187         }
188
189         SCellRendererPane rendererPane = component.getCellRendererPane();
190         if (isSelectable) {
191             if (component.getShowAsFormComponent()) {
192                 writeButtonStart(component, device, component.getSelectionParameter(row, false));
193                 device.print(" type=\"submit\" name=\"");
194                 Utils.write(device, Utils.event(component));
195                 device.print("\" value=\"");
196                 Utils.write(device, component.getSelectionParameter(row, false));
197                 device.print("\"");
198             } else {
199                 RequestURL selectionAddr = component.getRequestURL();
200                 selectionAddr.addParameter(Utils.event(component),
201                         component.getSelectionParameter(row, false));
202
203                 writeLinkStart(device, selectionAddr);
204             }
205
206             Utils.optAttribute(device, "tabindex", component.getFocusTraversalIndex());
207             Utils.writeEvents(device, component);
208             device.print(">");
209
210             rendererPane.writeComponent(device, cellComp, component);
211
212             if (component.getShowAsFormComponent())
213                 device.print("</button>");
214             else
215                 device.print("</a>");
216         } else {
217             rendererPane.writeComponent(device, cellComp, component);
218         }
219         
220         if (renderControlIcon) {
221             /*
222              * we have to close the table
223              */

224             device.print("</td></tr></table>\n");
225         }
226         
227
228         //handle the depth level of the tree
229
int nextPathCount = 1;
230         int pathCount = path.getPathCount();
231         TreePath JavaDoc nextPath = component.getPathForRow(row + 1);
232         // is there a next element? else use initialized level.
233
if (nextPath != null) {
234             nextPathCount = nextPath.getPathCount();
235         }
236         if ( pathCount < nextPathCount ) {
237             indentOnce(device, component, path);
238         } else if ( pathCount > nextPathCount ) {
239             device.print("</li>\n");
240             for (int i = nextPathCount; i < pathCount; i++) {
241                 device.print("</ul></div></li>\n");
242             }
243         } else if ( path.getPathCount() == nextPathCount ) {
244             device.print("</li>");
245         }
246     }
247
248
249     /**
250      * @param device
251      * @param selectionAddr
252      * @throws IOException
253      */

254     protected void writeLinkStart(Device device, RequestURL selectionAddr) throws IOException JavaDoc {
255         device.print("<a HREF=\"");
256         Utils.write(device, selectionAddr.toString());
257         device.print("\"");
258     }
259
260
261     protected void writeButtonStart(STree component, Device device, String JavaDoc value) throws IOException JavaDoc {
262         device.print("<button");
263     }
264
265
266     public void writeContent(final Device device, final SComponent _c)
267             throws IOException JavaDoc {
268         final STree component = (STree) _c;
269
270         int start = 0;
271         int count = component.getRowCount();
272
273         java.awt.Rectangle JavaDoc viewport = component.getViewportSize();
274         if (viewport != null) {
275             start = viewport.y;
276             count = viewport.height;
277         }
278
279         final int depth = component.getMaximumExpandedDepth();
280
281         device.print("<ul class=\"STree\"");
282         Utils.printCSSInlineFullSize(device, _c.getPreferredSize());
283         device.print(">");
284         if (start != 0) {
285             TreePath JavaDoc path = component.getPathForRow(start);
286             indentRecursive(device, component, path.getParentPath());
287         }
288
289         for (int i = start; i < start + count; ++i) {
290             writeTreeNode(component, device, i, depth);
291         }
292         device.print("</ul>");
293     }
294
295     /**
296      * Recursively indents the Tree in case it isn't displayed from the root
297      * node. reversely traverses the {@link TreePath} and renders afterwards.
298      * @param device
299      * @param component
300      * @param path
301      * @throws IOException
302      */

303     private void indentRecursive(Device device, STree component, TreePath JavaDoc path) throws IOException JavaDoc {
304         if (path == null) return;
305         indentRecursive(device, component, path.getParentPath());
306         device.print("<li>");
307         indentOnce(device, component, path);
308     }
309
310
311     /**
312      * Helper method for code reuse
313      */

314     private void indentOnce(Device device, STree component, TreePath JavaDoc path) throws IOException JavaDoc {
315         device.print("<div");
316         if (!isLastChild(component.getModel(), path, path.getPathCount()-1)) {
317             device.print(" class=\"SSubTree\"");
318         }
319         device.print("><ul class=\"STree\">\n");
320     }
321
322
323     //--- setters and getters for the properties.
324

325     public SIcon getCollapseControlIcon() {
326         return collapseControlIcon;
327     }
328
329     public void setCollapseControlIcon(SIcon collapseControlIcon) {
330         this.collapseControlIcon = collapseControlIcon;
331     }
332
333     public SIcon getEmptyFillIcon() {
334         return emptyFillIcon;
335     }
336
337     public void setEmptyFillIcon(SIcon emptyFillIcon) {
338         this.emptyFillIcon = emptyFillIcon;
339     }
340
341     public SIcon getExpandControlIcon() {
342         return expandControlIcon;
343     }
344
345     public void setExpandControlIcon(SIcon expandControlIcon) {
346         this.expandControlIcon = expandControlIcon;
347     }
348
349     public SIcon getHashMark() {
350         return hashMark;
351     }
352
353     public void setHashMark(SIcon hashMark) {
354         this.hashMark = hashMark;
355     }
356
357     public SIcon getLeafControlIcon() {
358         return leafControlIcon;
359     }
360
361     public void setLeafControlIcon(SIcon leafControlIcon) {
362         this.leafControlIcon = leafControlIcon;
363     }
364
365 }
366
Popular Tags