⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 helpdialog.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
/*
 * 11/14/2003
 *
 * HelpDialog.java - A "Help" dialog box for use in Java applications.
 * Copyright (C) 2003 Robert Futrell
 * email@address.com
 * www.website.com
 *
 * 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 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.fife.help;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.text.Document;
import javax.swing.text.Position;
import javax.swing.text.html.HTMLDocument;

import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.InputSource;


import org.fife.RListSelectionModel;
import org.fife.RTreeSelectionModel;
import org.fife.RUtilities;
import org.fife.ui.RButton;
import org.fife.ui.RScrollPane;
import org.fife.ui.StatusBar;
import org.fife.ui.UIUtilities;
import org.fife.ui.app.GUIApplication;


/**
 * A help dialog similar to those found in most Microsoft Windows programs.
 * The dialog contains a pane with Contents, Index, and Search tabs, each
 * of which yields the expected way to find help.  Help pages should be
 * HTML.<p>
 * 
 * Features of <code>HelpDialog</code> include:
 * <ul>
 *    <li>Contents/Index/Search pane - Works just like most Windows programs'
 *        Contents/Index/Search.  Pick your favorite way to find help.</li>
 *    <li>Search/Index options automatically find all help documents (which you
 *        pass to HelpDialog) containing the word/phrase for which the user
 *        wants to find help.</li>
 *    <li>History - The HelpDialog class will remember the help documents
 *        the user has previously visited, and the user can use the Back and
 *        Forward buttons to easily traverse previous help.
 *    <li>HTML Help - Help documents are HTML, to allow for easy formatting.
 *        </li>
 * </ul>
 *
 * Notes:<br>
 *   In your HTML documentation, anchors can be used as hyperlinks; however,
 *   if you have a hyperlink that is simply an anchor to another place in the
 *   current HTML file (<code>a href="#anchor"</code> as opposed to
 *   <code>a href="file2.html#anchor"</code>), you need to explicitly state
 *   that the anchor is in the current file (i.e.,
 *   <code>a href="file2.html#anchor"</code>) for this class to parse it
 *   correctly.
 *
 * @author Robert Futrell
 * @version 1.0
 */
public class HelpDialog extends JFrame implements ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3120550294746862067L;

	private GUIApplication guiApp;

	private JTabbedPane tabbedPane;
	private DefaultMutableTreeNode root;

	private JTree tocTree;				// Tree laying out the table of contents.
	private boolean rootVisible;

	private JEditorPane editorPane;		// Right-hand pane; displays actual help.

	private JList indexList;				// List of all elements in our index.
	private JButton indexDisplayButton;	// Display button on the "Index" tab.
	private JTextField indexField;		// Text field in which they can type in an index value.

	private JList searchList;			// List of all found documents on Search panel.
	private JButton searchDisplayButton;	// Display button on the "Search" tab.
	private JButton listTopicsButton;		// Button to display help topics matching searchString.
	private JTextField searchField;		// Text field tp type a string to search for.

	private JButton backButton;			// "Back" button on toolbar.
	private JButton forwardButton;		// "Forward" button on toolbar.

	private String searchString;			// What to look for in the search tab.
	private boolean highlightSearchString;

	private ArrayList history;			// All HelpTreeNodes the user has previoiusly viewed.
	private int historyPos;				// Position in history array we're at.
	private boolean updateHistory;		// If true, selecting a tocTree node updates history.

	private boolean clickedOnTOCTree;		// Whether they clicked on tocTree to go to a help page.

	private JLabel keywordToFindLabel;
	private JLabel keywordToFindLabel2;
	private JLabel topicToDisplayLabel;

	private String baseDir;
	private URL baseURL;

	private ResourceBundle treeBundle;

	private String[] indexElements;

	private static final String HTML_TYPE		= "text/html";
	private static final String TEXT_TYPE		= "text/plain";

	private static final String NO_MATCH_HTML	= "<html><body>" +
				"<h2>No matches found in Help.</h2>" +
				"<HR ALIGN=\"center\" WIDTH=\"100%\">" +
				"</body></html>";

	// tags used in nodes.
	private static final String INDEXITEMS		= "IndexItems";
	private static final String NAME			= "name";
	private static final String PAGE			= "Page";
	private static final String PAGE_VALUE		= "page";
	private static final String PROPERTIES_FILE	= "PropertiesFile";
	private static final String ROOT_ELEMENT	= "HelpDialogContents";
	private static final String TREE_NODE		= "Node";
	private static final String TREE_ROOT_NODE	= "RootNode";
	private static final String VISIBLE		= "visible";


