001: package com.calipso.xmleditor;
002:
003: import org.w3c.dom.Node;
004: import org.w3c.dom.NodeList;
005: import org.w3c.dom.NamedNodeMap;
006:
007: import javax.swing.*;
008: import javax.swing.tree.*;
009: import javax.swing.event.TreeSelectionListener;
010: import javax.swing.event.TreeSelectionEvent;
011: import java.util.*;
012: import java.awt.*;
013:
014: /**
015: *
016: * User: soliveri
017: * Date: 26-sep-2003
018: * Time: 14:17:16
019: *
020: */
021:
022: public class XmlEditorPanel extends JPanel implements
023: TreeSelectionListener {
024:
025: private String name;
026: private JPanel pnlMain;
027: private CardLayout cardLayout;
028: private JTree tree;
029: private DefaultTreeModel model;
030: private XmlEditorTreeModelNode currentNode;
031: private XmlEditorTreeModelNode lastNode;
032: private HashMap subPanels;
033: private XmlEditorTreeDefinitionNode nodeDefinition;
034: private Vector treeNodesHistory;
035: private boolean isBlocked;
036: private Node domRoot;
037: private boolean isJustXml;
038: private boolean isOnlyXsd = false;
039:
040: public void setOnlyXsd(boolean onlyXsd) {
041: this .isOnlyXsd = onlyXsd;
042: }
043:
044: /**
045: * Crea un nuevo panel en base a una definicion
046: * @param nodeDefinition
047: * @throws XmlEditorException
048: */
049: public XmlEditorPanel(XmlEditorTreeDefinitionNode nodeDefinition)
050: throws XmlEditorException {
051: name = nodeDefinition.getValue();
052: isBlocked = false;
053: isJustXml = false;
054: initialize(nodeDefinition);
055: }
056:
057: /**
058: * Crea un nuevo panel con un modelo y un nodo Root
059: * @param model
060: * @param domRoot
061: */
062: public XmlEditorPanel(DefaultTreeModel model, Node domRoot) {
063: this .model = model;
064: isJustXml = true;
065: this .domRoot = domRoot;
066: initialize();
067: }
068:
069: /**
070: * Inicializa los paneles. Inicializa el panel con CardLayout
071: */
072: private void initialize() {
073: createCardLayoutPanels();
074: setLayout(new BorderLayout());
075: JSplitPane splitPanel = new JSplitPane(
076: JSplitPane.VERTICAL_SPLIT, createCenterPanel(),
077: createSouthPanel());
078: splitPanel.setDividerLocation(200);
079: splitPanel.setDividerSize(2);
080: add(splitPanel, BorderLayout.CENTER);
081: }
082:
083: /**
084: * Crea el panel con CardLayout, genera los subpaneles y llena los datos.
085: */
086: private void createCardLayoutPanels() {
087: cardLayout = new CardLayout();
088: pnlMain = new JPanel(cardLayout);
089: HashMap subPanels = new HashMap();
090: getLeafsFrom(domRoot, subPanels);
091: Iterator iterator = subPanels.keySet().iterator();
092: while (iterator.hasNext()) {
093: String currentKey = iterator.next().toString();
094: pnlMain.add(((JPanel) subPanels.get(currentKey)),
095: currentKey);
096: }
097: this .subPanels = (HashMap) subPanels.clone();
098: }
099:
100: /**
101: * Inicia la creacion recursiva de los subpaneles, en base a los hijos de los nodos.
102: * @param node
103: * @param subPanels
104: */
105: private void getLeafsFrom(Node node, HashMap subPanels) {
106: if (node.getAttributes().getLength() > 0) {
107: subPanels.put(node.getNodeName(), new XmlEditorSubPanel(
108: getAttrsNamesFrom(node)));
109: getSubPanelsFrom(node.getChildNodes(), subPanels);
110: } else {
111: getSubPanelsFrom(node.getChildNodes(), subPanels);
112: }
113: }
114:
115: /**
116: * Obtiene los subpaneles en base a una lista de nodos hijos. Se llama recursivamente con los hijos de cada nodo visitado
117: * @param children
118: * @param subPanels
119: */
120: private void getSubPanelsFrom(NodeList children, HashMap subPanels) {
121: for (int i = 0; i < children.getLength(); i++) {
122: Node node = children.item(i);
123: if (node.getNodeType() == Node.ELEMENT_NODE) {
124: if (node.getAttributes().getLength() > 0) {
125: subPanels.put(node.getNodeName(),
126: new XmlEditorSubPanel(
127: getAttrsNamesFrom(node)));
128: } else {
129: subPanels.put(node.getNodeName(),
130: new XmlEditorSubPanel(new Vector()));
131: getSubPanelsFrom(node.getChildNodes(), subPanels);
132: }
133: }
134: }
135: }
136:
137: /**
138: * Obtiene los nombres de los atributos de un nodo.
139: * @param node
140: * @return
141: */
142: private Vector getAttrsNamesFrom(Node node) {
143: Vector vector = new Vector();
144: NamedNodeMap attrs = node.getAttributes();
145: for (int i = 0; i < attrs.getLength(); i++) {
146: Node attr = attrs.item(i);
147: vector.add(attr.getNodeName());
148: }
149: return vector;
150: }
151:
152: /**
153: * Inicializa los paneles, pero basandose en una definicion.
154: * @param nodeDefinition
155: * @throws XmlEditorException
156: */
157: private void initialize(XmlEditorTreeDefinitionNode nodeDefinition)
158: throws XmlEditorException {
159: this .nodeDefinition = nodeDefinition;
160: model = getModelFrom(nodeDefinition);
161: createCardLayoutPanels(nodeDefinition);
162: setLayout(new BorderLayout());
163: JSplitPane splitPanel = new JSplitPane(
164: JSplitPane.VERTICAL_SPLIT, createCenterPanel(),
165: createSouthPanel());
166: splitPanel.setDividerLocation(200);
167: splitPanel.setDividerSize(2);
168: add(splitPanel, BorderLayout.CENTER);
169: }
170:
171: /**
172: * Obtiene un modelo de arbol en base a un definicion.
173: * @param nodeDefinition
174: * @return
175: */
176: private DefaultTreeModel getModelFrom(
177: XmlEditorTreeDefinitionNode nodeDefinition) {
178: XmlEditorTreeModelNode node = new XmlEditorTreeModelNode(
179: nodeDefinition.getValue());
180: fillTreeModel(nodeDefinition, node);
181: return new DefaultTreeModel(node);
182: }
183:
184: /**
185: * Llena un nodo en base a una definicion de nodo. Itera los subnodos llamandose recursivamente para cada uno.
186: * @param nodeDefinition
187: * @param node
188: */
189: private void fillTreeModel(
190: XmlEditorTreeDefinitionNode nodeDefinition,
191: XmlEditorTreeModelNode node) {
192: Iterator iterator = nodeDefinition.getSubnodes().keySet()
193: .iterator();
194: while (iterator.hasNext()) {
195: XmlEditorTreeDefinitionNode definition = (XmlEditorTreeDefinitionNode) nodeDefinition
196: .getSubnodes().get(iterator.next());
197: XmlEditorTreeModelNode newNode = new XmlEditorTreeModelNode(
198: definition.getValue());
199: node.add(newNode);
200: fillTreeModel(definition, newNode);
201: }
202: }
203:
204: private JPanel createSouthPanel() {
205: JPanel pnlSouth = new JPanel(new BorderLayout());
206: JScrollPane pane = new JScrollPane(pnlMain);
207: pnlSouth.add(pane, BorderLayout.CENTER);
208: return pnlSouth;
209: }
210:
211: /**
212: * Crea los paneles CardLayout cuando hay una definicion.
213: * @param nodeDefinition
214: * @throws XmlEditorException
215: */
216: private void createCardLayoutPanels(
217: XmlEditorTreeDefinitionNode nodeDefinition)
218: throws XmlEditorException {
219: cardLayout = new CardLayout();
220: pnlMain = new JPanel(cardLayout);
221: HashMap subPanels = new HashMap();
222: getLeafsFrom(nodeDefinition, subPanels);
223: Iterator iterator = subPanels.keySet().iterator();
224: while (iterator.hasNext()) {
225: String currentKey = iterator.next().toString();
226: pnlMain.add(((JPanel) subPanels.get(currentKey)),
227: currentKey);
228: }
229: this .subPanels = (HashMap) subPanels.clone();
230: }
231:
232: /**
233: * Obtiene los paneles, en base a una definicion.
234: * @param nodeDefinition
235: * @param subPanels
236: * @throws XmlEditorException
237: */
238: private void getLeafsFrom(
239: XmlEditorTreeDefinitionNode nodeDefinition,
240: HashMap subPanels) throws XmlEditorException {
241: if (nodeDefinition.getItemsKeys().size() > 0) {
242: subPanels.put(nodeDefinition.getValue(),
243: new XmlEditorSubPanel(
244: nodeDefinition.getItemsKeys(),
245: nodeDefinition.getItems()));
246: getSubPanelsFrom(nodeDefinition.getSubnodes(), subPanels);
247: } else {
248: getSubPanelsFrom(nodeDefinition.getSubnodes(), subPanels);
249: }
250: }
251:
252: private void getSubPanelsFrom(Map nodes, HashMap subPanels)
253: throws XmlEditorException {
254: Iterator iterator = nodes.keySet().iterator();
255: while (iterator.hasNext()) {
256: XmlEditorTreeDefinitionNode node = (XmlEditorTreeDefinitionNode) nodes
257: .get(iterator.next().toString());
258: if (node.getItemsKeys().size() > 0) {
259: subPanels.put(node.getValue(), new XmlEditorSubPanel(
260: node.getItemsKeys(), node.getItems()));
261: Map newNodes = node.getSubnodes();
262: getSubPanelsFrom(newNodes, subPanels);
263: } else {
264: subPanels.put(node.getValue(), new XmlEditorSubPanel(
265: new Vector(), new HashMap()));
266: Map newNodes = node.getSubnodes();
267: getSubPanelsFrom(newNodes, subPanels);
268: }
269: }
270: }
271:
272: private JPanel createCenterPanel() {
273: JPanel centerPanel = new JPanel(new BorderLayout());
274: tree = new JTree(model);
275: tree.addTreeSelectionListener(this );
276: JScrollPane scrollTree = new JScrollPane(tree);
277: centerPanel.add(scrollTree, BorderLayout.CENTER);
278: return centerPanel;
279: }
280:
281: public void valueChanged(TreeSelectionEvent e) {
282: currentNode = (XmlEditorTreeModelNode) (e.getPath()
283: .getLastPathComponent());
284: valueChanged();
285: }
286:
287: public void valueChanged() {
288: getTreeNodesHistory().add(currentNode);
289: if (getTreeNodesHistory().size() > 1) {
290: lastNode = (XmlEditorTreeModelNode) getTreeNodesHistory()
291: .elementAt(getTreeNodesHistory().size() - 2);
292: }
293: if (/*currentNode.getAttributes().size() != 0 &&*/currentNode
294: .isLeaf()) {
295: leafHasBeenSelected();
296: } else if (!currentNode.isLeaf()
297: && currentNode.getChildCount() > 0) {
298: folderHasBeenSelected();
299: } else {
300: cardLayout.show(pnlMain, currentNode.toString());
301: }
302:
303: }
304:
305: /**
306: * Realiza las acciones necesarias a realizar cuando se ha seleccionado una carpeta
307: */
308: private void folderHasBeenSelected() {
309: if (!isJustXml) {
310: if (lastNode != currentNode) {
311: verifyModelNodeChanges(false);
312: }
313: if (!isBlocked) {
314: if (currentNode.getAttributes() != null //((XmlEditorSubPanel) subPanels.get(currentNode.toString())).getInputComponents().isEmpty()
315: && currentNode != getTreeModel().getRoot()) {
316: cardLayout.show(pnlMain, currentNode.toString());
317: }//else{
318: //((XmlEditorSubPanel) subPanels.get(currentNode.toString())).eraseInputFields();
319: //}
320: }
321: } else {
322: verifyModelNodeChanges(false);
323: ((XmlEditorSubPanel) subPanels.get(currentNode.toString()))
324: .eraseInputFields();
325: cardLayout.show(pnlMain, currentNode.toString());
326: }
327: }
328:
329: /**
330: * Realiza las acciones necesarias a realizar cuando se ha seleccionado una hoja
331: */
332: private void leafHasBeenSelected() {
333: if (!isJustXml) {
334: if (lastNode != currentNode) {
335: verifyModelNodeChanges(true);
336: }
337: if (!isBlocked) {
338: XmlEditorTreeModelNode parent = (XmlEditorTreeModelNode) currentNode
339: .getParent();
340: XmlEditorSubPanel subPanel = null;
341: if (parent != null) {
342: subPanel = (XmlEditorSubPanel) subPanels.get(parent
343: .toString());
344: if (subPanel != null) {
345: if (!isOnlyXsd) {
346: subPanel.fillFrom(currentNode);
347: cardLayout.show(pnlMain, parent.toString());
348: }
349: cardLayout
350: .show(pnlMain, currentNode.toString());
351: }
352: }
353: }
354: } else {
355: verifyModelNodeChanges(true);
356: XmlEditorTreeModelNode parent = (XmlEditorTreeModelNode) currentNode
357: .getParent();
358: if (parent != null) {
359: XmlEditorSubPanel subPanel = (XmlEditorSubPanel) subPanels
360: .get(parent.toString());
361: subPanel.fillFrom(currentNode);
362: cardLayout.show(pnlMain, parent.toString());
363: }
364: }
365: }
366:
367: /**
368: * Verifica que los cambios realizados para un nodo sean correctos.
369: * @param isLeaf
370: */
371: private void verifyModelNodeChanges(boolean isLeaf) {
372: if (getTreeNodesHistory().size() > 1) {
373: if (isLeaf) {
374: verifyModelNodeChangesIfLeaf();
375: } else {
376: verifyModelNodeChangesIfFolder();
377: }
378: }
379: }
380:
381: /**
382: * Verifica las modificaciones si se selecciono una carpeta.
383: * Realiza el update del modelo.
384: */
385: private void verifyModelNodeChangesIfFolder() {
386: if (currentNode == lastNode.getParent() && lastNode.isLeaf()) {
387: XmlEditorSubPanel subPanel = (XmlEditorSubPanel) subPanels
388: .get(currentNode.toString());
389: updateModelNodeFrom(subPanel, lastNode);
390: } else if (currentNode != lastNode.getParent()
391: && lastNode.isLeaf()) {
392: XmlEditorTreeModelNode parent = (XmlEditorTreeModelNode) lastNode
393: .getParent();
394: XmlEditorSubPanel subPanel = (XmlEditorSubPanel) subPanels
395: .get(parent.toString());
396: updateModelNodeFrom(subPanel, lastNode);
397: }
398: }
399:
400: /**
401: * Verifica las modificaciones si se selecciono una hoja.
402: * Realiza el update del modelo.
403: */
404: private void verifyModelNodeChangesIfLeaf() {
405: if ((lastNode.getParent() == currentNode.getParent())
406: && lastNode.isLeaf()) {
407: XmlEditorTreeModelNode parent = (XmlEditorTreeModelNode) lastNode
408: .getParent();
409: if (parent != null) {
410: XmlEditorSubPanel subPanel = (XmlEditorSubPanel) subPanels
411: .get(parent.toString());
412: updateModelNodeFrom(subPanel, lastNode);
413: }
414: } else if (lastNode.getParent() != null) {
415: if (lastNode.getParent() != currentNode.getParent()
416: && lastNode.isLeaf()) {
417: XmlEditorTreeModelNode parent = (XmlEditorTreeModelNode) lastNode
418: .getParent();
419: XmlEditorSubPanel subPanel = (XmlEditorSubPanel) subPanels
420: .get(parent.toString());
421: updateModelNodeFrom(subPanel, lastNode);
422: }
423: }
424: }
425:
426: /**
427: * Verifica que no halla ningun error de datos. En ese caso actualiza los datos. Sino, bloquea el modelo.
428: * @param subPanel
429: * @param node
430: */
431: private void updateModelNodeFrom(XmlEditorSubPanel subPanel,
432: XmlEditorTreeModelNode node) {
433: String id = "";
434: if (node.getId() != null) {
435: id = node.getId();
436: }
437: if (!isJustXml && !isOnlyXsd) {
438: String wrongElement = validateFrom(subPanel,
439: (XmlEditorTreeModelNode) node/*.getParent()*/);
440: if (wrongElement != null) {
441: JOptionPane.showMessageDialog(this ,
442: "Falta completar el campo " + wrongElement);
443: isBlocked = true;
444: getTreeNodesHistory().removeElementAt(
445: getTreeNodesHistory().size() - 1);
446: tree.setSelectionPath(new TreePath(node));
447: } else {
448: isBlocked = false;
449: node.updateAttributesFrom(subPanel);
450: }
451: } else if (!isOnlyXsd) {
452: node.updateAttributesFrom(subPanel);
453: }
454: String newId = "";
455: if (node.getId() != null) {
456: newId = node.getId();
457: }
458: if (!id.equalsIgnoreCase(newId)) {
459: node.setUserObject(newId);
460: this .invalidate();
461: }
462: }
463:
464: /**
465: * Obtiene el root para una definicion.
466: * @param children
467: * @return
468: */
469: private XmlEditorTreeModelNode getRootSpecs(Enumeration children) {
470: while (children.hasMoreElements()) {
471: XmlEditorTreeModelNode modelNode = (XmlEditorTreeModelNode) children
472: .nextElement();
473: if (modelNode.isLeaf()) {
474: return modelNode;
475: }
476: }
477: return null;
478: }
479:
480: /**
481: * Borra un nodo del arbol.
482: */
483: public void deleteNode() {
484: if (!isJustXml) {
485: if (currentNode == getRootSpecs(((XmlEditorTreeModelNode) model
486: .getRoot()).children())
487: || currentNode == model.getRoot()) {
488: JOptionPane.showMessageDialog(this ,
489: "Debe existir una instancia de "
490: + ((XmlEditorTreeModelNode) model
491: .getRoot()).getUserObject());
492: return;
493: }
494: }
495: DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
496: TreeNode parent = currentNode.getParent();
497: if (parent != null) {
498: ((XmlEditorSubPanel) subPanels.get(parent.toString()))
499: .eraseInputFields();
500: model.removeNodeFromParent(currentNode);
501: }
502: //updateModelNodeFrom(, currentNode);
503: }
504:
505: /**
506: * Agrega un nodo hijo al nodo seleccionado, en base a sus atributos.
507: */
508: public void addNode() {
509: if (!isJustXml) {
510: if (currentNode != getRootSpecs(((XmlEditorTreeModelNode) model
511: .getRoot()).children())
512: && currentNode != model.getRoot()) {
513: //if(getRootSpecs(((XmlEditorTreeModelNode)model.getRoot()).children()) == null) {
514: //XmlEditorSubPanel subPanel = (XmlEditorSubPanel) subPanels.get(currentNode.toString());
515: if (subPanels.get(currentNode.toString()) == null) {
516: currentNode = (XmlEditorTreeModelNode) currentNode
517: .getParent();
518: }
519: XmlEditorSubPanel subPanel = getSubPanelFor(currentNode);
520: if (subPanel != null) {
521: String wrongElement = validateFrom(subPanel,
522: currentNode);
523: if (wrongElement != null) {
524: JOptionPane.showMessageDialog(this ,
525: "Falta completar el campo "
526: + wrongElement);
527: } else {
528: updateTreeModel(getId(currentNode), subPanel);
529: }
530: }
531: } else {
532: JOptionPane.showMessageDialog(this ,
533: "Solo debe existir una instancia de "
534: + ((XmlEditorTreeModelNode) model
535: .getRoot()).getUserObject());
536: }
537: } else {
538: XmlEditorSubPanel subPanel = getSubPanelFor(currentNode);
539: if (subPanel != null) {
540: updateTreeModel(getId(subPanel), subPanel);
541: }
542: }
543: }
544:
545: private String getId(XmlEditorTreeModelNode node) {
546: if (subPanels.get(node.toString()) != null) {
547: return node.toString();
548: } else {
549: return node.getParent().toString();
550: }
551: }
552:
553: /**
554: * Obtiene el subpanel que corresponde a un nodo.
555: * @param node
556: * @return
557: */
558: private XmlEditorSubPanel getSubPanelFor(XmlEditorTreeModelNode node) {
559: XmlEditorSubPanel subPanel = (XmlEditorSubPanel) subPanels
560: .get(node.toString());
561: if (subPanel == null) {
562: subPanel = (XmlEditorSubPanel) subPanels.get(node
563: .getParent().toString());
564: }
565: return subPanel;
566: }
567:
568: private String validateFrom(XmlEditorSubPanel subPanel,
569: XmlEditorTreeModelNode modelNode) {
570: //XmlEditorTreeDefinitionNode definition = getNodeDefinitionFrom(nodeDefinition, modelNode);
571: //return XmlEditorSubPanelValidator.validateFrom(subPanel, definition);
572: XmlEditorTreeModelNode auxModelNode;
573: if (subPanels.get(modelNode.toString()) == null) {
574: auxModelNode = (XmlEditorTreeModelNode) modelNode
575: .getParent();
576: } else {
577: auxModelNode = modelNode;
578: }
579: XmlEditorTreeDefinitionNode definition = getNodeDefinitionFrom(
580: nodeDefinition, auxModelNode);
581: if (definition != null
582: && !modelNode.toString().equalsIgnoreCase(
583: definition.getValue())) {
584: return XmlEditorSubPanelValidator.validateFrom(subPanel,
585: definition);
586: }
587: return null;
588: }
589:
590: private String getId(XmlEditorSubPanel subPanel) {
591: if (subPanel.getInputComponents() != null
592: && !subPanel.getInputComponents().isEmpty()) {
593: return ((JTextField) subPanel.getInputComponents()
594: .elementAt(0)).getText();
595: } else {
596: return "";
597: }
598: }
599:
600: /**
601: * Realiza el update del modelo despues de agregar un nodo. Crea el subpanel y limpia sus atributos.
602: * @param nodeName
603: * @param subPanel
604: */
605: private void updateTreeModel(String nodeName,
606: XmlEditorSubPanel subPanel) {
607: XmlEditorTreeModelNode modelNode = new XmlEditorTreeModelNode(
608: "New " + nodeName);
609: modelNode.addAttributesFrom(subPanel);
610: ((XmlEditorSubPanel) subPanels.get(getId(currentNode)))
611: .eraseInputFields();
612: DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
613: model.insertNodeInto(modelNode, currentNode, 0);
614: int[] selRows = tree.getSelectionRows();
615: for (int i = 0; i < selRows.length; i++) {
616: tree.expandRow(selRows[i]);
617: }
618: }
619:
620: /**
621: * Obtiene la definicion para un nodo, en base a una definicion (si no es la correspondiente buscara recursivamente entre sus hijos)
622: * @param definition
623: * @param modelNode
624: * @return
625: */
626: private XmlEditorTreeDefinitionNode getNodeDefinitionFrom(
627: XmlEditorTreeDefinitionNode definition,
628: XmlEditorTreeModelNode modelNode) {
629: if (definition.getValue().equals(modelNode.toString())) {
630: return definition;
631: } else {
632: return getNodeDefinitionFrom(definition.getSubnodes(),
633: false, modelNode);
634: }
635: }
636:
637: private XmlEditorTreeDefinitionNode getNodeDefinitionFrom(
638: Map subNodes, boolean found,
639: XmlEditorTreeModelNode modelNode) {
640: XmlEditorTreeDefinitionNode returnVal = null;
641: Iterator iterator = subNodes.keySet().iterator();
642: while (iterator.hasNext() && !found) {
643: XmlEditorTreeDefinitionNode definition = (XmlEditorTreeDefinitionNode) subNodes
644: .get(iterator.next().toString());
645: if (definition.getValue().equals(modelNode.toString())) {
646: return definition;
647: } else {
648: returnVal = getNodeDefinitionFrom(definition
649: .getSubnodes(), found, modelNode);
650: if (returnVal != null) {
651: found = true;
652: }
653: }
654: }
655: return returnVal;
656: }
657:
658: public DefaultTreeModel getTreeModel() {
659: return model;
660: }
661:
662: public String getName() {
663: return name;
664: }
665:
666: public Map getSubPanels() {
667: return subPanels;
668: }
669:
670: private Vector getTreeNodesHistory() {
671: if (treeNodesHistory == null) {
672: treeNodesHistory = new Vector();
673: }
674: return treeNodesHistory;
675: }
676:
677: public JTree getTree() {
678: return tree;
679: }
680:
681: public XmlEditorTreeDefinitionNode getNodeDefinition() {
682: return nodeDefinition;
683: }
684:
685: /**
686: * Colapsa todos los nodos del arbol recursivamente, dejando solo desplegada la raiz.
687: */
688: public void collapseAllNodes() {
689: int j = tree.getRowCount();
690: for (int i = 0; j == tree.getRowCount()
691: && i < tree.getRowCount(); i++) {
692: tree.collapseRow(tree.getRowCount() - i);
693: }
694: if (j != tree.getRowCount()) {
695: collapseAllNodes();
696: }
697: }
698:
699: private XmlEditorTreeModelNode getRootNode() {
700: XmlEditorTreeModelNode node = currentNode;
701: while (node.getParent() != null) {
702: node = (XmlEditorTreeModelNode) node.getParent();
703: }
704: return node;
705: }
706:
707: }
|