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

📄 sourcebrowserplugin.java~1~

📁 具有不同语法高亮的编辑器实例
💻 JAVA~1~
📖 第 1 页 / 共 3 页
字号:
		// that this should always be a TagEntry, but we're just being
		// safe by checking here.
		else if (object instanceof TagEntry) {

			ExtendedTagEntry entry = (ExtendedTagEntry)object;

			// If we've already generated the (probably HTML) tooltip text,
			// use it.
			if (entry.cachedToolTipText!=null) {
				text = entry.cachedToolTipText;
			}

			// Create the tooltip text (HTML, or just text if only a line
			// number was found (such as #defines for C/C++).
			else {

				text = entry.pattern;

				// If we have a pattern, try to create an HTML tooltip.
				if (text!=null) {

					// To trim off the "regular expression" parts.
					text = text.substring(2, text.length()-2);

					if (getUseHTMLToolTips()) {
						// FIXME: Fix me to look line by line (as it's
						// guaranteed to be just a a line!).
						RTextEditorPane textArea = owner.getMainView().
													currentTextArea;
						String pattern = RTextUtilities.
									getRegularExpressionForLine(text, true);
						if (pattern!=null) { // i.e., the regex is okay.
							Point pos = FindDialog.getNextMatchPosRegEx(pattern,
										textArea.getText(), 0, true, true, false);
							if (pos!=null) {
								try {
									int line = textArea.getLineOfOffset(pos.x);
									text = getHTMLForLine(line);
									entry.cachedToolTipText = text;
								} catch (javax.swing.text.BadLocationException ble) {
									owner.displayException(ble);
								}
							}
						}
					}

				}

				// If all we have is a line number, use the tag's element's
				// name as the tooltip.
				else {
					text = entry.name.replaceAll("\t", " ");
				}

			} // End of else.

		} // End of else if (object instanceof TagEntry).

		// Set the tooltip text.
		treeRenderer.setToolTipText(text);

	}


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


	/**
	 * Called when the user downclicks in the ctags tree.
	 */
	public void mousePressed(MouseEvent e) {
		maybeShowPopup(e);
	}


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


	/**
	 * Called when the user up-clicks in the ctags tree.
	 */
	public void mouseReleased(MouseEvent e) {
		maybeShowPopup(e);
	}


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


	/**
	 * Refreshes the tag list for the current document.
	 */
	public void refresh() {
		// Tricks this browser into refreshing its tree using the new
		// ctags location.
		currentTextAreaPropertyChanged(new CurrentTextAreaEvent(
					owner.getMainView(),
					CurrentTextAreaEvent.TEXT_AREA_CHANGED,
					null, owner.getMainView().currentTextArea));
	}


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


	/**
	 * Sets the path used to run the ctags executable.
	 *
	 * @return The path to use.
	 * @see #getCTagsExecutableLocation
	 */
	public void setCTagsExecutableLocation(String location) {
		if (ctagsExecutableLocation==null ||
				!ctagsExecutableLocation.equals(location)) {
			ctagsExecutableLocation = location;
			ctagsFile = location==null ? null : new File(location);
			refresh(); // Redo ctags list with new executable.
		}
	}


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


	/**
	 * Makes the "tags tree" display an error message.
	 *
	 * @param errorMessage The message to display.
	 */
	private void setErrorMessage(String message) {
		DefaultMutableTreeNode root = new DefaultMutableTreeNode();
		DefaultMutableTreeNode node = new DefaultMutableTreeNode(message);
		root.add(node);
		treeModel.setRoot(root);
	}


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


	/**
	 * Sets whether HTML tooltips are used in this source browser.
	 *
	 * @param use Whether or not to use HTML tooltips.
	 * @see #getUseHTMLToolTips
	 */
	public void setUseHTMLToolTips(boolean use) {
		useHTMLToolTips = use;
	}


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


	/**
	 * Called just before this <code>Plugin</code> is removed from an
	 * RText instance.  Here we uninstall any listeners we registered.
	 *
	 * @return Whether the uninstall went cleanly.
	 */
	public boolean uninstall() {
		owner.getMainView().removeCurrentTextAreaListener(this);
		return true;
	}


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


	/**
	 * This method is overridden so that the embedded tree and its right-
	 * click popup menu are updated.
	 */
	public void updateUI() {
		super.updateUI();
		if (sourceTree!=null) {
			treeRenderer = new SourceTreeCellRenderer();
			sourceTree.setCellRenderer(treeRenderer); // So it picks up new LnF's colors??
		}
		if (rightClickMenu!=null)
			javax.swing.SwingUtilities.updateComponentTreeUI(rightClickMenu);
	}


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


	/**
	 * Called when the user clicks on a tree node.  This method attempts to
	 * find the declaration of the selected item in the current text area, and
	 * if it is found (which it should be, unless it was removed, it is
	 * selected.
	 *
	 * @param e The tree selection event.
	 */
	public void valueChanged(TreeSelectionEvent e) {
		TreePath path = sourceTree.getSelectionPath();
		// Must check for null, otherwise we get an exception on shutdown.
		if (path!=null) {
			Object object = ((DefaultMutableTreeNode)path.
								getLastPathComponent()).getUserObject();
			if (object instanceof TagEntry) {
				TagEntry entry = (TagEntry)object;
				RTextEditorPane textArea = owner.getMainView().currentTextArea;
				if (entry.pattern!=null) {
					// FIXME: Fix me to look line by line (as it's
					// guaranteed to be just a a line!).
					String pattern = RTextUtilities.getRegularExpressionForLine(
								entry.pattern.substring(2, entry.pattern.length()-2), true);
					if (pattern!=null) { // i.e., the regex is okay.
						Point pos = FindDialog.getNextMatchPosRegEx(pattern,
									textArea.getText(), 0, true, true, false);
						if (pos!=null) {
							textArea.setCaretPosition(pos.x);
							textArea.moveCaretPosition(pos.y);
							owner.setMessages(null, lineFoundText);
						}
						else {
							UIManager.getLookAndFeel().
										provideErrorFeedback(this);
							owner.setMessages(null, cantFindLineText);
						}
					}
				}
				else { // Must use line number (used by C macros, for instance).
					Element map = textArea.getDocument().getDefaultRootElement();
					Element line = map.getElement((int)entry.lineNumber-1);
					textArea.setCaretPosition(line.getStartOffset());
					textArea.moveCaretPosition(line.getEndOffset()-1);
				}
				textArea.requestFocusInWindow();	// So we can see the highlighted line.
			}
		}
	}


/*****************************************************************************/
/************************* INNER CLASSES *************************************/
/*****************************************************************************/


	/**
	 * A tag entry with an extra field to cache the tooltip text.
	 */
	class ExtendedTagEntry extends TagEntry {

		public String cachedToolTipText;

		public ExtendedTagEntry(String line) {
			super(line);
		}
	}


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


	/**
	 * Sets the appropriate icons for tree nodes (the '+' and '-' icons
	 * for nodes that can be expanded/contracted).
	 */
	class SourceTreeCellRenderer extends DefaultTreeCellRenderer {

		private Icon yellowBullet;
		private Icon greenBullet;

		public SourceTreeCellRenderer() {
			super();
			PluginClassLoader cl = (PluginClassLoader)this.getClass().
												getClassLoader();
			yellowBullet = new ImageIcon(cl.getResource(YELLOW_BULLET));
			greenBullet = new ImageIcon(cl.getResource(GREEN_BULLET));
		}

		public Component getTreeCellRendererComponent(JTree tree,
							Object value, boolean sel, boolean expanded,
							boolean leaf, int row, boolean hasFocus) {
			super.getTreeCellRendererComponent(tree, value, sel,
									expanded, leaf, row, hasFocus);
//			/*
			Object obj = ((DefaultMutableTreeNode)value).getUserObject();
			if (obj instanceof String) { // As opposed to TagEntry.
				String str = (String)obj;
				int index = str.indexOf('(');
				if (index>-1) { // Not true if ctags not found.
					setText("<html>" + str.substring(0,index) + "<b>" +
						str.substring(index) + "</b></html>");
				}
			}
//			*/
			if (leaf && value.toString().indexOf("(0)")==-1) {
				setIcon(greenBullet);
			}
			else {
				setIcon(row==0 ? fileIcon : yellowBullet);
			}
			return this;
		}

	}


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


	/**
	 * UI for the source browser tree.  This class allows for any number of
	 * left-mouse-button clicks to toggle a tree branch's expanded state.
	 */
	class SourceBrowserTreeUI extends BasicTreeUI {

		/**
		 * Overridden so any number of left mouse clicks toggles the tree
		 * node's expansion.
		 */
		protected boolean isToggleEvent(MouseEvent e) {
			if(!SwingUtilities.isLeftMouseButton(e))
				return false;
			return true;
		}

	}


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


	/**
	 * Reads output of the SourceBrowser process in a separate thread.  We
	 * do this because ctags 5.5.4 (at least on Windows) will freeze if you
	 * have it parse an invalid source file (such as a Java file containing
	 * only "ssss").  Running this in a separate thread allows us to kill the
	 * thread if the process takes too long to end and prevent the GUI from
	 * locking up.  Not doing this would result in the user having to kill
	 * the main RText process, as well as the then-zombied ctags process.
	 */
	private class ReaderThread extends Thread {

		private String toExecute;
		private Process process;
		private Object stopKey;

		public void destroyProcessIfNecessary() {
			// Be sure and always kill the process!
			if (process!=null) {
				process.destroy();
				process = null;
			}
		}

		public void run() {

			try {
				process = Runtime.getRuntime().exec(toExecute);
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(process.getInputStream()));
				//process.waitFor();
				String line = reader.readLine();
				while (line!=null && stopKey!=null) {
					TagEntry entry = new ExtendedTagEntry(line);
					ArrayList list = (ArrayList)map.get(entry.kind);
					if (list!=null) {	// A supported tag type for this language.
						// Get rid of any escapes added for '/''s.
						if (entry.pattern!=null)
							entry.pattern = entry.pattern.replaceAll("\\\\/", "/");
						list.add(entry);
					}
					line = reader.readLine();
				}
				reader.close();
			} catch (Throwable t) {
				t.printStackTrace();
			} finally {
				destroyProcessIfNecessary();
			}

		}

		public void start(String toExecute) {
			stopKey = this;
			this.toExecute = toExecute;
			super.start();
		}

		// Recommended by Java's API as a "safe" way to stop a thread.
		// stop() is deprecated and is unsafe, so we must set up a variable
		// that is polled periodically by the thread.
		public void stopSafely() {
			stopKey = null;
		}

	}


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


	/**
	 * Toggles the visibility of this source browser.
	 */
	private class ViewAction extends AbstractAction {

		public ViewAction(ResourceBundle msg) {
			putValue(NAME, msg.getString("MenuItem.View"));
			putValue(MNEMONIC_KEY, new Integer(
					msg.getString("MenuItem.View.Mnemonic").charAt(0)));
			putValue(LONG_DESCRIPTION, msg.getString("MenuItem.View.Desc"));
		}

		public void actionPerformed(ActionEvent e) {
			setActive(!isActive());
		}

	}


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

}

⌨️ 快捷键说明

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