/*****************************************************************************/


	/**
	 * Creates a new help dialog.
	 *
	 * @param owner The frame that owns this dialog.
	 * @param contentsFile The XML file specifying the structure of this
	 *                     online help.
	 * @param baseDir The directory in which all help stuff is stored.  This
	 *                will also be used as the base directory for relative
	 *                links in the HTML of the online help.
	 */
	public HelpDialog(GUIApplication owner, String contentsFile,
										String baseDir) {

		// Make the title of the dialog appropriate.
		super();
		this.guiApp = owner;

		// Create some stuff we'll need below.
		ResourceBundle msg = getHelpBundle();
		HelpListener listener = new HelpListener();

		// Set the base URL.
		this.baseDir = baseDir;
		try {
			setBaseURL(new URL("file:///" + baseDir));
		} catch (Exception e) {
			guiApp.displayException(this, e);
		}

		// Create the DefaultMutableTreeNode tree that will be our "tree" of
		// help pages.
		createRoot(contentsFile);

		// Make a text area for the right-component of the split pane (the HTML help).
		editorPane = new JEditorPane();
		editorPane.setFont(new Font("monospaced", Font.PLAIN, 12));
		editorPane.setPreferredSize(new Dimension(81*8,300));
		editorPane.setEditable(false);
		editorPane.addHyperlinkListener(listener);
		editorPane.setContentType("text/html");
		editorPane.getDocument().putProperty("IgnoreCharsetDirective", Boolean.TRUE);

		// Create contents subpanel for the left-component of the split pane.
		JPanel tocPanel = UIUtilities.createTabbedPanePanel();
		tocPanel.setLayout(new BoxLayout(tocPanel, BoxLayout.Y_AXIS));
		tocPanel.setBorder(UIUtilities.getEmpty5Border());
		tocTree = new JTree(root);
		tocTree.setRootVisible(rootVisible);	// Set in initializeFromXMLFile().
		tocTree.setSelectionModel(new RTreeSelectionModel());
		tocTree.setToggleClickCount(1);
		tocTree.addTreeSelectionListener(listener);
		tocTree.addKeyListener(listener);
		JScrollPane scrollPane = new RScrollPane(1,1, tocTree);
		scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		tocPanel.add(scrollPane);

		// Create the index subpanel for the left-component of the split pane.
		JPanel indexPanel = UIUtilities.createTabbedPanePanel();
		indexPanel.setLayout(new BoxLayout(indexPanel, BoxLayout.Y_AXIS));
		indexPanel.setBorder(UIUtilities.getEmpty5Border());
		JPanel indexInputPanel = UIUtilities.createTabbedPanePanel();
		indexInputPanel.setLayout(new BoxLayout(indexInputPanel, BoxLayout.Y_AXIS));
		keywordToFindLabel = new JLabel(msg.getString("KeywordLabel"));
		JPanel ilPanel = UIUtilities.createTabbedPanePanel();
		ilPanel.setLayout(new BoxLayout(ilPanel, BoxLayout.X_AXIS));
		ilPanel.add(keywordToFindLabel);
		ilPanel.add(Box.createHorizontalGlue());
		indexField = new JTextField();
		indexField.setMaximumSize(new Dimension(3000,20));
		indexField.getDocument().addDocumentListener(listener);
		indexField.addKeyListener(listener);
		indexInputPanel.add(ilPanel);
		indexInputPanel.add(indexField);
		indexList = new JList(indexElements);
		indexElements = null;
		indexList.addMouseListener(listener);
		indexList.addKeyListener(listener);
		indexList.setSelectionModel(new RListSelectionModel());
		JScrollPane indexScrollPane = new RScrollPane(1,1, indexList);
		indexScrollPane.setPreferredSize(new Dimension(100,200));
		indexScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		JPanel indexButtonPanel = UIUtilities.createTabbedPanePanel();
		indexButtonPanel.setLayout(new BoxLayout(indexButtonPanel, BoxLayout.X_AXIS));
		indexDisplayButton = UIUtilities.createTabbedPaneButton(msg.getString("Display"));
		indexDisplayButton.setActionCommand("Display");
		indexDisplayButton.addActionListener(this);
		indexButtonPanel.add(Box.createHorizontalGlue());
		indexButtonPanel.add(indexDisplayButton);
		indexPanel.add(indexInputPanel);
		indexPanel.add(Box.createVerticalStrut(8));
		indexPanel.add(indexScrollPane);
		indexPanel.add(Box.createVerticalStrut(8));
		indexPanel.add(indexButtonPanel);
		indexList.setSelectedIndex(0);

		// Create the search subpanel for the left-component of the split pane.
		JPanel searchPanel = UIUtilities.createTabbedPanePanel();
		searchPanel.setLayout(new BoxLayout(searchPanel, BoxLayout.Y_AXIS));
		searchPanel.setBorder(UIUtilities.getEmpty5Border());
		JPanel searchInputPanel = UIUtilities.createTabbedPanePanel();
		searchInputPanel.setLayout(new BoxLayout(searchInputPanel, BoxLayout.Y_AXIS));
		keywordToFindLabel2 = new JLabel(msg.getString("KeywordLabel"));
		JPanel slPanel = UIUtilities.createTabbedPanePanel();
		slPanel.setLayout(new BoxLayout(slPanel, BoxLayout.X_AXIS));
		slPanel.add(keywordToFindLabel2);
		slPanel.add(Box.createHorizontalGlue());
		searchField = new JTextField();
		searchField.setMaximumSize(new Dimension(3000,20));
		searchField.getDocument().addDocumentListener(listener);
		searchField.addKeyListener(listener);
		listTopicsButton = UIUtilities.createTabbedPaneButton(msg.getString("ListTopics"));
		listTopicsButton.setActionCommand("ListTopics");
		listTopicsButton.addActionListener(this);
		listTopicsButton.setEnabled(false);
		JPanel ltbPanel = UIUtilities.createTabbedPanePanel();
		ltbPanel.setLayout(new BoxLayout(ltbPanel, BoxLayout.X_AXIS));
		ltbPanel.add(Box.createHorizontalGlue());
		ltbPanel.add(listTopicsButton);
		topicToDisplayLabel = new JLabel(msg.getString("TopicToDisplay"));
		JPanel stlPanel = UIUtilities.createTabbedPanePanel();
		stlPanel.setLayout(new BoxLayout(stlPanel, BoxLayout.X_AXIS));
		stlPanel.add(topicToDisplayLabel);
		stlPanel.add(Box.createHorizontalGlue());
		searchInputPanel.add(slPanel);
		searchInputPanel.add(Box.createHorizontalGlue());
		searchInputPanel.add(searchField);
		searchInputPanel.add(Box.createVerticalStrut(5));
		searchInputPanel.add(ltbPanel);
		searchList = new JList();
		searchList.addMouseListener(listener);
		searchList.addKeyListener(listener);
		searchList.setSelectionModel(new RListSelectionModel());
		JScrollPane searchScrollPane = new RScrollPane(1,1, searchList);
		searchScrollPane.setPreferredSize(new Dimension(100,200));
		searchScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		JPanel searchButtonPanel = UIUtilities.createTabbedPanePanel();
		searchButtonPanel.setLayout(new BoxLayout(searchButtonPanel, BoxLayout.X_AXIS));
		searchDisplayButton = UIUtilities.createTabbedPaneButton(msg.getString("Display"));
		searchDisplayButton.setActionCommand("Display");
		searchDisplayButton.addActionListener(this);
		searchDisplayButton.setEnabled(false);
		searchButtonPanel.add(Box.createHorizontalGlue());
		searchButtonPanel.add(searchDisplayButton);
		searchPanel.add(searchInputPanel);
		searchPanel.add(Box.createVerticalStrut(5));
		searchPanel.add(stlPanel);
		searchPanel.add(searchScrollPane);
		searchPanel.add(Box.createVerticalStrut(8));
		searchPanel.add(searchButtonPanel);

		// Put the subpanels for the left frame into a tabbed pane.
		tabbedPane = new JTabbedPane();
		tabbedPane.addChangeListener(listener);
		tabbedPane.addTab(msg.getString("Contents"), tocPanel);
		tabbedPane.addTab(msg.getString("Index"), indexPanel);
		tabbedPane.addTab(msg.getString("Search"), searchPanel);

		// Create the Help dialog's left panel.
		JPanel leftPanel = new JPanel(new GridLayout(1,1));
		leftPanel.setPreferredSize(new Dimension(300,400));
		leftPanel.add(tabbedPane);

		// Create the split pane.
		JSplitPane splitPane = new JSplitPane();
		splitPane.setLeftComponent(leftPanel);
		JScrollPane rightScrollPane = new RScrollPane(400,200, editorPane);
		rightScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		splitPane.setRightComponent(rightScrollPane);

		// Make the toolbar.
		JToolBar toolBar = new JToolBar();
		backButton = new RButton(msg.getString("Back"));
		backButton.setActionCommand("Back");
		backButton.addActionListener(this);
		backButton.setEnabled(false);
		toolBar.add(backButton);
		forwardButton = new RButton(msg.getString("Forward"));
		forwardButton.setActionCommand("Forward");
		forwardButton.addActionListener(this);
		forwardButton.setEnabled(false);
		toolBar.add(forwardButton);
		toolBar.setFloatable(false);

		// Make our help dialog!
		Container contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(toolBar, BorderLayout.NORTH);
		contentPane.add(splitPane, BorderLayout.CENTER);
		contentPane.add(new StatusBar(""), BorderLayout.SOUTH);
		pack();

		// Initially, the use hasn't viewed any nodes.
		history = new ArrayList();
		updateHistory = true;
		clickedOnTOCTree = true;		// Initially, we assume they click on tocTree first.
		historyPos = -1;				// Initially, there is no history to point to.

		// By default, our tree is open to the first node.
		// This will select it in the tocTree and bring up first help page.
		tocTree.setSelectionRow(0);

		// We must reset backButton to be disabled, as setSelectionRow enables it.
		backButton.setEnabled(false);

		// Get ready to go!
		setTitle(msg.getString("Title"));
		msg = null; // May help in GC.
		setIconImage(owner.getIconImage());
		pack();

	}


/*****************************************************************************/


	// Callback for when an action occurs.
	public void actionPerformed(ActionEvent e) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -