📄 finddialog.java~2~
字号:
/*
* FindDialog - Dialog for finding text in a GUI.
*/
package org.fife.ui.search;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ResourceBundle;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SpringLayout;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.fife.RUtilities;
import org.fife.ui.RButton;
import org.fife.ui.UIUtilities;
/**
* A "Find" dialog similar to those found in most Windows text editing
* applications. Contains many search options, including:<br>
* <ul>
* <li>Match Case</li>
* <li>Match Whole Word</li>
* <li>Use Regular Expressions</li>
* <li>Search Forwards or Backwards</li>
* </ul>
* The dialog also remembers your previous several selections in a combo box.
* <p>An application can use a <code>FindDialog</code> as follows. It is suggested
* that you create an <code>Action</code> or something similar to facilitate
* "bringing up" the Find dialog. Have the main application contain an object
* that implements both <code>PropertyChangeListener</code> and
* <code>ActionListener</code>. This object will receive the following events from
* the Find dialog:
* <ul>
* <li>"FindNext" action when the user clicks the "Find" button.</li>
* <li>"SearchDialog.MatchCase" property change when the user checks/unchecks the
* Match Case checkbox.</li>
* <li>"SearchDialog.MatchWholeWord" property change when the user checks/unchecks
* the Whole Word checkbox.</li>
* <li>"SearchDialog.UseRegularExpressions" property change when the user checks/unchecks
* the "Regular Expressions" checkbox.</li>
* <li>"SearchDialog.SearchDownward" property change when the user clicks either
* the Up or Down direction radio button.</li>
* </ul>
* Upon receiving the "FindNext" action from the Find dialog, the application can
* then use one of the Find dialog's static <code>getNextMatchPos</code> or
* <code>getNextMatchPosRegEx</code> methods to run the search on a given text
* component via its document.
* <p>The property events listed can all be ignored in a simple case; the Find dialog will
* remember the state of its checkboxes between invocations. However, if your application
* has both a Find and Replace dialog, you may wish to use these messages to synchronize
* the two search dialogs' options.
*
* @author Robert Futrell
* @version 1.0
*/
public class FindDialog extends AbstractFindReplaceDialog implements ActionListener {
/**
*
*/
private static final long serialVersionUID = 453120603537081734L;
private JButton findNextButton;
private JLabel findFieldLabel;
// This helps us work around the "bug" where JComboBox eats the first Enter
// press.
private String lastSearchString;
/*****************************************************************************/
/**
* Creates a new <code>FindDialog</code>.
*
* @param owner The main window that owns this dialog.
* @param actionListener The component that listens for "Find" actions.
*/
public FindDialog(Frame owner, ActionListener actionListener) {
this(owner, actionListener,
ResourceBundle.getBundle("org.fife.ui.search.Search"));
}
/*****************************************************************************/
/**
* Creates a new <code>FindDialog</code>.
*
* @param owner The main window that owns this dialog.
* @param actionListener The component that listens for "Find" actions.
* @param resources The resource bundle from which to get strings, etc.
*/
public FindDialog(Frame owner, ActionListener actionListener,
ResourceBundle resources) {
// Let it be known who the owner of this dialog is.
super(owner, resources, true);
// Make a panel containing the "Find" edit box.
JPanel enterTextPane = new JPanel(new SpringLayout());
enterTextPane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
JTextField textField = (JTextField)findTextComboBox.getEditor().getEditorComponent();
textField.addFocusListener(new FindFocusAdapter());
textField.addKeyListener(new FindKeyListener());
textField.getDocument().addDocumentListener(new FindDocumentListener());
findFieldLabel = new JLabel((String)resources.getString("FindWhat"));
findFieldLabel.setDisplayedMnemonic((int)resources.getString("FindWhatMnemonic").charAt(0));
findFieldLabel.setLabelFor(findTextComboBox);
enterTextPane.add(findFieldLabel);
enterTextPane.add(findTextComboBox); // Defined in superclass.
RUtilities.makeSpringCompactGrid(enterTextPane, 1, 2, //rows, cols
0,0, //initX, initY
6, 6); //xPad, yPad
// Make a panel containing the inherited search direction radio
// buttons and the inherited search options.
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
bottomPanel.setBorder(UIUtilities.getEmpty5Border());
bottomPanel.add(searchConditionsPanel);
bottomPanel.add(dirPanel);
// Now, make a panel containing all the above stuff.
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
// JPanel fooPanel = new JPanel();
// fooPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0,0));
// fooPanel.add(enterTextPane);
// leftPanel.add(fooPanel);
leftPanel.add(enterTextPane);
leftPanel.add(bottomPanel);
// Make a panel containing the action buttons.
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(2,1, 5,5));
findNextButton = new RButton(resources.getString("Find"));
findNextButton.setMnemonic((int)resources.getString("FindMnemonic").charAt(0));
findNextButton.setEnabled(false); // Initially, nothing to look for.
findNextButton.setActionCommand("FindNext");
findNextButton.addActionListener(this);
buttonPanel.add(findNextButton);
buttonPanel.add(cancelButton); // cancelButton declared in superclass.
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new BorderLayout());
rightPanel.add(buttonPanel, BorderLayout.NORTH);
// Put everything into a neat little package.
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.setBorder(BorderFactory.createEmptyBorder(5,0,0,5));
contentPane.add(leftPanel);
contentPane.add(rightPanel, BorderLayout.EAST);
setContentPane(contentPane);
getRootPane().setDefaultButton(findNextButton); // Pressing Enter in this dialog fires FindNext.
setTitle(resources.getString("FindDialogTitle"));
setResizable(false);
pack();
setLocationRelativeTo(owner);
registerExtraKeyboardActions();
}
/*****************************************************************************/
// Listens for an action in this Find dialog.
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
if (actionCommand.equals("FindNext")) {
// Add the item to the combo box's list, if it isn't already there.
findTextComboBox.addItem(((JTextField)findTextComboBox.getEditor().getEditorComponent()).getText());
// If they just searched for an item that's already in the list other than
// the first, move it to the first position.
if (findTextComboBox.getSelectedIndex()>0) {
Object item = findTextComboBox.getSelectedItem();
findTextComboBox.removeItem(item);
findTextComboBox.insertItemAt(item, 0);
findTextComboBox.setSelectedIndex(0);
}
} // End of if (actionCommand.equals("FindNext")).
// Otherwise, maybe the superclass has something to do with this action.
else {
super.actionPerformed(e);
}
}
/*****************************************************************************/
/**
* Adds an <code>ActionListener</code> to this dialog. The listener will
* receive notification when the user clicks the "Find" button with an
* actionCommand string of "FindNext".
*
* @param l The listener to add.
* @see #removeActionListener
*/
public void addActionListener(ActionListener l) {
findNextButton.addActionListener(l);
}
/*****************************************************************************/
/**
* Returns the text on the "Find" button.
*
* @return The text on the Find button.
* @see #setFindButtonText
*/
public final String getFindButtonText() {
return findNextButton.getText();
}
/*****************************************************************************/
/**
* Returns the label on the "Find what" text field.
*
* @return The text on the "Find what" text field.
* @see #setFindWhatLabelText
*/
public final String getFindWhatLabelText() {
return findFieldLabel.getText();
}
/*****************************************************************************/
/**
* Removes an <code>ActionListener</code> from this dialog.
*
* @param l The listener to remove
* @see #addActionListener
*/
public void removeActionListener(ActionListener l) {
findNextButton.removeActionListener(l);
}
/*****************************************************************************/
/**
* Sets the text on the "Find" button.
*
* @param text The text for the Find button.
* @see #getFindButtonText
*/
public final void setFindButtonText(String text) {
findNextButton.setText(text);
}
/*****************************************************************************/
/**
* Sets the label on the "Find what" text field.
*
* @param text The text for the "Find what" text field's label.
* @see #getFindWhatLabelText
*/
public final void setFindWhatLabelText(String text) {
findFieldLabel.setText(text);
}
/*****************************************************************************/
/**
* Overrides <code>JDialog</code>'s <code>setVisible</code> method; decides
* whether or not buttons are enabled.
*
* @param visible Whether or not the dialog should be visible.
*/
public void setVisible(boolean visible) {
if (visible==true) {
String selectedItem = (String)findTextComboBox.getSelectedItem();
if (selectedItem==null)
findNextButton.setEnabled(false);
else
findNextButton.setEnabled(true);
// Call JDialog's setVisible.
super.setVisible(true);
// Make the "Find" text field active.
JTextField textField = (JTextField)findTextComboBox.getEditor().getEditorComponent();
textField.requestFocusInWindow();
textField.selectAll();
}
else
super.setVisible(false);
}
/*****************************************************************************/
/**
* Called whenever the user changes the Look and Feel, etc.
* This is overridden so we can reinstate the listeners that are evidently
* lost on the JTextField portion of our combo box.
*/
public void updateUI() {
JTextField textField = (JTextField)findTextComboBox.getEditor().getEditorComponent();
textField.addFocusListener(new FindFocusAdapter());
textField.addKeyListener(new FindKeyListener());
textField.getDocument().addDocumentListener(new FindDocumentListener());
}
/*****************************************************************************/
/**************************** PRIVATE INNER CLASSES **********************************/
/*****************************************************************************/
/**
* Listens for changes in the text field (find search field).
*/
private class FindDocumentListener implements DocumentListener {
// This function is called whenever text is inserted into the document AFTER the fact.
public void insertUpdate(DocumentEvent e) {
findNextButton.setEnabled(true);
}
// This function is called whenever text is removed from the document AFTER the fact.
public void removeUpdate(DocumentEvent e) {
if (((JTextField)findTextComboBox.getEditor().getEditorComponent()).getDocument().getLength()==0)
findNextButton.setEnabled(false);
}
// This function is called whenever a property of the text is changed AFTER the fact.
// NOTE: This isn't done here, as textField isn't a rich text edit.
public void changedUpdate(DocumentEvent e) {
}
}
/*****************************************************************************/
/**
* Listens for the text field gaining focus. All it does is select all text
* in the combo box's text area.
*/
private class FindFocusAdapter extends FocusAdapter {
public void focusGained(FocusEvent e) {
((JTextField)findTextComboBox.getEditor().getEditorComponent()).selectAll();
lastSearchString = (String)findTextComboBox.getSelectedItem(); // Remember what it originally was, in case they tabbed out.
}
}
/*****************************************************************************/
/**
* Listens for key presses in the find dialog.
*/
private class FindKeyListener implements KeyListener {
// Listens for the user pressing a key down.
public void keyPressed(KeyEvent e) {
}
// Listens for a user releasing a key.
public void keyReleased(KeyEvent e) {
// This is an ugly hack to get around JComboBox's
// insistance on eating the first Enter keypress
// it receives when it has focus and its selected item
// has changed since the last time it lost focus.
if (e.getKeyCode()==KeyEvent.VK_ENTER) {
String searchString = (String)findTextComboBox.getSelectedItem();
if (!searchString.equals(lastSearchString)) {
findNextButton.doClick();
lastSearchString = searchString;
((JTextField)findTextComboBox.getEditor().getEditorComponent()).selectAll();
}
}
}
// Listens for a key being typed.
public void keyTyped(KeyEvent e) {
}
}
/*****************************************************************************/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -