001: // WebOnSwing - Web Application Framework
002: //Copyright (C) 2003 Fernando Damian Petrola
003: //
004: //This library is free software; you can redistribute it and/or
005: //modify it under the terms of the GNU Lesser General Public
006: //License as published by the Free Software Foundation; either
007: //version 2.1 of the License, or (at your option) any later version.
008: //
009: //This library is distributed in the hope that it will be useful,
010: //but WITHOUT ANY WARRANTY; without even the implied warranty of
011: //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: //Lesser General Public License for more details.
013: //
014: //You should have received a copy of the GNU Lesser General Public
015: //License along with this library; if not, write to the Free Software
016: //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017:
018: package net.ar.webonswing.ui;
019:
020: import java.util.*;
021:
022: import javax.swing.*;
023: import javax.swing.tree.*;
024:
025: import net.ar.webonswing.*;
026: import net.ar.webonswing.helpers.*;
027: import net.ar.webonswing.managers.script.*;
028: import net.ar.webonswing.managers.templates.*;
029: import net.ar.webonswing.remote.*;
030: import net.ar.webonswing.render.markup.*;
031: import net.ar.webonswing.render.templates.*;
032: import net.ar.webonswing.render.templates.html.*;
033: import net.ar.webonswing.swing.components.*;
034: import net.ar.webonswing.swing.layouts.*;
035: import net.ar.webonswing.walkers.*;
036: import net.ar.webonswing.wrapping.*;
037: import net.ar.webonswing.wrapping.swing.*;
038:
039: import org.apache.commons.lang.*;
040:
041: public class TreeUIContributor extends
042: AbstractSwingComponentUIContributor {
043: protected String theTreeExpandValue;
044: protected StringBuffer theTreeCheckValue;
045: protected HtmlTemplate theTemplate;
046: protected TreeCellRenderer theTreeCellRenderer;
047: protected JTree theTree = null;
048: protected int theNodeCount;
049: protected RenderingContributionContainer theContribManager = null;
050: protected String theTreeName;
051: protected Map theCellCache;
052:
053: private StringBuffer theScript;
054:
055: public void doRenderingContribution(
056: RenderingContributionContainer aContribManager) {
057: init();
058:
059: theContribManager = aContribManager;
060:
061: JTree aTree = (JTree) getJComponent();
062:
063: theTreeName = theComponent.getName();
064:
065: theTemplate = (HtmlTemplate) WosSwingHelper
066: .getTemplateForComponent("JTree", aTree);
067:
068: TreeNode theRootNode = (TreeNode) theTree.getModel().getRoot();
069: theTreeCellRenderer = theTree.getCellRenderer();
070:
071: String theResult = renderTreeNode(theRootNode, theScript);
072: String theFinalScript = theScript.toString() + ";"
073: + RemoteHelper.getListenersAdds(theComponent);
074: theContribManager.doContribution(theComponent, new TextContent(
075: theResult), null, theFinalScript);
076: }
077:
078: protected void init() {
079: theScript = new StringBuffer();
080: theNodeCount = 0;
081: theTreeCheckValue = new StringBuffer();
082: theTreeExpandValue = "";
083: theCellCache = Collections.synchronizedMap(new HashMap());
084: }
085:
086: public void setComponent(VisualComponent aComponent) {
087: super .setComponent(aComponent);
088: theTree = (JTree) getJComponent();
089:
090: if (!(theTree.getLayout() instanceof TemplateLayout)) {
091: theTree.setLayout(WosFramework
092: .getTemplateLayoutForName("TreeDemo.JTree"));
093: //theTree.setCellRenderer(new TreeDemoWindow.CheckRenderer());
094: }
095: }
096:
097: private String renderTreeNode(TreeNode aTreeNode,
098: StringBuffer theNodeScript) {
099: if (aTreeNode instanceof CheckNode)
100: theTreeCheckValue.append(((CheckNode) aTreeNode)
101: .isSelected() ? "1" : "0");
102:
103: String theNodeNumber = new Integer(theNodeCount++).toString();
104: String theRowName = theTreeName + ".row." + theNodeNumber;
105: boolean isRootNode = theTree.getModel().getRoot() == aTreeNode;
106: String theNodeName = isRootNode ? theTreeName : theRowName;
107:
108: theNodeScript.append("new JTree"
109: + (aTreeNode.isLeaf() ? "Leaf" : "") + "('"
110: + theNodeName + "')");
111:
112: String theNodeType = isRootNode ? "theRootNode" : aTreeNode
113: .isLeaf() ? "theLeafNode" : "theCollapsedNode";
114: HtmlTemplate theNodeTemplate = HtmlTemplateManager
115: .getClonedSubTemplate(theTemplate, theNodeType);
116: HtmlTemplate theNextItemTemplate = HtmlTemplateManager
117: .getClonedSubTemplate(theTemplate,
118: "theRootNode.theNextItem");
119:
120: StringBuffer theResult = new StringBuffer();
121: for (int i = 0; i < aTreeNode.getChildCount(); i++) {
122: TreeNode theChild = aTreeNode.getChildAt(i);
123: StringBuffer theChildScript = new StringBuffer();
124:
125: theResult.append(renderTreeNode(theChild, theChildScript));
126: theNodeScript.append(".add (" + theChildScript.toString()
127: + ")");
128: }
129:
130: String theCellResult = getCells(aTreeNode, theRowName,
131: isRootNode);
132:
133: theNodeTemplate.addIdTagTemplateElement("theTreeCell",
134: new TextContent(theCellResult));
135:
136: if (!aTreeNode.isLeaf()) {
137: HtmlTemplate theExpandablePartTemplate = HtmlTemplateManager
138: .getSubTemplate(theNodeTemplate,
139: "theNextItem.theExpandablePart");
140: theExpandablePartTemplate.addIdTagTemplateElement(
141: "theContent", new TextContent(theResult));
142: theExpandablePartTemplate.mergeFoundTagKeepingName(new Tag(
143: "span").addAttribute("id", theRowName
144: + ".expandable"));
145: }
146: if (isRootNode) {
147: theNodeTemplate
148: .getSubTemplate("theLastRowClicked")
149: .mergeFoundTag(
150: new Tag("input")
151: .addAttribute(
152: "name",
153: theTreeName
154: + ".lastRowClicked")
155: .addAttribute(
156: "value",
157: theTree.getSelectionCount() > 0 ? theTree
158: .getSelectionRows()[0]
159: : 0));
160: theNodeTemplate.getSubTemplate("theTreeState")
161: .mergeFoundTag(
162: new Tag("input").addAttribute("name",
163: theTreeName + ".checkValue")
164: .addAttribute(
165: "value",
166: theTreeCheckValue
167: .toString()));
168: theTreeExpandValue = (String) theTree
169: .getClientProperty("theTreeExpandValue");
170: if (theTreeExpandValue == null)
171: theTreeExpandValue = StringUtils.repeat("0",
172: theNodeCount);
173: theNodeTemplate.getSubTemplate("theTreeExpandState")
174: .mergeFoundTag(
175: new Tag("input").addAttribute("name",
176: theTreeName + ".expandValue")
177: .addAttribute("value",
178: theTreeExpandValue));
179: }
180:
181: theNodeTemplate.mergeFoundTagKeepingName(new Tag("span")
182: .addAttribute("id", theNodeName));
183: theNextItemTemplate.addIdTagTemplateElement(
184: "theExpandablePart", theNodeTemplate);
185:
186: return theNextItemTemplate.renderToText();
187: }
188:
189: private String getCells(TreeNode aTreeNode, String theRowName,
190: boolean isRootNode) {
191: boolean isSelected = theTree.getSelectionPath() != null
192: && theTree.getSelectionPath().getLastPathComponent() == aTreeNode;
193: String theCellText = aTreeNode.toString();
194: String theHashValue = new Boolean(isRootNode).toString()
195: + new Boolean(isSelected).toString()
196: + new Boolean(aTreeNode.isLeaf()).toString();
197:
198: String theCachedCell = (String) theCellCache.get(theHashValue);
199: if (theCachedCell == null) {
200: ((MutableTreeNode) aTreeNode).setUserObject("theCellText");
201: theCellCache.put(theHashValue, theCachedCell = createCells(
202: aTreeNode, "theRowName", isRootNode));
203: ((MutableTreeNode) aTreeNode).setUserObject(theCellText);
204: }
205:
206: theCachedCell = StringUtils.replace(theCachedCell,
207: "theCellText", theCellText);
208: theCachedCell = StringUtils.replace(theCachedCell,
209: "theRowName", theRowName);
210:
211: return theCachedCell.toString();
212: }
213:
214: private String createCells(TreeNode aTreeNode, String theRowName,
215: boolean isRootNode) {
216: boolean isSelected = theTree.getSelectionPath() != null
217: && theTree.getSelectionPath().getLastPathComponent() == aTreeNode;
218:
219: StringBuffer theCellResult = new StringBuffer();
220:
221: VisualComponent theTreeRendererComponent = new ComponentStandardizer()
222: .standardizeChildsComponentHierarchy(new SwingComponentWrapper(
223: (JComponent) theTreeCellRenderer
224: .getTreeCellRendererComponent(theTree,
225: aTreeNode, isSelected, false,
226: aTreeNode.isLeaf(), 1, false)));
227:
228: HtmlTemplate theCollapsedCellTemplate = HtmlTemplateManager
229: .getClonedSubTemplate(theTemplate,
230: "theCollapsedNode.theTreeCell");
231: theCollapsedCellTemplate.addIdTagTemplateElement("theContent",
232: theContribManager.getContainerRenderer().render(
233: theTreeRendererComponent));
234: theCollapsedCellTemplate.mergeFoundTagKeepingName(new Tag(
235: "span").addAttribute("id", theRowName
236: + (aTreeNode.isLeaf() ? "" : ".collapsed")));
237: theCellResult.append(theCollapsedCellTemplate.renderToText());
238:
239: if (!aTreeNode.isLeaf() && !isRootNode) {
240: VisualComponent theTreeRendererComponentExpanded = new ComponentStandardizer()
241: .standardizeChildsComponentHierarchy(new SwingComponentWrapper(
242: (JComponent) theTreeCellRenderer
243: .getTreeCellRendererComponent(
244: theTree, aTreeNode,
245: isSelected, true, aTreeNode
246: .isLeaf(), 1, false)));
247:
248: HtmlTemplate theExpandedCellTemplate = HtmlTemplateManager
249: .getClonedSubTemplate(theTemplate,
250: "theExpandedNode.theTreeCell");
251: theExpandedCellTemplate.addIdTagTemplateElement(
252: "theContent", theContribManager
253: .getContainerRenderer().render(
254: theTreeRendererComponentExpanded));
255: theExpandedCellTemplate.mergeFoundTagKeepingName(new Tag(
256: "span")
257: .addAttribute("id", theRowName + ".expanded"));
258: theCellResult
259: .append(theExpandedCellTemplate.renderToText());
260: }
261:
262: return theCellResult.toString();
263: }
264:
265: public void dispatchEvents(List anEvents) {
266: for (Iterator i = anEvents.iterator(); i.hasNext();) {
267: RemoteEvent theEvent = (RemoteEvent) i.next();
268: JTree theSourceTree = (JTree) ((ComponentWrapper) theEvent
269: .getSource()).getWrappedComponent();
270:
271: if (theEvent.getName().endsWith("lastRowClicked")) {
272: expandAll(theSourceTree, true);
273: theSourceTree.setSelectionRow(new Integer(
274: (String) theEvent.getParameters()[0])
275: .intValue());
276: } else if (theEvent.getName().endsWith("checkValue")) {
277: theTreeCheckValue = new StringBuffer((String) theEvent
278: .getParameters()[0]);
279: theNodeCount = 0;
280:
281: setCheckState((TreeNode) theSourceTree.getModel()
282: .getRoot());
283: } else if (theEvent.getName().endsWith("expandValue")) {
284: theTreeExpandValue = (String) theEvent.getParameters()[0];
285: theSourceTree.putClientProperty("theTreeExpandValue",
286: theTreeExpandValue);
287: }
288: }
289: }
290:
291: public void expandAll(JTree aTree, boolean expand) {
292: TreeNode root = (TreeNode) aTree.getModel().getRoot();
293: expandAll(aTree, new TreePath(root), expand);
294: }
295:
296: private void expandAll(JTree aTree, TreePath parent, boolean expand) {
297: TreeNode node = (TreeNode) parent.getLastPathComponent();
298: if (node.getChildCount() >= 0) {
299: for (Enumeration e = node.children(); e.hasMoreElements();) {
300: TreeNode n = (TreeNode) e.nextElement();
301: TreePath path = parent.pathByAddingChild(n);
302: expandAll(aTree, path, expand);
303: }
304: }
305:
306: if (expand)
307: aTree.expandPath(parent);
308: else
309: aTree.collapsePath(parent);
310: }
311:
312: public void setCheckState(TreeNode aTreeNode) {
313: if (theNodeCount < theTreeCheckValue.length()) {
314: CheckNode theTreeNode = (CheckNode) aTreeNode;
315: theTreeNode.setSelected(theTreeCheckValue
316: .charAt(theNodeCount) == '1');
317: theNodeCount++;
318:
319: for (int i = 0; i < aTreeNode.getChildCount(); i++) {
320: TreeNode theChild = aTreeNode.getChildAt(i);
321: setCheckState(theChild);
322: }
323: }
324: }
325:
326: public VisitableContainer getContainerVisitable() {
327: return new NullContainerVisitable();
328: }
329:
330: public void doScriptContribution(
331: ScriptContributionContainer aContributionManager) {
332: aContributionManager.addInclude(WosFramework.getInstance()
333: .getCompleteResourcePath()
334: + "/js/JTree.js");
335: }
336: }
|