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

📄 findinfilesthread.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 10/03/2005
 *
 * FindInFilesThread.java - Thread that does the searching for a
 * Find in Files dialog.
 * Copyright (C) 2005 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.ui.search;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.awt.Point;
import javax.swing.JTextArea;
import javax.swing.text.BadLocationException;
import javax.swing.text.Element;

import org.fife.io.UnicodeReader;
import org.fife.ui.GUIWorkerThread;


/**
 * A thread created by a <code>FindInFilesDialog</code> to do the searching.
 *
 * @author Robert Futrell
 * @version 1.0
 * @see FindInFilesDialog
 */
class FindInFilesThread extends GUIWorkerThread {

	private FindInFilesDialog dialog;
	private File directory;

	private String verboseLabelString;
	private String verboseNoFiltMatchString;
	private String dontSearchSubfoldersString;
	private String newFilesToExamineString;	
	private String occurrencesString;


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


	/**
	 * Constructor.
	 *
	 * @param dialog The "find in files" dialog.
	 * @param directory The directory in which to search.
	 */
	public FindInFilesThread(FindInFilesDialog dialog, File directory) {

		this.dialog = dialog;
		this.directory = directory;

		ResourceBundle msg = dialog.getBundle();
		verboseLabelString = "<html><em>" + msg.getString("VerboseLabel") +
							"</em>";
		verboseNoFiltMatchString = msg.getString("VerboseNoFiltMatch");
		dontSearchSubfoldersString = msg.getString("SearchSubFoldUnchecked");
		newFilesToExamineString = msg.getString("NewFilesToExamine");
		occurrencesString = " " + msg.getString("Occurrences");

	}


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


	protected MatchData createErrorMatchData(String filePath, String msg) {
		return new MatchData(filePath, "--", msg,
							MatchData.TYPE_ERROR);
	}


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


	protected MatchData createVerboseMatchData(String filePath, String msg) {
		return new MatchData(filePath, "--", verboseLabelString + msg,
							MatchData.TYPE_VERBOSE);
	}


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


	/**
	 * Converts a <code>String</code> representing a wildcard file filter into
	 * another <code>String</code> containing a regular expression good for
	 * finding files that match the wildcard expressions.<br><br>
	 * Example: For<br><br>
	 * <code>String regEx = getRegularExpressionForFileFilter("*.c");</code>
	 * <br><br>
	 * <code>regEx</code> will contain <code>^.*\.c$</code>.
	 *
	 * @param fileFilter The file filter for which to create equivalent
	 *        regular expressions.  This filter can currently only contain
	 *        the wildcards '*' and '?'.
	 * @param showErrorDialog If <code>true</code>, an error dialog is
	 *        displayed if an error occurs.
	 * @return A <code>String</code> representing an equivalent regular
	 *         expression for the string passed in.  If an error occurs,
	 *         <code>null</code> is returned.
	 */
	private String getRegularExpressionForFileFilter(String fileFilter,
										boolean showErrorDialog) {

		// Create a regex for the file filter.
		String pattern = "^" + fileFilter;
		pattern = pattern.replaceAll("\\.", "\\\\.");	// '.' => '\.'
		pattern = pattern.replaceAll("\\*", ".*");		// '*' => '.*'
		pattern = pattern.replaceAll("\\?", ".");		// '?' => '.'
		pattern = pattern.replaceAll("\\$", "\\\\\\$");	// '$' => '\$'
		pattern += "$";

		try {
			Pattern.compile(pattern);
		} catch (PatternSyntaxException pse) {
			// Do nothing; should never fail.
		}

		return pattern;

	}


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


	/**
	 * Runs the search.
	 */
	public Object construct() {

		String searchString = dialog.getSearchString();

		// Next, get the list of regular expressions to apply when deciding
		// whether or not to look in a file.  If we're on Windows, do case-
		// insensitive regexes.
		StringTokenizer st = new StringTokenizer(
								dialog.getInFilesComboBoxContents());
		Pattern[] filterStrings = new Pattern[st.countTokens()];
		int numFilterStrings = 0;
		boolean osIsWindows = System.getProperty("os.name").toLowerCase().
											indexOf("windows")>-1;
		int flags = osIsWindows ? Pattern.CASE_INSENSITIVE : 0;
		try {
			while (st.hasMoreTokens()) {
				String pattern = getRegularExpressionForFileFilter(
											st.nextToken(), true);
				if (pattern!=null)
					filterStrings[numFilterStrings++] =
									Pattern.compile(pattern, flags);
			}
		} catch (PatternSyntaxException e) {
			e.printStackTrace(); // Never happens.
		}
		if (numFilterStrings==0) {
			dialog.searchCompleted("");
			return null;
		}

		// Then, do the search.
		// The next two lines have the effect of "clearing" the results.
		dialog.clearSearchResults();
		File[] files = directory.listFiles();
		List fileList = new ArrayList();
		fileList.addAll(Arrays.asList(files));

		boolean checkSubfolders = dialog.getCheckSubfolders();
		boolean matchingLines = dialog.getShowMatchingLines();
		boolean matchCase = dialog.getMatchCase();
		boolean wholeWord = dialog.getMatchWholeWord();
		boolean useRegExpressions = dialog.getUseRegEx();
		boolean doVerboseOutput = dialog.getDoVerboseOutput();

		// Since we're using getNextMatchPosImpl, we do this to keep from
		// having to lower-case it every iteration of the loop in each file.
		// If we're using regular expressions however, we just let the regex
		// engine do it.
		if (!useRegExpressions && !matchCase)
			searchString = searchString.toLowerCase();

		long startMillis = System.currentTimeMillis();

		// Use JTextArea as it figures out line numbers for us.
		JTextArea textArea = new JTextArea();

		int numFiles = fileList.size();
		for (int i=0; i<numFiles; i++) {

			// If the user cancelled the search...
			if (Thread.currentThread().isInterrupted()) {
				dialog.searchCompleted(
					dialog.getBundle().getString("SearchTerminated"));
				return null;
			}

			File temp = (File)fileList.get(i);
			String fileFullPath = temp.getAbsolutePath();

			// If temp is a regular file (i.e., non-directory) AND exists...
			if (temp.isFile()) {

				// If the file doesn't match one of the filters from
				// "In files:", skip it.
				boolean filteredOut = true;
				for (int j=0; j<numFilterStrings; j++) {
					Matcher m = filterStrings[j].matcher(temp.getName());
					if (m.matches()) {
						filteredOut = false;
						break;
					}
				}
				if (filteredOut==true) {
					if (doVerboseOutput) {
						MatchData data = createVerboseMatchData(
								fileFullPath, verboseNoFiltMatchString);
						dialog.addMatchData(data);
					}
					continue;
				}

				// Display the file we're searching in the status bar.
				// Note that this method postpones the update to the EDT.
				dialog.setStatusText(
						dialog.getBundle().getString("SearchingFile")
						+ i + "/" + numFiles + ": " + fileFullPath);

				// NOTE:  WHAT IS THE BEST WAY TO READ IN A FILE?  WE DO IT
				// THIS WAY BECAUSE WE USE TEXTAREA LATER.

⌨️ 快捷键说明

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