📄 findinfilesdialog.java
字号:
/*
* 11/26/2003
*
* FindInFilesDialog.java - A dialog that allows you to search for text
* in all files in a directory.
* 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.ui.search;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.text.JTextComponent;
import org.fife.RUtilities;
import org.fife.ui.FSATextField;
import org.fife.ui.RButton;
import org.fife.ui.RComboBoxModel;
import org.fife.ui.RScrollPane;
import org.fife.ui.StatusBar;
import org.fife.ui.UIUtilities;
import org.fife.ui.rtextfilechooser.RDirectoryChooser;
/**
* A dialog allowing the user to search for a text string in all files in a
* directory, so they don't have to do the files one at a time.
*
* @author Robert Futrell
* @version 0.8
*/
public class FindInFilesDialog extends AbstractSearchDialog
implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 2000876159791476172L;
/**
* Property notification sent out when the user does a search. This
* notifies that the list of search strings in the "Find what" combo box
* has changed. Note that the "old" value will always be
* <code>null</code>; the "new" value is a <code>Vector</code> of strings
* containing the new values.
*/
public static final String SEARCH_STRINGS_PROPERTY = "FindInFilesDialog.searchStrings";
// Text fields in which the user enters parameters that are not
// defined in AbstractSearchDialog.
private JComboBox inFilesComboBox;
private FSATextField inFolderTextField;
private JCheckBox subfoldersCheckBox;
private JButton findButton;
private JButton browseButton;
private JRadioButton matchingLinesRadioButton;
private JRadioButton fileCountsOnlyRadioButton;
private JCheckBox verboseCheckBox;
private StatusBar statusBar;
private FindInFilesTable resultsTable;
// This helps us work around the "bug" where JComboBox eats the first
// Enter press.
private String lastSearchString;
private String lastInFilesString;
// The listener list for FindInFilesEvents.
private EventListenerList eventListenerList;
private FindInFilesThread workerThread;
// Some strings cached from our resources for efficiency.
private ResourceBundle resources;
private String defaultStatusText;
private String searchingCompleteString;
/*****************************************************************************/
/**
* Creates a new <code>FindInFilesDialog</code>.
*
* @param owner The main window that owns this dialog.
*/
public FindInFilesDialog(Frame owner) {
this(owner, ResourceBundle.getBundle("org.fife.ui.search.Search"));
}
/*****************************************************************************/
/**
* Creates a new <code>FindInFilesDialog</code>.
*
* @param owner The owner of this dialog.
* @param msg The resource bundle.
*/
public FindInFilesDialog(Frame owner, ResourceBundle msg) {
super(owner, msg, true);
this.setTitle(msg.getString("FindInFilesDialogTitle"));
// These listeners will be used by all text fields.
FindInFilesDocumentListener documentListener = new FindInFilesDocumentListener();
FindInFilesFocusAdapter focusAdapter = new FindInFilesFocusAdapter();
FindInFilesKeyListener keyListener = new FindInFilesKeyListener();
// Set the main content pane for the "Find in Files" dialog.
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
setContentPane(contentPane);
// Make a "Find what" combo box.
findTextComboBox.setEditable(true);
JTextComponent textField = getTextComponent(findTextComboBox);
textField.addFocusListener(focusAdapter);
textField.addKeyListener(keyListener);
textField.getDocument().addDocumentListener(documentListener);
// Make an "In files" combo box.
inFilesComboBox = new JComboBox(new RComboBoxModel());
inFilesComboBox.setEditable(true);
textField = getTextComponent(inFilesComboBox);
textField.addFocusListener(focusAdapter);
textField.addKeyListener(keyListener);
textField.getDocument().addDocumentListener(documentListener);
// Make an "In folder" text field.
// NOTE: Change the line below for "directories only", but
// SLOW NFS paths because of File.isDirectory()...
inFolderTextField = new FSATextField();//true);
inFolderTextField.setText(System.getProperty("user.home"));
inFolderTextField.addFocusListener(focusAdapter);
inFolderTextField.getDocument().addDocumentListener(documentListener);
// Make a panel containing the edit boxes and their associated labels.
JPanel inputPanel = new JPanel(new SpringLayout());
// Make labels to go with the combo boxes/text fields.
JLabel findLabel = new JLabel(msg.getString("FindWhat"));
findLabel.setLabelFor(findTextComboBox);
findLabel.setDisplayedMnemonic((int)msg.getString("FindWhatMnemonic").charAt(0));
JLabel inLabel = new JLabel(msg.getString("InFiles"));
inLabel.setLabelFor(inFilesComboBox);
inLabel.setDisplayedMnemonic((int)msg.getString("InFilesMnemonic").charAt(0));
JLabel dirLabel = new JLabel(msg.getString("InDirectory"));
dirLabel.setLabelFor(inFolderTextField);
dirLabel.setDisplayedMnemonic((int)msg.getString("InDirectoryMnemonic").charAt(0));
// Make a panel of the edit fields and add it to inputPanel.
inputPanel.add(findLabel);
inputPanel.add(findTextComboBox);
inputPanel.add(inLabel);
inputPanel.add(inFilesComboBox);
inputPanel.add(dirLabel);
inputPanel.add(inFolderTextField);
RUtilities.makeSpringCompactGrid(inputPanel,
3,2, // rows,cols,
0,0, // initial-x, initial-y,
5,5); // x-spacing, y-spacing.
// Make a "Conditions" panel.
JPanel conditionsPanel = new JPanel();
conditionsPanel.setBorder(createTitledBorder(msg.getString("Conditions")));
conditionsPanel.setLayout(new BoxLayout(conditionsPanel, BoxLayout.Y_AXIS));
conditionsPanel.add(caseCheckBox);
conditionsPanel.add(wholeWordCheckBox);
conditionsPanel.add(regExpCheckBox);
// Make a "Report detail" panel.
JPanel detailPanel = new JPanel();
detailPanel.setBorder(createTitledBorder(msg.getString("ReportDetail")));
detailPanel.setLayout(new BoxLayout(detailPanel, BoxLayout.Y_AXIS));
matchingLinesRadioButton = new JRadioButton(msg.getString("MatchingLines"));
RUtilities.setMnemonic(matchingLinesRadioButton, msg.getString("MatchingLinesMnemonic"));
matchingLinesRadioButton.setSelected(true);
detailPanel.add(matchingLinesRadioButton);
fileCountsOnlyRadioButton = new JRadioButton(msg.getString("FileCounts"));
RUtilities.setMnemonic(fileCountsOnlyRadioButton, msg.getString("FileCountsMnemonic"));
ButtonGroup bg = new ButtonGroup();
bg.add(matchingLinesRadioButton);
bg.add(fileCountsOnlyRadioButton);
detailPanel.add(fileCountsOnlyRadioButton);
// Make a panel containing the "Report detail" panel and some checkboxes.
JPanel detailEtcPanel = new JPanel();
detailEtcPanel.setLayout(new BoxLayout(detailEtcPanel, BoxLayout.Y_AXIS));
subfoldersCheckBox = new JCheckBox(msg.getString("SearchSubfolders"));
subfoldersCheckBox.setMnemonic((int)msg.getString("SearchSubfoldersMnemonic").charAt(0));
detailEtcPanel.add(detailPanel);
detailEtcPanel.add(subfoldersCheckBox);
// Make a panel containing the "Conditions" and "detailEtc" panels.
JPanel bottomLeftPanel = new JPanel();
bottomLeftPanel.setLayout(new BoxLayout(bottomLeftPanel, BoxLayout.X_AXIS));
bottomLeftPanel.add(conditionsPanel);
bottomLeftPanel.add(Box.createRigidArea(new Dimension(10,5)));
bottomLeftPanel.add(detailEtcPanel);
bottomLeftPanel.add(Box.createHorizontalGlue());
// Make a panel containing all of the text fields, and the bottom left panel.
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
leftPanel.add(inputPanel);
leftPanel.add(bottomLeftPanel);
// Make a panel containing the buttons.
JPanel rightPanel2 = new JPanel(new GridLayout(3,1, 5,5));
findButton = new RButton(msg.getString("Find"));
findButton.setMnemonic((int)msg.getString("FindMnemonic").charAt(0));
findButton.setActionCommand("FindInFiles");
findButton.addActionListener(this);
browseButton = new RButton(msg.getString("Browse"));
browseButton.setMnemonic((int)msg.getString("BrowseMnemonic").charAt(0));
browseButton.setActionCommand("Browse");
browseButton.addActionListener(this);
cancelButton = new RButton(msg.getString("Close"));
cancelButton.setMnemonic((int)msg.getString("CloseMnemonic").charAt(0));
cancelButton.setActionCommand("Close");
cancelButton.addActionListener(this);
rightPanel2.add(findButton);
rightPanel2.add(browseButton);
rightPanel2.add(cancelButton);
JPanel rightPanel = new JPanel(new BorderLayout());
rightPanel.setBorder(BorderFactory.createEmptyBorder(0,5,0,0));
rightPanel.add(rightPanel2, BorderLayout.NORTH);
// Combine leftPanel and rightPanel.
JPanel topPanel = new JPanel(new BorderLayout());
topPanel.add(leftPanel);
topPanel.add(rightPanel, BorderLayout.EAST);
// Make a panel containing a "Verbose output" checkbox.
JPanel verbosePanel = new JPanel();
verbosePanel.setLayout(new BoxLayout(verbosePanel, BoxLayout.X_AXIS));
verboseCheckBox = new JCheckBox(msg.getString("Verbose"));
verboseCheckBox.setMnemonic((int)msg.getString("VerboseMnemonic").charAt(0));
verbosePanel.add(verboseCheckBox);
verbosePanel.add(Box.createHorizontalGlue());
// Make the "results" panel.
JPanel resultsPanel = new JPanel(new GridLayout(1,1, 3,3));
Border empty5Border = UIUtilities.getEmpty5Border();
resultsPanel.setBorder(BorderFactory.createCompoundBorder(
empty5Border,
BorderFactory.createCompoundBorder(
createTitledBorder(msg.getString("Results")),
BorderFactory.createEmptyBorder(3,3,3,3)
)));
resultsTable = new FindInFilesTable();
resultsTable.addMouseListener(new FindInFilesDialogMouseListener(resultsTable));
JScrollPane resultsScrollPane = new RScrollPane(resultsTable);
resultsScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
resultsScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
resultsPanel.add(resultsScrollPane);
// Make the "status bar."
statusBar = new org.fife.ui.StatusBar();
// Initialize some variables.
eventListenerList = new EventListenerList();
this.resources = msg;
defaultStatusText = resources.getString("DefaultStatusText");
searchingCompleteString = resources.getString("SearchingComplete");
// Put everything together.
setStatusText(defaultStatusText);
JPanel temp = new JPanel();
temp.setBorder(empty5Border);
temp.setLayout(new BoxLayout(temp, BoxLayout.Y_AXIS));
temp.add(topPanel);
temp.add(Box.createVerticalStrut(5));
temp.add(verbosePanel);
contentPane.add(temp, BorderLayout.NORTH);
contentPane.add(resultsPanel);
contentPane.add(statusBar, BorderLayout.SOUTH);
getRootPane().setDefaultButton(findButton);
setModal(false);
pack();
inFolderTextField.discoverParentWindow();
setLocationRelativeTo(owner);
}
/*****************************************************************************/
/**
* Called whenever the user does something.
*/
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
// If the user selects the "Find" button...
if (actionCommand.equals("FindInFiles")) {
// Add the "Find What" item to the combo box's list. Then, if
// they just searched for an item that's already in the list
// other than the first, move it to the first position.
findTextComboBox.addItem(getTextComponent(findTextComboBox).getText());
if (findTextComboBox.getSelectedIndex()>0) {
Object item = findTextComboBox.getSelectedItem();
findTextComboBox.removeItem(item);
findTextComboBox.insertItemAt(item, 0);
findTextComboBox.setSelectedIndex(0);
}
// Add the "In Files" item to the combo box's list. Then, if
// they just searched for an item that's already in the list
// other than the first, move it to the first position.
inFilesComboBox.addItem(getTextComponent(inFilesComboBox).getText());
if (inFilesComboBox.getSelectedIndex()>0) {
Object item = inFilesComboBox.getSelectedItem();
inFilesComboBox.removeItem(item);
inFilesComboBox.insertItemAt(item, 0);
inFilesComboBox.setSelectedIndex(0);
}
// Update our "master list" of search strings.
firePropertyChange(SEARCH_STRINGS_PROPERTY,
null, getSearchStrings());
// Actually perform the search.
doFindInFiles();
} // End of if (actionCommand.equals("FindInFiles")).
// If the user selects the "Browse..." button...
else if (actionCommand.equals("Browse")) {
RDirectoryChooser chooser = new RDirectoryChooser(this);
chooser.setVisible(true);
String directory = chooser.getChosenDirectory();
if (directory!=null) {
inFolderTextField.setFileSystemAware(false);
inFolderTextField.setText(directory);
inFolderTextField.setFileSystemAware(true);
}
}
// If the user selects the Close/Stop button...
else if (actionCommand.equals("Close")) {
FindInFilesThread workerThread = getWorkerThread();
if (workerThread!=null) { // Search going on => stop search.
workerThread.interrupt();
setSearching(false);
}
else { // No search => close the dialog.
this.setVisible(false);
}
}
// The superclass might care about this action.
else
super.actionPerformed(e);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -