source: gli/trunk/src/org/greenstone/gatherer/gui/HelpFrame.java@ 17005

Last change on this file since 17005 was 17005, checked in by ak19, 16 years ago

Fixed a bug (missing help files) that caused an exception when the applet runs (see Firefox > Tools > Java Console output). This minor bugfix has not solved the bigger issue though: that of the help files being missing.

  • Property svn:keywords set to Author Date Id Revision
File size: 12.0 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Principal Author: John Thompson, NZDL Project, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.io.*;
41import java.net.*;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.event.*;
45import javax.swing.tree.*;
46import org.greenstone.gatherer.Configuration;
47import org.greenstone.gatherer.DebugStream;
48import org.greenstone.gatherer.Dictionary;
49import org.greenstone.gatherer.Gatherer;
50import org.greenstone.gatherer.util.JarTools;
51import org.greenstone.gatherer.util.StaticStrings;
52import org.greenstone.gatherer.util.XMLTools;
53import org.w3c.dom.*;
54
55
56/**
57 * This class provides a nice help facility. It is a separate frame that can be positioned
58 * as the user wishes, and provides a contents page and the help information.
59 * @author Michael Dewsnip, NZDL Project
60 */
61public class HelpFrame
62 extends JFrame
63{
64 /** The size of the frame */
65 static private final Dimension SIZE = new Dimension(800, 560);
66
67 static private HelpFrame self = null;
68
69 /** The help view at the bottom of the frame. */
70 static private JEditorPane help_pane = null;
71 /** The help contents tree at the top of the frame. */
72 static private JTree help_contents_tree = null;
73 /** The help contents tree model. */
74 static private HelpContentsTreeModel help_contents_tree_model = null;
75 /** The split between the contents tree and the page view. */
76 static private JSplitPane split_pane = null;
77
78 public HelpFrame()
79 {
80 setDefaultCloseOperation(HIDE_ON_CLOSE);
81 setSize(SIZE);
82 setTitle(Dictionary.get("Help.Title"));
83
84 help_pane = new JEditorPane();
85 help_pane.setEditable(false);
86 help_pane.addHyperlinkListener(new HelpPaneHyperlinkListener());
87
88 HelpContentsTreeNode help_tree_root_node = new HelpContentsTreeNode(null, Dictionary.get("Help.Contents"));
89 help_contents_tree_model = new HelpContentsTreeModel(help_tree_root_node);
90 help_contents_tree = new JTree((DefaultTreeModel) help_contents_tree_model);
91 help_contents_tree.addTreeSelectionListener(new HelpContentsTreeSelectionListener());
92 help_contents_tree.setExpandsSelectedPaths(true);
93
94 // Creation
95 JPanel content_pane = (JPanel) this.getContentPane();
96 split_pane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
97 JScrollPane help_contents_tree_scroll = new JScrollPane(help_contents_tree);
98 JScrollPane help_pane_scroll = new JScrollPane(help_pane);
99
100 // Layout
101 split_pane.add(help_contents_tree_scroll, JSplitPane.LEFT);
102 split_pane.add(help_pane_scroll, JSplitPane.RIGHT);
103 content_pane.setLayout(new BorderLayout());
104 content_pane.add(split_pane, BorderLayout.CENTER);
105
106 // Center
107 Dimension screen_size = Toolkit.getDefaultToolkit().getScreenSize();
108 setLocation((screen_size.width - SIZE.width) / 2, (screen_size.height - SIZE.height) / 2);
109
110 // Pretty corner icon
111 this.setIconImage(JarTools.getImage("gatherer_small.gif").getImage());
112
113 self = this;
114 }
115
116 public void destroy()
117 {
118 help_contents_tree = null;
119 help_pane = null;
120 }
121
122
123 /** Retrieve the relative file path to the language-specific help index xml file. */
124 private String getHelpFolder()
125 {
126 String help_folder = "help/" + Configuration.getLanguage() + "/";
127
128 // Applet case: get help files out of JAR file
129 if (Gatherer.isApplet && JarTools.getResource("/" + help_folder) != null) {
130 return help_folder;
131 }
132
133 // Normal case: get help files out of GLI "help" folder
134 if (new File(help_folder).exists()) {
135 return help_folder;
136 }
137
138 // Resort to English
139 return "help/" + StaticStrings.ENGLISH_LANGUAGE_STR + "/";
140 }
141
142
143 private URL getURLForSection(String section_name)
144 {
145 // Form the path to the help file from the section name
146 if (section_name != null) {
147 String help_file_path = getHelpFolder() + section_name + StaticStrings.HTM_FILE_EXTENSION;
148
149 try {
150 // Applet case: get help file out of JAR file
151 if (Gatherer.isApplet) {
152 return JarTools.getResource("/" + help_file_path);
153 }
154
155 // Normal case: get help file out of GLI "help" folder
156 return (new File(help_file_path)).toURL();
157 }
158 catch (Exception exception) {
159 DebugStream.printStackTrace(exception);
160 }
161 }
162
163 return null;
164 }
165
166
167 static private void selectHelpContentsTreeNode(String section_name)
168 {
169 // Find the tree node with this section name, then select it
170 selectHelpContentsTreeNode(help_contents_tree_model.getHelpContentsTreeNodeNamed(section_name));
171 }
172
173
174 static private void selectHelpContentsTreeNode(HelpContentsTreeNode help_tree_node)
175 {
176 // Ensure the node in the help contents tree is selected and visible
177 TreePath help_tree_node_path = new TreePath(help_tree_node.getPath());
178 help_contents_tree.setSelectionPath(help_tree_node_path);
179 help_contents_tree.scrollPathToVisible(help_tree_node_path);
180 }
181
182
183 static public void setView(String section_name)
184 {
185 // Select the appropriate node in the help contents tree
186 selectHelpContentsTreeNode(section_name);
187
188 // Show the help page with the specified section name
189 self.showHelpPage(section_name);
190 }
191
192
193 private void showHelpPage(String section_name)
194 {
195 // Find the tree node with this section name, then show the page for the node
196 showHelpPage(getURLForSection(section_name));
197 }
198
199
200 private void showHelpPage(URL help_page_url)
201 {
202 // Display the selected page
203 if (help_page_url != null) {
204 try {
205 help_pane.setPage(help_page_url);
206 }
207 catch (Exception exception) {
208 DebugStream.printStackTrace(exception);
209 }
210 }
211
212 // Make the help frame visible
213 setVisible(true);
214 split_pane.setDividerLocation(0.4);
215 }
216
217
218 private class HelpContentsTreeModel
219 extends DefaultTreeModel
220 {
221 public HelpContentsTreeModel(MutableTreeNode help_tree_root_node)
222 {
223 super(help_tree_root_node);
224
225 // Load the XML help index file and build the contents structure from it
226 try {
227 String help_index_file_path = getHelpFolder() + "help_index.xml";
228 Document document = null;
229 if (Gatherer.isApplet && JarTools.getResource(help_index_file_path) != null) {
230 document = XMLTools.parseXMLFile(help_index_file_path, true);
231 }
232
233 if (new File(help_index_file_path).exists()) {
234 document = XMLTools.parseXMLFile(help_index_file_path, false);
235 }
236
237 if (document == null) {
238 String errormsg = "HelpFrame.HelpContentsTreeModel constructor(): There's no help document after parsing";
239 System.err.println(errormsg);
240 DebugStream.println(errormsg);
241 return;
242 }
243 // Traverse the help hierarchy, building a tree representing its structure
244 Node document_node = document.getFirstChild();
245
246 // Add a help contents tree node for each major section
247 int section_number = 0;
248 NodeList children = document_node.getChildNodes();
249 for (int i = 0; i < children.getLength(); i++) {
250 Node child = children.item(i);
251 if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
252 section_number++;
253 buildHelpContentsTree(help_tree_root_node, section_number + StaticStrings.EMPTY_STR, child);
254 }
255 }
256 }
257 catch (Exception exception) {
258 DebugStream.printStackTrace(exception);
259 }
260 }
261
262
263 private void buildHelpContentsTree(MutableTreeNode parent, String pos, Node node)
264 {
265 // Determine the section name
266 String section_name = ((Element) node).getAttribute(StaticStrings.NAME_ATTRIBUTE);
267
268 // Determine the section title
269 String section_title = "";
270 NodeList children = node.getChildNodes();
271 for (int i = 0; i < children.getLength(); i++) {
272 Node child = children.item(i);
273 if (child.getNodeName().equals(StaticStrings.TITLE_ELEMENT)) {
274 section_title = pos + ": ";
275 if (child.getFirstChild() != null) {
276 section_title += child.getFirstChild().getNodeValue();
277 }
278 }
279 }
280
281 // Add the node into the tree
282 HelpContentsTreeNode help_tree_node = new HelpContentsTreeNode(section_name, section_title);
283 insertNodeInto(help_tree_node, parent, parent.getChildCount());
284
285 // Apply recursively to the children of this node
286 int section_number = 0;
287 for (int i = 0; i < children.getLength(); i++) {
288 Node child = children.item(i);
289 if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
290 section_number++;
291 buildHelpContentsTree(help_tree_node, pos + StaticStrings.STOP_CHARACTER + section_number, child);
292 }
293 }
294 }
295
296
297 private HelpContentsTreeNode getHelpContentsTreeNodeNamed(String section_name)
298 {
299 // Find the node with name matching section name, somewhere in the tree
300 if (section_name != null) {
301 Enumeration descendants = ((DefaultMutableTreeNode) root).preorderEnumeration();
302 while (descendants.hasMoreElements()) {
303 HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) descendants.nextElement();
304 if (section_name.equals(help_tree_node.section_name)) {
305 return help_tree_node;
306 }
307 }
308 }
309
310 // Couldn't be found, so just return the root (Contents) node
311 return (HelpContentsTreeNode) root;
312 }
313 }
314
315
316 /** This listener is used to listen for selection changes in the contents tree, and
317 * to show the appropriate page as required.
318 */
319 private class HelpContentsTreeSelectionListener
320 implements TreeSelectionListener
321 {
322 /** Any implementation of <i>TreeSelectionListener</i> must include this method so we can be informed when the tree selection changes.
323 * @param event A <strong>TreeSelectionEvent</strong> containing al the relevant information about the event itself.
324 */
325 public void valueChanged(TreeSelectionEvent event)
326 {
327 HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) event.getPath().getLastPathComponent();
328 selectHelpContentsTreeNode(help_tree_node);
329 showHelpPage(help_tree_node.section_name);
330 }
331 }
332
333
334 /** This class provides a wrapper around a <strong>DefaultMutableTreeNode</strong> which
335 * provides the ability to set an html page to be loaded when this node is selected.
336 */
337 private class HelpContentsTreeNode
338 extends DefaultMutableTreeNode
339 {
340 /** The unique name of the section (matches the HTML filename) */
341 public String section_name = null;
342 /** The title to be displayed for this tree node. */
343 public String section_title = null;
344
345 public HelpContentsTreeNode(String section_name, String section_title)
346 {
347 this.section_name = section_name;
348 this.section_title = section_title;
349 }
350
351 public String toString()
352 {
353 return section_title;
354 }
355 }
356
357
358 private class HelpPaneHyperlinkListener
359 implements HyperlinkListener
360 {
361 public void hyperlinkUpdate(HyperlinkEvent e)
362 {
363 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
364 // Determine which node in the help contents tree to select, then select it
365 String section_link = e.getURL().getFile();
366 if (section_link.endsWith(".htm")) {
367 section_link = section_link.substring(section_link.lastIndexOf("/") + 1);
368 section_link = section_link.substring(0, section_link.length() - ".htm".length());
369 selectHelpContentsTreeNode(section_link);
370 }
371
372 // Change to the page specified by the link
373 showHelpPage(e.getURL());
374 }
375 }
376 }
377}
Note: See TracBrowser for help on using the repository browser.