// package com.swingswinging.common.ui.tree; package tree; import java.io.*; import java.util.*; import javax.swing.event.*; import javax.swing.tree.*; import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.*; /** * XMLのDOMを用いて木構造を保持するTreeModelの実装です。 * @version 1.0 2002-12-23 * @author Takashi KOBAYASHI */ public class XMLTreeModel implements TreeModel { private Document doc; private Map elms; protected EventListenerList listeners; /** * デフォルトのコンストラクタ。 */ protected XMLTreeModel() { listeners = new EventListenerList(); elms = new HashMap(); } /** * 格納するDOMのオブジェクトを引数にしてTreeModelのインスタンスを生成します。 * @param doc XMLドキュメント */ public XMLTreeModel( Document doc ) { this(); this.doc = doc; } /** * XMLのファイル名を指定してTreeModelのインスタンスを生成します。ファイルを読み込んで、内部的にDocumentのインスタンスを取得します。 * @param 変数名 */ public XMLTreeModel( String filename ) { this(); try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // factory.setCoalescing( true ); factory.setIgnoringComments( true ); factory.setIgnoringElementContentWhitespace( true ); factory.setValidating( true ); doc = factory.newDocumentBuilder().parse( new File( filename ) ); doc.normalize(); } catch( SAXException sxe ) { sxe.printStackTrace(); } catch( ParserConfigurationException pce ) { pce.printStackTrace(); } catch( IOException ioe ) { ioe.printStackTrace(); } } /** * 木構造のルート(root: 根)となるTreeNodeを取得します。 * @return DOMのルート要素(org.w3c.dom.Document)を格納したXMLTreeNodeのインスタンス */ public Object getRoot() { Object ret = elms.get( doc ); if( ret == null ) { ret = new XMLTreeNode( doc, elms ); elms.put( doc, ret ); } return ret; } /** * parentで指定されたXMLTreeNodeの子ノードで、indexで指定された位置に格納されているノードを取得します。 * @param parent このTreeModelに格納された木構造に含まれるXMLTreeNode * @return index番目にあるparentの子ノード */ public Object getChild( Object parent, int index ) { if( parent == null ) throw new IllegalArgumentException( "Argument parent is Null" ); if( !( parent instanceof XMLTreeNode ) ) throw new IllegalArgumentException( "Unexpected type: " + parent.getClass().getName() ); return ( (XMLTreeNode)parent ).getChildAt( index ); } /** * parentで指定されたXMLTreeNodeの子ノードの数を取得します。 * @param parent このTreeModelに格納された木構造に含まれるXMLTreeNode * @return parentの子ノードの数 */ public int getChildCount( Object parent ) { if( parent == null ) throw new IllegalArgumentException( "Argument parent is Null" ); if( !( parent instanceof XMLTreeNode ) ) throw new IllegalArgumentException( "Unexpected type: " + parent.getClass().getName() ); return ( (XMLTreeNode)parent ).getChildCount(); } /** * nodeが葉である場合に、trueを返します。nodeが葉であるかどうかは、nodeが格納するDOMの要素に依存します。 * @param node このTreeModelに格納された木構造に含まれるXMLTreeNode * @return nodeが葉の場合、true * @see tree.XMLTreeNode */ public boolean isLeaf( Object node ) { if( node == null ) throw new IllegalArgumentException( "Argument parent is Null" ); if( !( node instanceof XMLTreeNode ) ) throw new IllegalArgumentException( "Unexpected type: " + node.getClass().getName() ); return ( (XMLTreeNode)node ).isLeaf(); } /** * 未実装。 */ public void valueForPathChanged( TreePath path, Object newValue ) { } /** * parentで指定されたXMLTreeNodeの子ノードのうち、childで指定されたXMLTreeNodeが何番目に格納されているか、その位置を返します。 * @param parent このTreeModelに格納された木構造に含まれるXMLTreeNode * @param child parentの子ノードのXMLTreeNode * @return parentの子ノードの中で、childが何番目に格納されているか */ public int getIndexOfChild( Object parent, Object child ) { if( ( parent == null ) || ( child == null ) ) throw new IllegalArgumentException( "Argument(s) is/are Null" ); if( !( parent instanceof XMLTreeNode ) ) throw new IllegalArgumentException( "Unexpected type of Argument parent: " + parent.getClass().getName() ); if( !( child instanceof XMLTreeNode ) ) throw new IllegalArgumentException( "Unexpected type of Argument child: " + child.getClass().getName() ); return ( (XMLTreeNode)parent ).getIndex( (XMLTreeNode)child ); } /** * 木構造が変化したときに発生するTreeModelEventに対するリスナを追加登録します。 * @param l 追加するリスナ */ public void addTreeModelListener( TreeModelListener l ) { listeners.add( TreeModelListener.class, l ); } /** * addTreeModelListener()で登録したリスナを削除します。 * @param l 削除するリスナ */ public void removeTreeModelListener( TreeModelListener l ) { listeners.remove( TreeModelListener.class, l ); } }