/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package app.navigps.gui.displayItemsMap;
import app.navigps.gui.NaviRootWindow;
import app.navigps.gui.Scrollbar.ui.LineScrollBarUI;
import app.navigps.gui.svgComponents.DOMDocumentTree;
import app.navigps.gui.svgComponents.DOMDocumentTreeController;
import app.navigps.utils.Utils;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import javax.swing.ImageIcon;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import org.apache.batik.bridge.svg12.ContentManager;
import org.apache.batik.bridge.svg12.DefaultXBLManager;
import org.apache.batik.dom.AbstractDocument;
import org.apache.batik.dom.svg12.XBLOMContentElement;
import org.apache.batik.dom.xbl.NodeXBL;
import org.apache.batik.dom.xbl.XBLManager;
import org.apache.batik.swing.svg.GVTTreeBuilderAdapter;
import org.apache.batik.swing.svg.GVTTreeBuilderEvent;
import org.apache.batik.swing.svg.SVGDocumentLoaderEvent;
import org.apache.batik.swing.svg.SVGDocumentLoaderListener;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.svg.SVGDocument;
/**
* Created on 2008-12-30, 19:37:03
* @author vara
*/
public class PanelWithBatikJTree extends JScrollPane{
//create only with -s start up parameter(window with properties svg doc)
private DOMDocumentTree tree;
/**
*
*/
public final DOMTreeSelectionListener treeSelectionListener = new DOMTreeSelectionListener();
private final GVTTreeListener listener = new GVTTreeListener();
//test
protected DetailsPanel attributePanel;
public PanelWithBatikJTree(DetailsPanel dp){
attributePanel = dp;
init();
}
/**
*
*/
public void reloadTree(){
getGVTTreeListener().reload();
}
private void init(){
setBorder(null);
getViewport().setOpaque(false);
getViewport().setBorder(null);
tree = new DOMDocumentTree(null,
new DOMDocumentTreeController() {
@Override
public boolean isDNDSupported() {
return true;
}
});
tree.setOpaque(false);
tree.setBorder(null);
tree.addTreeSelectionListener(treeSelectionListener);
tree.setCellRenderer(new NodeRenderer());
setViewportView(tree);
JScrollBar scbH = getHorizontalScrollBar();
JScrollBar scbV = getVerticalScrollBar();
scbH.setOpaque(false);
scbV.setOpaque(false);
scbV.setUI(new LineScrollBarUI());
scbH.setUI(new LineScrollBarUI());
scbH.removeAll();
scbV.removeAll();
attributePanel.addActionToButton(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
reloadTree();
}
});
}
/**
*
* @param doc
*/
public void createModelTree(SVGDocument doc){
long startTime = System.nanoTime();
System.out.println("----Create content window properties----");
System.out.println("Build Tree Nodes ...");
System.out.println("Build Tree Model for Tree Nodes ...");
TreeNode root = createTree(doc,false);
DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
if(model==null){
model = new DefaultTreeModel(root);
tree.setModel(model);
}else
model.setRoot(root);
System.out.println("Build Tree Model Completed");
System.out.println("Build Tree Nodes Completed");
long stopTime = System.nanoTime();
String time = Utils.roundsValue(((stopTime-startTime)/1000000),5);
System.err.println("Time : "+time+" milisec.");
}
/**
*
* @return
*/
public GVTTreeListener getGVTTreeListener(){
return listener;
}
private class GVTTreeListener extends GVTTreeBuilderAdapter
implements SVGDocumentLoaderListener{
private SVGDocument doc;
@Override
public void gvtBuildCompleted(GVTTreeBuilderEvent e) {
reload();
}
@Override
public void gvtBuildStarted(GVTTreeBuilderEvent e) {
//tree.setModel(null);
}
@Override
public void gvtBuildCancelled(GVTTreeBuilderEvent e) {}
@Override
public void gvtBuildFailed(GVTTreeBuilderEvent e) {}
@Override
public void documentLoadingStarted(SVGDocumentLoaderEvent e) {}
@Override
public void documentLoadingCompleted(SVGDocumentLoaderEvent e) {
doc = e.getSVGDocument();
}
@Override
public void documentLoadingCancelled(SVGDocumentLoaderEvent e) {}
@Override
public void documentLoadingFailed(SVGDocumentLoaderEvent e) {}
public void reload(){
if(doc!=null){
createModelTree(doc);
}
}
}
/**
* Finds and returns the node in the tree that represents the given node
* in the document.
*
* @param theTree
* The given JTree
* @param node
* The given org.w3c.dom.Node
* @return Node or null if not found
*/
protected DefaultMutableTreeNode findNode(JTree theTree, Node node) {
DefaultMutableTreeNode root = (DefaultMutableTreeNode) theTree
.getModel().getRoot();
Enumeration treeNodes = root.breadthFirstEnumeration();
while (treeNodes.hasMoreElements()) {
DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) treeNodes
.nextElement();
NodeInfo userObject = (NodeInfo) currentNode.getUserObject();
if (userObject.getNode() == node) {
return currentNode;
}
}
return null;
}
/**
* Finds and selects the given node in the document tree.
*
* @param targetNode
* The node to be selected
*/
public void selectNode(final Node targetNode) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
DefaultMutableTreeNode node = findNode(tree, targetNode);
if (node != null) {
TreeNode[] path = node.getPath();
TreePath tp = new TreePath(path);
// Changes the selection
tree.setSelectionPath(tp);
// Expands and scrolls the TreePath to visible if
// needed
tree.scrollPathToVisible(tp);
}
}
});
}
/**
*
* @param node
* @param showWhitespace
* @return
*/
protected MutableTreeNode createTree(Node node,boolean showWhitespace) {
DefaultMutableTreeNode result;
result = new DefaultMutableTreeNode(new NodeInfo(node));
for (Node n = node.getFirstChild(); n != null; n = n.getNextSibling()) {
if (!showWhitespace && (n instanceof org.w3c.dom.Text)) {
String txt = n.getNodeValue();
if (txt.trim().length() == 0)
continue;
}
result.add(createTree(n, showWhitespace));
}
if (node instanceof NodeXBL) {
Element shadowTree = ((NodeXBL) node).getXblShadowTree();
if (shadowTree != null) {
DefaultMutableTreeNode shadowNode
= new DefaultMutableTreeNode
(new ShadowNodeInfo(shadowTree));
shadowNode.add(createTree(shadowTree, showWhitespace));
result.add(shadowNode);
}
}
if (node instanceof XBLOMContentElement) {
AbstractDocument doc = (AbstractDocument) node.getOwnerDocument();
XBLManager xm = doc.getXBLManager();
if (xm instanceof DefaultXBLManager) {
DefaultMutableTreeNode selectedContentNode
= new DefaultMutableTreeNode(new ContentNodeInfo(node));
DefaultXBLManager dxm = (DefaultXBLManager) xm;
ContentManager cm = dxm.getContentManager(node);
if (cm != null) {
NodeList nl = cm.getSelectedContent((XBLOMContentElement) node);
for (int i = 0; i < nl.getLength(); i++) {
selectedContentNode.add(createTree(nl.item(i),
showWhitespace));
}
result.add(selectedContentNode);
}
}
}
return result;
}
/**
*
*/
protected class DOMTreeSelectionListener implements TreeSelectionListener {
//protected CSSStyleDeclaration style;
//protected ViewCSS viewCSS;
/**
* Called when the selection changes.
* @param ev
*/
@Override
public void valueChanged(TreeSelectionEvent ev) {
DefaultMutableTreeNode mtn;
mtn = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
if (mtn == null) {
return;
}
Object nodeInfo = mtn.getUserObject();
if (nodeInfo instanceof NodeInfo) {
final Node node = ((NodeInfo) nodeInfo).getNode();
switch (node.getNodeType()) {
case Node.DOCUMENT_NODE:
attributePanel.getXMLEditorPanel().getNodeXmlArea().setText(
createDocumentText((Document) node));
break;
case Node.ELEMENT_NODE:
new Thread(new Runnable() {
@Override
public void run() {
attributePanel.setPreviewElement((Element) node);
}
}).start();
break;
case Node.COMMENT_NODE:
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
attributePanel.getXMLEditorPanel().getNodeXmlArea().setText(
node.getNodeValue());
}
}
}
/**
*
* @param doc
* @return
*/
protected String createDocumentText(Document doc) {
StringBuffer sb = new StringBuffer();
sb.append("Nodes: ");
sb.append(nodeCount(doc));
return sb.toString();
}
/**
*
* @param node
* @return
*/
protected int nodeCount(Node node) {
int result = 1;
for (Node n = node.getFirstChild();
n != null;
n = n.getNextSibling()) {
result += nodeCount(n);
}
return result;
}
/**
* Processes element selection overlay.
*
* @param ev
* Tree selection event
*/
protected void handleElementSelection(TreeSelectionEvent ev) {
TreePath[] paths = ev.getPaths();
for (int i = 0; i < paths.length; i++) {
TreePath path = paths[i];
DefaultMutableTreeNode mtn =
(DefaultMutableTreeNode) path.getLastPathComponent();
Object nodeInfo = mtn.getUserObject();
if (nodeInfo instanceof NodeInfo) {
Node node = ((NodeInfo) nodeInfo).getNode();
if (node.getNodeType() == Node.ELEMENT_NODE) {
}
}
}
}
}
/**
* To render the tree nodes.
*/
protected class NodeRenderer extends DefaultTreeCellRenderer {
/**
*
*/
protected ImageIcon elementIcon;
/**
*
*/
protected ImageIcon commentIcon;
/**
*
*/
protected ImageIcon piIcon;
/**
*
*/
protected ImageIcon textIcon;
/**
*
*/
public NodeRenderer() {
setBackgroundNonSelectionColor(new Color(0,0,0,0));
String folder = "batik/treerenderer/";
elementIcon = NaviRootWindow.createNavigationIcon(folder+"element","gif");
commentIcon = NaviRootWindow.createNavigationIcon(folder+"comment", "gif");
piIcon =NaviRootWindow.createNavigationIcon(folder+"pi", "gif");
textIcon = NaviRootWindow.createNavigationIcon(folder+"text", "gif");
setIconTextGap(8);
}
/**
* Sets the value of the current tree cell.
* @param tree
* @param value
* @param expanded
* @param sel
* @param hasFocus
* @param leaf
* @param row
*/
@Override
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean sel,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, sel, expanded,
leaf, row, hasFocus);
switch (getNodeType(value)) {
case Node.ELEMENT_NODE:
setIcon(elementIcon);
break;
case Node.COMMENT_NODE:
setIcon(commentIcon);
break;
case Node.PROCESSING_INSTRUCTION_NODE:
setIcon(piIcon);
break;
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
setIcon(textIcon);
break;
}
return this;
}
/**
* Returns the DOM type of the given object.
* @param value
* @return the type or -1.
*/
protected short getNodeType(Object value) {
DefaultMutableTreeNode mtn = (DefaultMutableTreeNode)value;
Object obj = mtn.getUserObject();
if (obj instanceof NodeInfo) {
Node node = ((NodeInfo)obj).getNode();
return node.getNodeType();
}
return -1;
}
}
/**
* To store the nodes informations
*/
public static class NodeInfo {
/**
* The DOM node.
*/
protected Node node;
/**
* Creates a new NodeInfo object.
* @param n
*/
public NodeInfo(Node n) {
node = n;
}
/**
* Returns the DOM Node associated with this node info.
* @return
*/
public Node getNode() {
return node;
}
/**
* Returns a printable representation of the object.
*/
@Override
public String toString() {
if (node instanceof Element) {
Element e = (Element) node;
String id = e.getAttribute(SVGConstants.SVG_ID_ATTRIBUTE);
if (id.length() != 0) {
return node.getNodeName() + " \"" + id + "\"";
}
}
return node.getNodeName();
}
}
/**
* To store the node information for a shadow tree.
*/
protected static class ShadowNodeInfo extends NodeInfo {
/**
*
* @param n
*/
public ShadowNodeInfo(Node n) {
super(n);
}
@Override
public String toString() {
return "shadow tree";
}
}
/**
* To store the node information for an xbl:content node's
* selected content.
*/
protected static class ContentNodeInfo extends NodeInfo {
/**
*
* @param n
*/
public ContentNodeInfo(Node n) {
super(n);
}
@Override
public String toString() {
return "selected content";
}
}
}