/* * Copyright 2001-2014 Aspose Pty Ltd. All Rights Reserved. * * This file is part of Aspose.Words. The source code in this file * is only intended as a supplement to the documentation, and is provided * "as is", without warranty of any kind, either expressed or implied. */ package com.aspose.words.examples.viewers_visualizers.document_explorer; import com.aspose.words.*; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; /** * Base class used to provide GUI representation for document nodes. */ public class Item { private Node mNode; private DefaultMutableTreeNode mTreeNode; private ImageIcon mIcon; private static ArrayList<Field> mControlCharFields; private static Map<Integer, String> mNodeTypes; private static Map<Integer, String> mHeaderFooterTypes; private static Map<String, String> mItemSet; private static ArrayList mIconNames = new ArrayList(); /** * Creates Item for the supplied document node. */ public Item(Node node) { mNode = node; } /** * Returns the node in the document that this Item represents. */ public Node getNode() { return mNode; } /** * The display name for this Item. Can be customized by overriding this method in inheriting classes. */ public String getName() throws Exception { return getNodeTypeString(mNode); } /** * The text of the corresponding document node. */ public String getText() throws Exception { String text = mNode.getText(); // Most control characters are converted to human readable form. // E.g. [!PageBreak!], [!Cell!], etc. for (Field fieldInfo : mControlCharFields) { if (fieldInfo.getType() == char.class && Modifier.isStatic(fieldInfo.getModifiers())) { Character ch = fieldInfo.getChar(null); // Represent a paragraph break using the special formatting marker. This makes the text easier to read. if(fieldInfo.getName().equals("PARAGRAPH_BREAK_CHAR")) text = text.replace(ch.toString(), "?" + "\n"); // JTextArea lines are separated using simple "\n" character and not using system independent new line character. else text = text.replace(ch.toString(), java.text.MessageFormat.format("[!{0}!]", fieldInfo.getName().replace("_CHAR", ""))); } } // All break chars should be supplemented with line feeds text = text.replace("BREAK!]", "BREAK!]\n"); return text; } /** * Creates a TreeNode for this item to be displayed in the Document Explorer TreeView control. */ public DefaultMutableTreeNode getTreeNode() throws Exception { if (mTreeNode == null) { mTreeNode = new DefaultMutableTreeNode(this); if (!mIconNames.contains(getIconName())) { mIconNames.add(getIconName()); } if (mNode instanceof CompositeNode && ((CompositeNode)mNode).getChildNodes().getCount() > 0) { mTreeNode.add(new DefaultMutableTreeNode("#dummy")); } } return mTreeNode; } /** * Returns the icon to display in the Document Explorer TreeView control. */ public ImageIcon getIcon() throws Exception { if (mIcon == null) { mIcon = loadIcon(getIconName()); if (mIcon == null) mIcon = loadIcon("Node"); } return mIcon; } /** * The icon for this node can be customized by overriding this property in the inheriting classes. * The name represents name of .ico file without extension located in the Icons folder of the project. */ protected String getIconName() throws Exception { return getClass().getSimpleName().replace("Item", ""); } /** * Provides lazy on-expand loading of underlying tree nodes. */ public void onExpand() throws Exception { if ("#dummy".equals(getTreeNode().getFirstChild().toString())) { getTreeNode().removeAllChildren(); Globals.mTreeModel.reload(getTreeNode()); for (Object o : ((CompositeNode)mNode).getChildNodes()) { Node n = (Node)o; getTreeNode().add(Item.createItem(n).getTreeNode()); } } } /** * Loads and returns an icon from the assembly resource stream. */ private ImageIcon loadIcon(String iconName) { java.net.URL imgURL = MainForm.class.getResource("images/" + iconName + ".gif"); if(imgURL != null) return new ImageIcon(imgURL); else return null; } /** * Removes this node from the document and the tree. */ public void remove() throws Exception { if (this.isRemovable()) { mNode.remove(); TreeNode parent = mTreeNode.getParent(); mTreeNode.removeFromParent(); Globals.mTreeModel.reload(parent); TreePath path = new TreePath(Globals.mRootNode); Globals.mTree.setSelectionPath(path); } } /** * Returns if this node can be removed from the document. Some nodes such as the last paragraph in the * document cannot be removed. */ public boolean isRemovable() { return true; } /** * Static ctor. */ static { // Populate a list of node types along with their class implementation. mItemSet = new HashMap<String, String>(); for(Class itemClass : DocumentItems.class.getDeclaredClasses()) { try { String nodeTypeString = (String) itemClass.getField("NODE_TYPE_STRING").get(null); mItemSet.put(nodeTypeString, itemClass.getName()); } catch (Exception e) { // IllegalAccessException, NoSuchFieldException or NoSuchMethodException - skip such exceptions if there are any. } } // Fill a list containing the information of each control char. mControlCharFields = new ArrayList<Field>(); Field[] fields = ControlChar.class.getFields(); for(Field fieldInfo : fields) { if(fieldInfo.getType() == char.class && Modifier.isStatic(fieldInfo.getModifiers())) { if(!fieldInfo.getName().equals("SPACE_CHAR")) mControlCharFields.add(fieldInfo); } } // Map node type integer values to their equivalent string name. mNodeTypes = new HashMap<Integer, String>(); Field[] nodeTypefields = NodeType.class.getFields(); for(Field fieldInfo : nodeTypefields) { if (fieldInfo.getType() == int.class && Modifier.isStatic(fieldInfo.getModifiers())) { try { int integerValue = fieldInfo.getInt(null); mNodeTypes.put(integerValue, fieldInfo.getName()); } catch (IllegalAccessException e) { // Skip any invalid fields. } } } // Maps header/footer type integer values to string names. mHeaderFooterTypes = new HashMap<Integer, String>(); fields = HeaderFooterType.class.getFields(); for(Field fieldInfo : fields) { if(fieldInfo.getType() == int.class && Modifier.isStatic(fieldInfo.getModifiers())) { try { int integerValue = fieldInfo.getInt(null); mHeaderFooterTypes.put(integerValue, fieldInfo.getName()); } catch (IllegalAccessException e) { // Skip any invalid fields. } } } } /** * Item class factory implementation. */ public static Item createItem(Node node) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { String typeName = getNodeTypeString(node); if (mItemSet.containsKey(typeName)) return (Item)Class.forName(mItemSet.get(typeName)). getConstructor(DocumentItems.class, Node.class). newInstance(null, node); else return new Item(node); } /** * Object.toString method used by Tree. */ public String toString() { // Introduced non-checked RuntimeException on purpose to not change Object.toString() signature try { return getName(); } catch (Exception e) { throw new RuntimeException(e); } } /** * Convert numerical representation of the node type to string. */ private static String getNodeTypeString(Node node) { int nodeType = node.getNodeType(); if(mNodeTypes.containsKey(nodeType)) return mNodeTypes.get(nodeType); else return ""; } /** * Convert numerical representation of HeaderFooter integer type to string. */ protected static String getHeaderFooterTypeAsString(HeaderFooter headerFooter) throws Exception { int headerFooterType = headerFooter.getHeaderFooterType(); if(mHeaderFooterTypes.containsKey(headerFooterType)) return mHeaderFooterTypes.get(headerFooterType); else return ""; } }