最近ちょっとしたことで必要になったDOMとJTreeとの相互変換について、ちょっとしたものを作りました。
// Very simple JTree <-> DOM converter
import java.io.*;
import javax.swing.tree.*;
import org.w3c.dom.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
/**
JTree内に保持されているconvert javax.swing.tree.DefaultMutableTreeNode
を保存/読み込みできるようにするためのorg.w3c.dom.Elementとの相互変換
のためのクラス。
例えば、以下のようなJTreeは下のようなDOMに変換されます。
root
a
b
<?xml version="1.0" encoding="utf-8"?>
<TreeNode tag="root">
<TreeNode tag="a"/>
<TreeNode tag="b"/>
</TreeNode>
また、下のDOMから上のようなDefaultMutaleTreeNodeを作成できます。
tag名と属性名はコンストラクタで設定可能です。
*/
public class TreeDOM
{
private String attrName = null;
private String tagName = null;
TreeDOM()
{
this("tag", "TreeNode");
}
TreeDOM(String attr, String tag)
{
attrName = attr;
tagName = tag;
}
/**
* nodeからDefaultMutabletTreeNodeを作成。見た通り。
*
* @param node DOMのNode
*/
public DefaultMutableTreeNode nodeToTreeNode(Node node)
{
DefaultMutableTreeNode treeNode = new DefaultMutableTreeNode();
NamedNodeMap map = node.getAttributes();
if (map == null)
return null;
Node n = map.getNamedItem(attrName);
if (n == null)
return null;
treeNode.setUserObject(n.getNodeValue());
if (node.hasChildNodes())
{
NodeList nodeList = node.getChildNodes();
for (int i = 0;i < nodeList.getLength();i ++)
{
DefaultMutableTreeNode childTreeNode = nodeToTreeNode(nodeList.item(i));
if (childTreeNode != null)
{
treeNode.add(childTreeNode);
}
}
}
return treeNode;
}
/**
* DefaultMutableTreeNodeからDOMのElementを作成。
*
* @param treeNode 変換元
*/
public Element treeNodeToNode(DefaultMutableTreeNode treeNode)
{
Document document = null;
try
{
// DOM 作成
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DOMImplementation domImpl = builder.getDOMImplementation();
document = domImpl.createDocument("", tagName, null);
}
// あったら困る。
catch (javax.xml.parsers.ParserConfigurationException e)
{
return null;
}
Element el = treeNodeToNode(treeNode, document, document.getDocumentElement());
return (Element)el.getFirstChild();
}
/**
* 再帰の関数。documentでNodeを作ったり、タグを足したりするので、ちょっと
* 引数が多め。(改善の余地あり。)
*
* @param treeNode 変換するべき残っている子どもnode
* @param document Node, Attr作成用
* @param node 子どもを足すcurrent node
*/
private Element treeNodeToNode(DefaultMutableTreeNode treeNode, Document document, Element node)
{
Element tagNode = document.createElement(tagName);
Attr attr = document.createAttribute(attrName);
attr.setValue((String)treeNode.getUserObject());
tagNode.setAttributeNode(attr);
node.appendChild(tagNode);
if (!treeNode.isLeaf())
{
for (int i = 0;i < treeNode.getChildCount();i ++)
{
DefaultMutableTreeNode childTreeNode =
(DefaultMutableTreeNode)treeNode.getChildAt(i);
Element n = null;
if (childTreeNode != null)
{
n = treeNodeToNode(childTreeNode, document, tagNode);
}
}
}
return node;
}
}
> > > Ah, understood. I was stuck with Outlook at my last job, and it was
> > > impossible to get it to quote a message in a way that you could
> > > actually reply to things point by point. It seemed optimized for
> > > sending a message to every person in the company and making all of
> > > your text blue. What a fucking joke.
> >
> > If it's a joke you should use Comic Sans so everyone /knows/ it's
> > funny.
>
> No no, Comic Sans is for presentations to the shareholders!
Somebody who is presenting to shareholders knows how to change the
default font?
Weird...
Jonathan Rockway, Andy Armstrong, Jonathan Rockway, and Adrian Howard
http://www.nntp.perl.org/group/perl.module-authors/2007/10/msg5907.html
When you're setting a price, you're sending a signal. If your competitor's
software ranges in price from about $100 to about $500, and you decide, heck,
my product is about in the middle of the road, so I'll sell it for $300, well,
what message do you think you're sending to your customers? You're telling
them that you think your software is "eh." I have a better idea: charge $1350.
Now your customers will think, "oh, man, that stuff has to be the cat's
whiskers since they're charging mad coin for it!"
And then they won't buy it because the limit on the corporate AMEX is $500.
Misery.
-- Joel Spolsky
-- "Camels and Rubber Duckies" ( http://www.joelonsoftware.com/articles/CamelsandRubberDuckies.html )