/** *######################################################################### * * A component of the Gatherer application, part of the Greenstone digital * library suite from the New Zealand Digital Library Project at the * University of Waikato, New Zealand. * *

* * Principal Author: John Thompson, NZDL Project, University of Waikato * *

* * Copyright (C) 1999 New Zealand Digital Library Project * *

* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * *

* * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * *

* * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *######################################################################## */ package org.greenstone.gatherer.help; import java.awt.*; import java.io.*; import java.net.*; import java.util.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; import org.apache.xerces.parsers.DOMParser; import org.greenstone.gatherer.Dictionary; import org.greenstone.gatherer.Gatherer; import org.greenstone.gatherer.util.StaticStrings; import org.greenstone.gatherer.util.Utility; import org.w3c.dom.*; /** * This class provides a nice help facility. It is a separate frame that can be positioned * as the user wishes, and provides a contents page and the help information. * @author Michael Dewsnip, NZDL Project */ public class HelpFrame extends JFrame { static private final String NULL_STRING = ""; /** The size of the frame */ static private final Dimension SIZE = new Dimension(760, 560); /** The HTML rendering pane */ private JEditorPane view = null; /** The contents tree model */ private ContentsModel model = null; /** A contents tree for the top of the frame */ private JTree contents = null; private JSplitPane split_pane = null; public HelpFrame() { setDefaultCloseOperation(HIDE_ON_CLOSE); setSize(SIZE); Dictionary.registerText(this, "Help.Title"); view = new JEditorPane(); view.setEditable(false); view.addHyperlinkListener(new ViewHyperlinkListener()); HelpItem rootNode = new HelpItem(Dictionary.get("Help.Contents"), NULL_STRING); model = new ContentsModel(rootNode); contents = new JTree((DefaultTreeModel) model); contents.addTreeSelectionListener(new ContentsListener()); contents.setExpandsSelectedPaths(true); // Creation JPanel content_pane = (JPanel) this.getContentPane(); split_pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); JScrollPane index_scroll = new JScrollPane(contents); JScrollPane view_scroll = new JScrollPane(view); // Layout split_pane.add(index_scroll, JSplitPane.LEFT); split_pane.add(view_scroll, JSplitPane.RIGHT); content_pane.setLayout(new BorderLayout()); content_pane.add(split_pane, BorderLayout.CENTER); // Center Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize(); setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2); } private class ViewHyperlinkListener implements HyperlinkListener { public void hyperlinkUpdate(HyperlinkEvent e) { if(e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { try { view.setPage(e.getURL()); } catch(Exception exception) { Gatherer.printStackTrace(exception); } } } } public void destroy() { view = null; contents = null; } public void setView(String sectionName) { // Find the node in the tree with the specified sectionName HelpItem node = model.getHelpItemNamed(sectionName); // Ensure the node is selected and visible TreePath path = new TreePath(node.getPath()); contents.setSelectionPath(path); contents.scrollPathToVisible(path); // Display the selected page URL url = node.getURL(); if (url != null) { try { view.setPage(url); } catch (Exception exception) { Gatherer.printStackTrace(exception); } } // Make the help frame visible show(); split_pane.setDividerLocation(0.2); } private class ContentsModel extends DefaultTreeModel { public ContentsModel(MutableTreeNode rootNode) { super(rootNode); // Load the XML help file and build the contents structure from it try { DOMParser parser = new DOMParser(); parser.parse(Utility.getHelpFolder() + StaticStrings.HELP_INDEX_FILENAME); Document document = parser.getDocument(); // Traverse the document hierarchy, building a tree representing its structure Node documentNode = document.getFirstChild(); int sectionNum = 0; NodeList children = documentNode.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) { sectionNum++; buildContentsHierarchy(rootNode, sectionNum + StaticStrings.EMPTY_STR, child); } } } catch (Exception ex) { ex.printStackTrace(); } } public void buildContentsHierarchy(MutableTreeNode parent, String pos, Node node) { // Determine the section name String sectionName = ((Element) node).getAttribute(StaticStrings.NAME_ATTRIBUTE); // Determine the section title String sectionTitle = ""; NodeList children = node.getChildNodes(); for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child.getNodeName().equals(StaticStrings.TITLE_ELEMENT)) { sectionTitle = pos + ": "; if (child.getFirstChild() != null) { sectionTitle = sectionTitle + child.getFirstChild().getNodeValue(); } } } // Add the node into the tree HelpItem item = new HelpItem(sectionTitle, sectionName); insertNodeInto(item, parent, parent.getChildCount()); // Apply recursively to the children of this node int sectionNum = 0; for (int i = 0; i < children.getLength(); i++) { Node child = children.item(i); if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) { sectionNum++; buildContentsHierarchy(item, pos + StaticStrings.STOP_CHARACTER + sectionNum, child); } } } public HelpItem getHelpItemNamed(String sectionName) { // Find the node with name matching sectionName, somewhere in the tree Enumeration descendants = ((DefaultMutableTreeNode) root).preorderEnumeration(); while (descendants.hasMoreElements()) { HelpItem node = (HelpItem) descendants.nextElement(); if (node.name.equals(sectionName)) { return node; } } // Couldn't be found, so just return the root (Contents) node return (HelpItem) root; } } /** This listener is used to listen for selection changes in the contents tree, and * to show the appropriate page as required. */ private class ContentsListener implements TreeSelectionListener { /** Any implementation of TreeSelectionListener must include this method so we can be informed when the tree selection changes. * @param event A TreeSelectionEvent containing al the relevant information about the event itself. */ public void valueChanged(TreeSelectionEvent event) { TreePath path = event.getPath(); HelpItem node = (HelpItem) path.getLastPathComponent(); URL url = node.getURL(); if (url != null) { //view.showHTMLDocument(url); try { view.setPage(url); } catch (Exception exception) { Gatherer.printStackTrace(exception); } } } } /** This class provides a wrapper around a DefaultMutableTreeNode which * provides the ability to set an html page to be loaded when this node is selected. */ private class HelpItem extends DefaultMutableTreeNode { /** The unique name of the section (matches the HTML filename) */ public String name = null; /** The title to be displayed for this tree node. */ public String title = null; /** Constructor. * @param title The title to be shown for this node as a String. * @param name The name of the section as a String. */ public HelpItem(String title, String name) { this.name = name; this.title = title; } /** Method to create a url from the file name. * @return A URL that points to the file's location. */ public URL getURL() { if (name != null && !name.equals(NULL_STRING)) { try { File file = new File(Utility.getHelpFolder() + name + StaticStrings.HTM_FILE_EXTENSION); return file.toURL(); } catch (Exception e) { } } return null; } public String toString() { return title; } } }