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

Last change on this file since 16333 was 16333, checked in by anna, 16 years ago

By default GLI Help reads the index files (table of content) from GLI.jar, but then updates in the local help_index.xml can't be shown in GLI unless the current GLI.jar is deleted or a new GLI.jar is created. So now the default option is changed: if GLI applet is in use, use Jar file; otherwise, read from the classes folder. This is also consistent with other read operations in the class.

  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 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 // Traverse the help hierarchy, building a tree representing its structure
238 Node document_node = document.getFirstChild();
239
240 // Add a help contents tree node for each major section
241 int section_number = 0;
242 NodeList children = document_node.getChildNodes();
243 for (int i = 0; i < children.getLength(); i++) {
244 Node child = children.item(i);
245 if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
246 section_number++;
247 buildHelpContentsTree(help_tree_root_node, section_number + StaticStrings.EMPTY_STR, child);
248 }
249 }
250 }
251 catch (Exception exception) {
252 DebugStream.printStackTrace(exception);
253 }
254 }
255
256
257 private void buildHelpContentsTree(MutableTreeNode parent, String pos, Node node)
258 {
259 // Determine the section name
260 String section_name = ((Element) node).getAttribute(StaticStrings.NAME_ATTRIBUTE);
261
262 // Determine the section title
263 String section_title = "";
264 NodeList children = node.getChildNodes();
265 for (int i = 0; i < children.getLength(); i++) {
266 Node child = children.item(i);
267 if (child.getNodeName().equals(StaticStrings.TITLE_ELEMENT)) {
268 section_title = pos + ": ";
269 if (child.getFirstChild() != null) {
270 section_title += child.getFirstChild().getNodeValue();
271 }
272 }
273 }
274
275 // Add the node into the tree
276 HelpContentsTreeNode help_tree_node = new HelpContentsTreeNode(section_name, section_title);
277 insertNodeInto(help_tree_node, parent, parent.getChildCount());
278
279 // Apply recursively to the children of this node
280 int section_number = 0;
281 for (int i = 0; i < children.getLength(); i++) {
282 Node child = children.item(i);
283 if (child.getNodeName().equals(StaticStrings.SECTION_ELEMENT)) {
284 section_number++;
285 buildHelpContentsTree(help_tree_node, pos + StaticStrings.STOP_CHARACTER + section_number, child);
286 }
287 }
288 }
289
290
291 private HelpContentsTreeNode getHelpContentsTreeNodeNamed(String section_name)
292 {
293 // Find the node with name matching section name, somewhere in the tree
294 if (section_name != null) {
295 Enumeration descendants = ((DefaultMutableTreeNode) root).preorderEnumeration();
296 while (descendants.hasMoreElements()) {
297 HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) descendants.nextElement();
298 if (section_name.equals(help_tree_node.section_name)) {
299 return help_tree_node;
300 }
301 }
302 }
303
304 // Couldn't be found, so just return the root (Contents) node
305 return (HelpContentsTreeNode) root;
306 }
307 }
308
309
310 /** This listener is used to listen for selection changes in the contents tree, and
311 * to show the appropriate page as required.
312 */
313 private class HelpContentsTreeSelectionListener
314 implements TreeSelectionListener
315 {
316 /** Any implementation of <i>TreeSelectionListener</i> must include this method so we can be informed when the tree selection changes.
317 * @param event A <strong>TreeSelectionEvent</strong> containing al the relevant information about the event itself.
318 */
319 public void valueChanged(TreeSelectionEvent event)
320 {
321 HelpContentsTreeNode help_tree_node = (HelpContentsTreeNode) event.getPath().getLastPathComponent();
322 selectHelpContentsTreeNode(help_tree_node);
323 showHelpPage(help_tree_node.section_name);
324 }
325 }
326
327
328 /** This class provides a wrapper around a <strong>DefaultMutableTreeNode</strong> which
329 * provides the ability to set an html page to be loaded when this node is selected.
330 */
331 private class HelpContentsTreeNode
332 extends DefaultMutableTreeNode
333 {
334 /** The unique name of the section (matches the HTML filename) */
335 public String section_name = null;
336 /** The title to be displayed for this tree node. */
337 public String section_title = null;
338
339 public HelpContentsTreeNode(String section_name, String section_title)
340 {
341 this.section_name = section_name;
342 this.section_title = section_title;
343 }
344
345 public String toString()
346 {
347 return section_title;
348 }
349 }
350
351
352 private class HelpPaneHyperlinkListener
353 implements HyperlinkListener
354 {
355 public void hyperlinkUpdate(HyperlinkEvent e)
356 {
357 if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
358 // Determine which node in the help contents tree to select, then select it
359 String section_link = e.getURL().getFile();
360 if (section_link.endsWith(".htm")) {
361 section_link = section_link.substring(section_link.lastIndexOf("/") + 1);
362 section_link = section_link.substring(0, section_link.length() - ".htm".length());
363 selectHelpContentsTreeNode(section_link);
364 }
365
366 // Change to the page specified by the link
367 showHelpPage(e.getURL());
368 }
369 }
370 }
371}
Note: See TracBrowser for help on using the repository browser.