001: /*
002: ItsNat Java Web Application Framework
003: Copyright (C) 2007 Innowhere Software Services S.L., Spanish Company
004: Author: Jose Maria Arranz Santamaria
005:
006: This program is free software: you can redistribute it and/or modify
007: it under the terms of the GNU Affero General Public License as published by
008: the Free Software Foundation, either version 3 of the License, or
009: (at your option) any later version. See the GNU Affero General Public
010: License for more details. See the copy of the GNU Affero General Public License
011: included in this program. If not, see <http://www.gnu.org/licenses/>.
012: */
013:
014: package org.itsnat.impl.comp.ui;
015:
016: import org.itsnat.core.ItsNatException;
017: import org.itsnat.core.domutil.ElementTreeNode;
018: import org.itsnat.comp.ui.ItsNatTreeCellUI;
019: import org.itsnat.impl.comp.DefaultRowMapperImpl;
020: import javax.swing.tree.RowMapper;
021: import javax.swing.tree.TreeModel;
022: import javax.swing.tree.TreePath;
023: import org.itsnat.comp.ItsNatTree;
024: import org.itsnat.comp.ItsNatTreeCellRenderer;
025: import org.itsnat.comp.ItsNatTreeStructure;
026: import org.itsnat.comp.ui.ItsNatTreeUI;
027: import org.itsnat.core.domutil.ElementTreeNodeList;
028: import org.itsnat.impl.comp.ItsNatTreeImpl;
029: import org.itsnat.impl.core.ItsNatDocumentImpl;
030: import org.itsnat.impl.core.domutil.ElementTreeNodeImpl;
031: import org.itsnat.impl.core.domutil.ElementTreeNodeListImpl;
032: import org.itsnat.impl.core.domutil.ElementTreeVersatileImpl;
033: import org.w3c.dom.Element;
034: import org.w3c.dom.Node;
035:
036: /**
037: *
038: * @author jmarranz
039: */
040: public class ItsNatTreeUIImpl extends ItsNatElementComponentUIImpl
041: implements ItsNatTreeUI {
042: protected boolean enabled = true;
043: protected ElementTreeVersatileImpl elementTree;
044:
045: /**
046: * Creates a new instance of ItsNatTreeUIImpl
047: */
048: public ItsNatTreeUIImpl(ItsNatTreeImpl parentComp) {
049: super (parentComp);
050:
051: Element parentElement = getElement();
052:
053: ItsNatTreeStructure structure = parentComp
054: .getItsNatTreeStructure();
055: ItsNatTreeStructureCoreAdapterImpl structAdapter;
056: structAdapter = new ItsNatTreeStructureCoreAdapterImpl(
057: structure, this );
058:
059: ItsNatDocumentImpl itsNatDoc = getItsNatDocumentImpl();
060: this .elementTree = itsNatDoc
061: .createElementTreeVersatileInternal(parentComp
062: .isRootless(), parentComp.isTreeTable(),
063: parentElement, true, structAdapter, null);
064: }
065:
066: public ItsNatTree getItsNatTree() {
067: return (ItsNatTree) parentComp;
068: }
069:
070: public ItsNatTreeImpl getItsNatTreeImpl() {
071: return (ItsNatTreeImpl) parentComp;
072: }
073:
074: public RowMapper getRowMapper() {
075: return getItsNatTree().getRowMapper();
076: }
077:
078: public DefaultRowMapperImpl getDefaultRowMapper() {
079: return getItsNatTreeImpl().getDefaultRowMapper();
080: }
081:
082: public boolean isRootless() {
083: return elementTree.isRootless();
084: }
085:
086: public ItsNatTreeCellRenderer getItsNatTreeCellRenderer() {
087: return getItsNatTree().getItsNatTreeCellRenderer();
088: }
089:
090: public int logicToMarkupRow(int row) {
091: // Método no público
092: if (isRootless())
093: row--; // Porque el root es el 0 pero como no tiene markup la row del markup es una menor
094: return row;
095: }
096:
097: public int markupToLogicRow(int row) {
098: // Método no público
099: if (isRootless())
100: row++; // Porque el root es el 0 pero como no tiene markup la row del markup es una menor
101: return row;
102: }
103:
104: /*
105: public boolean isEmpty()
106: {
107: return elementTree.getChildTreeNodeList().isEmpty();
108: }
109:
110: public int getSize()
111: {
112: return elementTree.getChildTreeNodeList().getSize();
113: }
114: */
115: public int getChildCount(ElementTreeNodeImpl treeNode) {
116: return treeNode.getChildTreeNodeList().getLength();
117: }
118:
119: public ItsNatTreeCellUI getChildItsNatTreeCellUIAt(int index,
120: ElementTreeNodeImpl treeNode) {
121: ElementTreeNodeImpl childTreeNode = (ElementTreeNodeImpl) treeNode
122: .getChildTreeNodeList().getTreeNodeAt(index);
123: return getItsNatTreeCellUI(childTreeNode);
124: }
125:
126: public Element getParentElementFromRow(int row) {
127: ElementTreeNodeImpl treeNode = getElementTreeNodeFromRow(row);
128: if (treeNode == null)
129: return null;
130: return treeNode.getParentElement();
131: }
132:
133: public Element getContentElement(ElementTreeNodeImpl treeNode) {
134: ItsNatTree tree = getItsNatTree();
135: ItsNatTreeStructure structure = tree.getItsNatTreeStructure();
136: return structure.getContentElement(tree, getRow(treeNode),
137: treeNode.getParentElement());
138: }
139:
140: public Element getHandleElement(ElementTreeNodeImpl treeNode) {
141: ItsNatTree tree = getItsNatTree();
142: ItsNatTreeStructure structure = tree.getItsNatTreeStructure();
143: return structure.getHandleElement(tree, getRow(treeNode),
144: treeNode.getParentElement());
145: }
146:
147: public Element getIconElement(ElementTreeNodeImpl treeNode) {
148: ItsNatTree tree = getItsNatTree();
149: ItsNatTreeStructure structure = tree.getItsNatTreeStructure();
150: return structure.getIconElement(tree, getRow(treeNode),
151: treeNode.getParentElement());
152: }
153:
154: public Element getLabelElement(ElementTreeNodeImpl treeNode) {
155: ItsNatTree tree = getItsNatTree();
156: ItsNatTreeStructure structure = tree.getItsNatTreeStructure();
157: return structure.getLabelElement(tree, getRow(treeNode),
158: treeNode.getParentElement());
159: }
160:
161: public Element getContentElementFromRow(int row) {
162: ElementTreeNodeImpl treeNode = getElementTreeNodeFromRow(row);
163: if (treeNode == null)
164: return null;
165: return getContentElement(treeNode);
166: }
167:
168: public Element getHandleElementFromRow(int row) {
169: ElementTreeNodeImpl treeNode = getElementTreeNodeFromRow(row);
170: if (treeNode == null)
171: return null;
172: return getHandleElement(treeNode);
173: }
174:
175: public Element getIconElementFromRow(int row) {
176: ElementTreeNodeImpl treeNode = getElementTreeNodeFromRow(row);
177: if (treeNode == null)
178: return null;
179: return getIconElement(treeNode);
180: }
181:
182: public Element getLabelElementFromRow(int row) {
183: ElementTreeNodeImpl treeNode = getElementTreeNodeFromRow(row);
184: if (treeNode == null)
185: return null;
186: return getLabelElement(treeNode);
187: }
188:
189: public Element getContentElementFromTreePath(TreePath path) {
190: ElementTreeNodeImpl treeNode = getElementTreeNodeFromTreePath(path);
191: if (treeNode == null)
192: return null;
193: return getContentElement(treeNode);
194: }
195:
196: public Element getParentElementFromTreePath(TreePath path) {
197: ElementTreeNodeImpl treeNode = getElementTreeNodeFromTreePath(path);
198: if (treeNode == null)
199: return null;
200: return treeNode.getParentElement();
201: }
202:
203: public Element getHandleElementFromTreePath(TreePath path) {
204: ElementTreeNodeImpl treeNode = getElementTreeNodeFromTreePath(path);
205: if (treeNode == null)
206: return null;
207: return getHandleElement(treeNode);
208: }
209:
210: public Element getIconElementFromTreePath(TreePath path) {
211: ElementTreeNodeImpl treeNode = getElementTreeNodeFromTreePath(path);
212: if (treeNode == null)
213: return null;
214: return getIconElement(treeNode);
215: }
216:
217: public Element getLabelElementFromTreePath(TreePath path) {
218: ElementTreeNodeImpl treeNode = getElementTreeNodeFromTreePath(path);
219: if (treeNode == null)
220: return null;
221: return getLabelElement(treeNode);
222: }
223:
224: public int getRow(ElementTreeNodeImpl treeNode) {
225: // A día de hoy todos los nodos son visibles respecto al framework
226: int row = treeNode.getRow();
227: return markupToLogicRow(row);
228: }
229:
230: public ElementTreeNodeImpl getElementTreeNodeFromRow(int row) {
231: row = logicToMarkupRow(row);
232:
233: return elementTree.getElementTreeNodeFromRow(row);
234: }
235:
236: public ItsNatTreeCellUI getItsNatTreeCellUIFromNode(Node node) {
237: ElementTreeNodeImpl treeNode = elementTree
238: .getElementTreeNodeFromNode(node);
239: return getItsNatTreeCellUI(treeNode);
240: }
241:
242: public ItsNatTreeCellUI getItsNatTreeCellUIFromTreePath(
243: TreePath path) {
244: ElementTreeNodeImpl treeNode = getElementTreeNodeFromTreePath(path);
245: return getItsNatTreeCellUI(treeNode);
246: }
247:
248: public ItsNatTreeCellUI getItsNatTreeCellUIFromRow(int row) {
249: ElementTreeNodeImpl treeNode = getElementTreeNodeFromRow(row);
250: return getItsNatTreeCellUI(treeNode);
251: }
252:
253: public ItsNatTreeCellUIImpl getItsNatTreeCellUI(
254: ElementTreeNodeImpl treeNode) {
255: if (treeNode == null)
256: return null;
257: return ItsNatTreeCellUIImpl.getItsNatTreeCellUI(this , treeNode);
258: }
259:
260: public ElementTreeNodeImpl getElementTreeNodeFromTreePath(
261: TreePath path) {
262: if (path == null)
263: return null;
264: return getElementTreeNodeFromRow(getDefaultRowMapper()
265: .getRowForPath(path));
266: }
267:
268: public ElementTreeNodeListImpl getElementTreeNodeChildList(
269: TreePath path) {
270: ElementTreeNodeListImpl treeNodeList;
271: if ((path.getParentPath() == null) && isRootless()) // es el root y el árbol no tiene root con markup
272: {
273: return elementTree.getChildListRootless();
274: } else {
275: ElementTreeNodeImpl treeNode = getElementTreeNodeFromTreePath(path);
276: return (ElementTreeNodeListImpl) treeNode
277: .getElementTreeNodeList();
278: }
279: }
280:
281: public void insertTreeNodeAt(TreePath path) {
282: TreePath parentPath = path.getParentPath();
283: if (parentPath == null) // es el null
284: addRootNode(path);
285: else {
286: TreeModel dataModel = getItsNatTree().getTreeModel();
287: int index = dataModel.getIndexOfChild(parentPath
288: .getLastPathComponent(), path
289: .getLastPathComponent());
290: ElementTreeNode parentTreeNode = getElementTreeNodeFromTreePath(parentPath);
291: insertElementAt(index, path, parentTreeNode);
292: }
293: }
294:
295: public void insertTreeNodeAt(int index, TreePath parentPath) {
296: ElementTreeNodeList treeNodeListParent = getElementTreeNodeChildList(parentPath);
297: TreeModel dataModel = getItsNatTree().getTreeModel();
298: Object dataNode = dataModel.getChild(parentPath
299: .getLastPathComponent(), index);
300: TreePath path = parentPath.pathByAddingChild(dataNode);
301: insertElementAt(index, path, treeNodeListParent);
302: }
303:
304: public void removeTreeNodeAt(TreePath path) {
305: TreePath parentPath = path.getParentPath();
306: if (parentPath == null) // es el null
307: removeRootNode();
308: else {
309: TreeModel dataModel = getItsNatTree().getTreeModel();
310: int index = dataModel.getIndexOfChild(parentPath
311: .getLastPathComponent(), path
312: .getLastPathComponent());
313: removeTreeNodeAt(index, parentPath);
314: }
315: }
316:
317: public void removeTreeNodeAt(int index, TreePath parentPath) {
318: ElementTreeNodeListImpl treeNodeListParent = getElementTreeNodeChildList(parentPath);
319: removeElementAt(index, treeNodeListParent);
320: }
321:
322: public void removeAllChildTreeNodes(TreePath parentPath) {
323: if (parentPath == null) // Es el caso de eliminar el root
324: removeRootNode();
325: else {
326: ElementTreeNode parentTreeNode = getElementTreeNodeFromTreePath(parentPath);
327: ElementTreeNodeListImpl treeNodeListParent = (ElementTreeNodeListImpl) parentTreeNode
328: .getChildTreeNodeList();
329: int len = treeNodeListParent.getLength();
330: for (int i = 0; i < len; i++)
331: removeElementAt(i, treeNodeListParent);
332: }
333: }
334:
335: public void setNodeValueAt(TreePath path, boolean hasFocus,
336: ElementTreeNodeImpl treeNode, boolean isNew) {
337: int row = getDefaultRowMapper().getRowForPath(path);
338: if (row < 0)
339: throw new ItsNatException("Tree node is not shown: " + path);
340:
341: Object dataNode = path.getLastPathComponent();
342: setNodeValueAt(row, dataNode, hasFocus, treeNode, isNew);
343: }
344:
345: public void setTreeNodeValueAt(int index, TreePath parentPath,
346: boolean hasFocus) {
347: TreePath path = getItsNatTreeImpl().toTreePath(index,
348: parentPath);
349: setTreeNodeValueAt(path, hasFocus);
350: }
351:
352: public void setTreeNodeValueAt(TreePath path, boolean hasFocus) {
353: int row = getDefaultRowMapper().getRowForPath(path);
354: if ((row == 0) && isRootless())
355: return; // El root no tiene visualización
356: ElementTreeNodeImpl treeNode = getElementTreeNodeFromRow(row);
357: Object value = path.getLastPathComponent();
358: setNodeValueAt(row, value, hasFocus, treeNode, false);
359: }
360:
361: public void setNodeValueAt(int row, Object value, boolean hasFocus,
362: ElementTreeNodeImpl treeNode, boolean isNew) {
363: ItsNatTree tree = getItsNatTree();
364: TreeModel dataModel = tree.getTreeModel();
365: boolean isSelected = tree.getTreeSelectionModel()
366: .isRowSelected(row);
367: boolean isLeaf = dataModel.isLeaf(value);
368: boolean expanded = getItsNatTreeCellUI(treeNode).isExpanded();
369: Element treeNodeLabelElem = treeNode.getLabelElement();
370:
371: treeNode
372: .setUsePatternMarkupToRender(isUsePatternMarkupToRender()); // Asegura que tiene el último valor pues cada tree node tiene su propio estado
373: treeNode.prepareRendering(treeNodeLabelElem, isNew);
374:
375: ItsNatTreeCellRenderer renderer = getItsNatTreeCellRenderer();
376: if (renderer != null)
377: renderer.renderTreeCell(tree, row, value, isSelected,
378: expanded, isLeaf, hasFocus, treeNodeLabelElem,
379: isNew);
380: }
381:
382: public void removeElementAt(int index,
383: ElementTreeNodeListImpl treeNodeListParent) {
384: unrenderTreeNode(index, treeNodeListParent);
385:
386: treeNodeListParent.removeTreeNodeAt(index);
387: }
388:
389: public void insertElementAt(int index, TreePath path,
390: ElementTreeNode treeNodeParent) {
391: insertElementAt(index, path, treeNodeParent
392: .getChildTreeNodeList());
393: }
394:
395: public void insertElementAt(int index, TreePath path,
396: ElementTreeNodeList treeNodeList) {
397: ElementTreeNode newTreeNode = treeNodeList
398: .insertTreeNodeAt(index);
399:
400: setNodeValueAt(path, false, (ElementTreeNodeImpl) newTreeNode,
401: true);
402:
403: // Procesamos los hijos de forma recursiva
404: insertChildren(path, newTreeNode.getChildTreeNodeList());
405: }
406:
407: public void insertChildren(TreePath path,
408: ElementTreeNodeList treeNodeList) {
409: // Procesamos los hijos de forma recursiva
410: TreeModel dataModel = getItsNatTree().getTreeModel();
411: Object dataNode = path.getLastPathComponent();
412: int count = dataModel.getChildCount(dataNode);
413: for (int i = 0; i < count; i++) {
414: Object childNode = dataModel.getChild(dataNode, i);
415: TreePath childPath = path.pathByAddingChild(childNode);
416: insertElementAt(i, childPath, treeNodeList);
417: }
418: }
419:
420: public void addRootNode(Object dataNodeRoot) {
421: TreePath rootPath = new TreePath(dataNodeRoot);
422: addRootNode(rootPath);
423: }
424:
425: public void addRootNode(TreePath rootPath) {
426: // Interna, se cumple aquí que rootPath no tiene parent (es verdaderamente root)
427: if (!isRootless()) // Si es root less no tiene markup
428: {
429: ElementTreeNodeImpl rootNode = elementTree.addRootNode(); // Si ya había root dará error
430: setNodeValueAt(rootPath, false, rootNode, true);
431: }
432:
433: ElementTreeNodeList treeNodeList = getElementTreeNodeChildList(rootPath);
434:
435: // Procesamos los hijos de forma recursiva
436: insertChildren(rootPath, treeNodeList);
437: }
438:
439: public void unrenderTreeNode(int index,
440: ElementTreeNodeListImpl childList) {
441: ElementTreeNodeImpl treeNode = (ElementTreeNodeImpl) childList
442: .getTreeNodeAt(index);
443: unrenderTreeNode(treeNode);
444: }
445:
446: public void unrenderTreeNode(ElementTreeNodeImpl treeNode) {
447: if (treeNode == null)
448: return;
449:
450: ItsNatTreeCellRenderer renderer = getItsNatTreeCellRenderer();
451: if (renderer != null) {
452: Element treeNodeLabelElem = treeNode.getLabelElement();
453: renderer.unrenderTreeCell(getItsNatTree(), treeNode
454: .getRow(), treeNodeLabelElem);
455: }
456: // Es posible que el padre pueda no tener renderer pero los hijos sí.
457: ElementTreeNodeListImpl childList = treeNode
458: .getElementTreeNodeList();
459: unrenderTreeNode(childList);
460: }
461:
462: public void unrenderTreeNode(ElementTreeNodeListImpl childList) {
463: if (childList == null)
464: return;
465: int len = childList.getLength();
466: for (int i = 0; i < len; i++)
467: unrenderTreeNode(i, childList);
468: }
469:
470: public void removeRootNode() {
471: if (!isRootless())
472: unrenderTreeNode(elementTree.getRootNode()); // puede ser null el root (no tiene)
473: else
474: unrenderTreeNode(elementTree.getChildListRootless());
475:
476: elementTree.removeRootNode();
477: }
478:
479: public boolean isUsePatternMarkupToRender() {
480: return elementTree.isUsePatternMarkupToRender();
481: }
482:
483: public void setUsePatternMarkupToRender(boolean value) {
484: elementTree.setUsePatternMarkupToRender(value);
485: }
486:
487: public void setEnabled(boolean b) {
488: this .enabled = b;
489: }
490:
491: public boolean isEnabled() {
492: return enabled;
493: }
494: }
|