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.comp;
015:
016: import org.itsnat.comp.ui.ItsNatTreeUI;
017: import javax.swing.event.TreeExpansionListener;
018: import javax.swing.event.TreeWillExpandListener;
019: import javax.swing.tree.RowMapper;
020: import javax.swing.tree.TreeModel;
021: import javax.swing.tree.TreePath;
022: import javax.swing.tree.TreeSelectionModel;
023:
024: /**
025: * Is the base interface of tree based components.
026: *
027: * <p>A tree component manages a <code>javax.swing.tree.TreeModel</code>
028: * data model, tree node values are rendered as markup using a special object, the renderer,
029: * and may be optionally edited "in place" using a user defined editor.</p>
030: *
031: * <p>Any change to the data model is notified to the component and the markup
032: * is rendered again. The data model ever mandates over the markup,
033: * any initial markup content (initial root node) is removed.</p>
034: *
035: * <p>Almost a root node must be present in the markup, this element is used as a pattern
036: * to create new tree nodes, and is removed because by default the data model is empty.</p>
037: *
038: * <p>This component family uses a <code>javax.swing.tree.TreeSelectionModel</code> to keep
039: * track of selection states. When a tree node is selected (usually by clicking it) the selection
040: * state is updated accordingly using the selection model (this one fires any listener registered).</p>
041: *
042: * <p>There is no default decoration of tree node selection,
043: * selection model listeners may be used to decorate the tree node markup when its
044: * selection state changes.</p>
045: *
046: * <p>The component internally manages the expand/collapse behavior, when
047: * a mouse event is received (by default one click on handler, double click
048: * if icon or label) usually changes the expand/collapse state, this change
049: * is notified sending a <code>javax.swing.event.TreeExpansionEvent</code>
050: * to the registered listeners, these listeners must be used to manage how the expansion/collapsing
051: * is rendered visually (by default the component does not modify the view,
052: * does not force a default view behavior).</p>
053: *
054: * <p>By default this component uses the default renderer and editor and
055: * a <code>javax.swing.tree.DefaultTreeModel</code> data model.</p>
056: *
057: * <p>Row indexes start in 0.</p>
058: *
059: * <p>This component family is the "componentized" version of {@link org.itsnat.core.domutil.ElementTree} and
060: * follows a similar philosophy. </p>
061: *
062: * <p>ItsNat only provides "free trees" because
063: * no <tree> tag is present in HTML.</p>
064: *
065: * @author Jose Maria Arranz Santamaria
066: */
067: public interface ItsNatTree extends ItsNatElementComponent {
068: /**
069: * Returns the user interface manager of this component.
070: *
071: * @return the user interface manager.
072: */
073: public ItsNatTreeUI getItsNatTreeUI();
074:
075: /**
076: * Returns the current data model of this component.
077: *
078: * @return the current data model
079: * @see #setTreeModel(javax.swing.tree.TreeModel)
080: */
081: public TreeModel getTreeModel();
082:
083: /**
084: * Changes the data model of this component.
085: *
086: * <p>Current data model is disconnected from this component, and the new
087: * data model is bound to this component, every change is tracked and
088: * updates the user interfaces accordingly.</p>
089: *
090: * <p>If the specified data model is the same instance as the current data model,
091: * then is reset, component listener is removed and added again. Use this technique if
092: * you want to add a data model listener to be executed <i>before</i> the default component listener.
093: *
094: * @param dataModel the new data model.
095: * @see #getTreeModel()
096: */
097: public void setTreeModel(TreeModel dataModel);
098:
099: /**
100: * Informs whether this tree is a tree-table.
101: *
102: * <p>The tree-table mode only affects to the layout of tree nodes. If not
103: * tree-table (normal) child nodes are contained by the parent tree node markup,
104: * in a tree-table layout is as a list, all tree nodes are "top" level nodes
105: * as whether they all were roots (only from a layout point of view).</p>
106: *
107: * @return true if this tree has a tree-table layout.
108: */
109: public boolean isTreeTable();
110:
111: /**
112: * Informs whether this tree has a visible root.
113: *
114: * <p>In a root-less tree the root node has no markup, direct child nodes
115: * are top level nodes. This feature may be used to build trees with "multiple
116: * roots" visually, this is very useful in vertical tree-based menus where
117: * a root node is disturbing.</p>
118: *
119: * @return true if root node has no markup.
120: */
121: public boolean isRootless();
122:
123: /**
124: * Creates a data model instance appropriated to this component. This instance
125: * is not bound to the component.
126: *
127: * @return a new data model instance.
128: */
129: public TreeModel createDefaultTreeModel();
130:
131: /**
132: * Returns the number of mouse clicks needed to expand or close a node.
133: *
134: * <p>This number only counts for icon and label parts, the handle ever
135: * expands/collapses the node with every click.</p>
136: *
137: * <p>Valid numbers: 0,1 and 2. If 0 icon and label do not expand/collapse the node when clicked.</p>
138: *
139: * @return number of mouse clicks to expand/collapse a node. By default is 2.
140: * @see #setToggleClickCount(int)
141: */
142: public int getToggleClickCount();
143:
144: /**
145: * Sets the number of mouse clicks needed to expand or close a node.
146: *
147: * @param toggleClickCount number of mouse clicks to expand/collapse a node. Valid numbers: 0,1 and 2.
148: * @see #getToggleClickCount()
149: */
150: public void setToggleClickCount(int toggleClickCount);
151:
152: /**
153: * Registers a new "tree will expand" listener. This listener is called <i>before</i>
154: * a tree node is going to expand/collapse and can veto this action.
155: *
156: * @param tel the listener to register.
157: * @see #removeTreeWillExpandListener(javax.swing.event.TreeWillExpandListener)
158: */
159: public void addTreeWillExpandListener(TreeWillExpandListener tel);
160:
161: /**
162: * Unregisters the specified "tree will expand" listener.
163: *
164: * @param tel the listener to unregister.
165: * @see #addTreeWillExpandListener(javax.swing.event.TreeWillExpandListener)
166: */
167: public void removeTreeWillExpandListener(TreeWillExpandListener tel);
168:
169: /**
170: * Returns all registered tree "tree will expand" listeners
171: *
172: * @return an array with all registered "tree will expand" listeners
173: */
174: public TreeWillExpandListener[] getTreeWillExpandListeners();
175:
176: /**
177: * Registers a new tree expansion listener. This listener is called <i>after</i>
178: * a tree node is expanded/collapsed.
179: *
180: * @param tel the listener to register.
181: * @see #removeTreeExpansionListener(javax.swing.event.TreeExpansionListener)
182: */
183: public void addTreeExpansionListener(TreeExpansionListener tel);
184:
185: /**
186: * Unregisters the specified tree expansion listener.
187: *
188: * @param tel the listener to unregister.
189: * @see #addTreeExpansionListener(javax.swing.event.TreeExpansionListener)
190: */
191: public void removeTreeExpansionListener(TreeExpansionListener tel);
192:
193: /**
194: * Returns all registered "tree expansion" listeners
195: *
196: * @return an array with all registered "tree expansion" listeners
197: */
198: public TreeExpansionListener[] getTreeExpansionListeners();
199:
200: /**
201: * Returns the component structure.
202: *
203: * @return the component structure.
204: */
205: public ItsNatTreeStructure getItsNatTreeStructure();
206:
207: /**
208: * Returns the current component renderer. This renderer converts a tree node value to markup.
209: *
210: * @return the current renderer. By default uses the default renderer ({@link ItsNatComponentManager#createDefaultItsNatTreeCellRenderer()})
211: * @see #setItsNatTreeCellRenderer(ItsNatTreeCellRenderer)
212: */
213: public ItsNatTreeCellRenderer getItsNatTreeCellRenderer();
214:
215: /**
216: * Sets the component renderer.
217: *
218: * @param renderer the new renderer.
219: * @see #getItsNatTreeCellRenderer()
220: */
221: public void setItsNatTreeCellRenderer(
222: ItsNatTreeCellRenderer renderer);
223:
224: /**
225: * Returns the current tree node label editor. This object is used to edit in place
226: * a tree node value.
227: *
228: * @return the current editor. By default uses the default editor
229: * calling ({@link ItsNatComponentManager#createDefaultItsNatTreeCellEditor(ItsNatComponent)}) with a null parameter.
230: * @see #setItsNatTreeCellEditor(ItsNatTreeCellEditor)
231: */
232: public ItsNatTreeCellEditor getItsNatTreeCellEditor();
233:
234: /**
235: * Sets the tree node label editor.
236: *
237: * <p>Tree node edition works very much the same as label edition
238: * (see {@link ItsNatLabel#setItsNatLabelEditor(ItsNatLabelEditor)}).</p>
239: *
240: * <p>Some differences:</p>
241: *
242: * <p>The edition process starts programmatically by calling {@link #startEditingAtPath(javax.swing.tree.TreePath)}
243: * or {@link #startEditingAtRow(int)}.</p>
244: *
245: * <p>The edition takes place inside the tree node <i>label</i> element
246: * as returned by {@link ItsNatTreeStructure#getLabelElement(ItsNatTree,int,org.w3c.dom.Element)}.</p>
247: *
248: * <p>The new tree node value is set to the data model
249: * calling <code>javax.swing.tree.TreeModel.valueForPathChanged(javax.swing.tree.TreePath,Object)</code>.
250: * </p>
251: *
252: * @param editor the new editor. May be null (edition disabled).
253: * @see #getItsNatTreeCellEditor()
254: */
255: public void setItsNatTreeCellEditor(ItsNatTreeCellEditor editor);
256:
257: /**
258: * Returns the current selection model.
259: *
260: * @return the current selection model. By default a <code>javax.swing.tree.DefaultTreeSelectionModel</code> instance.
261: * @see #setTreeSelectionModel(javax.swing.tree.TreeSelectionModel)
262: */
263: public TreeSelectionModel getTreeSelectionModel();
264:
265: /**
266: * Sets the new selection model.
267: *
268: * <p>If the new selection model is the current defined then is "reset",
269: * component listener is removed and added again. Use this technique if
270: * you want to add a listener to be executed <i>before</i> the default component listener.</p>
271: *
272: * <p>The component automatically replaces the current selection model <code>javax.swing.tree.RowMapper</code>
273: * with the internal row mapper ({@link #getRowMapper()}) calling
274: * <code>TreeSelectionModel.setRowMapper(RowMapper)</code>.</p>
275: *
276: * @param selectionModel the new selection model.
277: * @see #getTreeSelectionModel()
278: */
279: public void setTreeSelectionModel(TreeSelectionModel selectionModel);
280:
281: /**
282: * Returns the previous path seeing the data model as a list (tree order).
283: *
284: * <p>First tries to return the previous sibling, if no sibling then returns the parent.</p>
285: *
286: * @return the previous path or null if specified path is the root node.
287: * @see #getNextPath(javax.swing.tree.TreePath)
288: * @see #getPreviousSiblingPath(javax.swing.tree.TreePath)
289: */
290: public TreePath getPreviousPath(TreePath path);
291:
292: /**
293: * Returns the path of the next node seeing the data model as a list (tree order).
294: *
295: * <p>First tries to return the first child, if no child returns the next sibling,
296: * if no next sibling returns the next sibling of the parent node, if none
297: * then the next sibling of the parent of the parent and so on.</p>
298: *
299: * @return the next path or null if this node is the last.
300: * @see #getPreviousPath(javax.swing.tree.TreePath)
301: * @see #getNextSiblingPath(javax.swing.tree.TreePath)
302: */
303: public TreePath getNextPath(TreePath path);
304:
305: /**
306: * Returns the path of the previous sibling node.
307: *
308: * @return the previous sibling path or null if specified path is the first child node or is the root.
309: * @see #getNextSiblingPath(javax.swing.tree.TreePath)
310: */
311: public TreePath getPreviousSiblingPath(TreePath path);
312:
313: /**
314: * Returns the path of the next sibling node.
315: *
316: * @return the next sibling path or null if specified path is the last child node or is the root.
317: * @see #getPreviousSiblingPath(javax.swing.tree.TreePath)
318: */
319: public TreePath getNextSiblingPath(TreePath path);
320:
321: /**
322: * Returns the last node (tree order)
323: *
324: * @return the last node, null if the tree is empty.
325: */
326: public TreePath getLastPath();
327:
328: /**
329: * Returns the number of nodes. This value is got traversing the data model.
330: *
331: * @return the number of nodes.
332: */
333: public int getTreeNodeCount();
334:
335: /**
336: * Returns the <code>expandsSelectedPaths</code> property.
337: * @return true if selection changes result in the parent path being expanded
338: * @see #setExpandsSelectedPaths(boolean)
339: */
340: public boolean isExpandsSelectedPaths();
341:
342: /**
343: * Sets the <code>expandsSelectedPaths</code> property. If
344: * true, any time the selection is changed, either via the
345: * <code>TreeSelectionModel</code>, or the cover methods provided by
346: * this component like {@link #expandNode(javax.swing.tree.TreePath)},
347: * the <code>TreePath</code>s parents will be
348: * expanded too to make them visible (visible meaning the parent path is
349: * expanded, not necessarily in the visible rectangle of the tree).
350: * If false, when the selection changes the node parents are not expanded.
351: * This is useful if you wish to have your selection model maintain selected paths
352: * that are not always expanded (all parents expanded).
353: *
354: * @param newValue the new value for <code>expandsSelectedPaths</code>
355: * @see #isExpandsSelectedPaths()
356: */
357: public void setExpandsSelectedPaths(boolean newValue);
358:
359: /**
360: * Used to start programmatically a tree node edition process "in place".
361: *
362: * @param path the tree node path to edit.
363: * @see #startEditingAtRow(int)
364: * @see #isEditing()
365: */
366: public void startEditingAtPath(TreePath path);
367:
368: /**
369: * Used to start programmatically a tree node edition process "in place".
370: *
371: * @param row the tree node row to edit.
372: * @see #startEditingAtPath(javax.swing.tree.TreePath)
373: * @see #isEditing()
374: */
375: public void startEditingAtRow(int row);
376:
377: /**
378: * Informs whether a tree node value is being edited.
379: *
380: * @return true if a tree node item value is being edited.
381: *
382: * @see #startEditingAtPath(javax.swing.tree.TreePath)
383: * @see #startEditingAtRow(int)
384: */
385: public boolean isEditing();
386:
387: /**
388: * Returns the path of the tree node being edited.
389: *
390: * @return the path of the tree node item being edited. Null if none is being edited.
391: */
392: public TreePath getEditingPath();
393:
394: /**
395: * Returns the row index of the tree node being edited.
396: *
397: * @return the row index of the tree node item being edited. -1 if none is being edited.
398: */
399: public int getEditingRow();
400:
401: /**
402: * Returns the event type used to activate the tree node edition process by the user.
403: *
404: * @return the event type used to activate the edition. By default is "dblclick".
405: * @see #setEditorActivatorEvent(String)
406: */
407: public String getEditorActivatorEvent();
408:
409: /**
410: * Sets the event type used to activate the tree node edition process by the user.
411: *
412: * @param eventType the event type used to activate the edition.
413: * @see #getEditorActivatorEvent()
414: */
415: public void setEditorActivatorEvent(String eventType);
416:
417: /**
418: * Informs whether the specified path is expanded.
419: *
420: * @param treePath the specified path.
421: * @return true if the specified path is expanded, true by default.
422: * @see org.itsnat.comp.ui.ItsNatTreeCellUI#isExpanded()
423: */
424: public boolean isExpandedNode(TreePath treePath);
425:
426: /**
427: * Marks the specified node as expanded.
428: *
429: * <p>First of all a {@link javax.swing.event.TreeExpansionEvent} event
430: * is sent to the registered {@link javax.swing.event.TreeWillExpandListener} listeners,
431: * if expansion request is not vetoed then the node is marked as expanded and previous event is sent again
432: * to the registered {@link javax.swing.event.TreeExpansionListener} listeners.</p>
433: *
434: * @param treePath the node path to expand.
435: * @see #collapseNode(javax.swing.tree.TreePath)
436: * @see org.itsnat.comp.ui.ItsNatTreeCellUI#expand(boolean)
437: */
438: public void expandNode(TreePath treePath);
439:
440: /**
441: * Marks the specified node as collapsed.
442: *
443: * <p>Symmetric behavior is applied to collapse request than
444: * {@link #expandNode(javax.swing.tree.TreePath)}.</p>
445: *
446: * @param treePath the node path to collapse.
447: * @see #expandNode(javax.swing.tree.TreePath)
448: * @see org.itsnat.comp.ui.ItsNatTreeCellUI#expand(boolean)
449: */
450: public void collapseNode(TreePath treePath);
451:
452: /**
453: * Changes the expansion state of the specified node to the contrary.
454: *
455: * <p>Same behavior as {@link #expandNode(javax.swing.tree.TreePath)}
456: * and {@link #collapseNode(javax.swing.tree.TreePath)}.</p>
457: *
458: * @param treePath the node path to change expansion state.
459: */
460: public void toggleExpansionStateNode(TreePath treePath);
461:
462: /**
463: * Expands the specified node and node parents.
464: *
465: * @param path the path to expand.
466: * @see #collapsePath(javax.swing.tree.TreePath)
467: */
468: public void expandPath(TreePath path);
469:
470: /**
471: * Collapses the specified node and node parents.
472: *
473: * @param path the path to expand.
474: * @see #expandPath(javax.swing.tree.TreePath)
475: */
476: public void collapsePath(TreePath path);
477:
478: /**
479: * Returns the built-in row mapper.
480: *
481: * <p>This row mapper can not be replaced and is set automatically
482: * to the registered selection model ({@link #setTreeSelectionModel(javax.swing.tree.TreeSelectionModel)}).</p>
483: *
484: * <p>Current implementation converts a <code>TreePath</code> to the matched row seeing
485: * the tree as a list (root node is 0), where every node is "visible" (in a server point of view,
486: * the same node in the client may be hidden).</p>
487: *
488: * @return the built-in row mapper.
489: */
490: public RowMapper getRowMapper();
491:
492: /**
493: * Returns the row position of the specified path. This position is obtained
494: * calling the built-in row mapper.
495: *
496: * @return the row position of the path.
497: * @return #getRowMapper()
498: */
499: public int getRowForPath(TreePath path);
500:
501: /**
502: * Returns the path of the node at the specified row position.
503: *
504: * <p>Current implementation specifies every node is visible (server point of view)
505: * row-path conversion is straightforward seeing the tree as a list.</p>
506: *
507: * @param row the specified row position.
508: * @return the path of the node at this row position.
509: * @see #getRowMapper()
510: */
511: public TreePath getTreePathForRow(int row);
512:
513: }
|