All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.ui.search.ReplaceDialog Maven / Gradle / Ivy

Go to download

RText is a powerful, cross-platform programmer's text editor written in Java. It is designed to be easy to use, highly customizable and flexible. Part of RText's design is for the source code to be simple, easy to understand, and well documented, so that other programmers can look into its inner-workings and figure out how RText ticks with ease. A good place to start (besides the source code) is the Javadoc for all classes used in the project.

There is a newer version: 2.0.7
Show newest version
/*
 * 11/14/2003
 *
 * ReplaceDialog.java - Dialog for replacing text in a GUI.
 * Copyright (C) 2003 Robert Futrell
 * robert_futrell at users.sourceforge.net
 * http://fifesoft.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.BorderLayout;
import java.awt.ComponentOrientation;
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.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SpringLayout;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.JTextComponent;

import org.fife.rtext.AssistanceIconPanel;
import org.fife.ui.MaxWidthComboBox;
import org.fife.ui.ResizableFrameContentPane;
import org.fife.ui.UIUtil;


/**
 * A "Replace" dialog similar to those found in most Windows text editing
 * applications.  Contains many search options, including:
*
    *
  • Match Case *
  • Match Whole Word *
  • Use Regular Expressions *
  • Search Forwards or Backwards *
* The dialog also remembers your previous several selections in a combo box. *

An application can use a ReplaceDialog as follows. It is suggested * that you create an Action or something similar to facilitate * "bringing up" the Replace dialog. Have the main application contain an object * that implements both PropertyChangeListener and * ActionListener. This object will receive the following events from * the Replace dialog: *

    *
  • "Replace" action when the user clicks the "Replace" button. *
  • "Replace All" action when the user clicks the "Replace All" button. *
  • "SearchDialog.MatchCase" property change when the user checks/unchecks the * Match Case checkbox. *
  • "SearchDialog.MatchWholeWord" property change when the user checks/unchecks * the Whole Word checkbox. *
  • "SearchDialog.UseRegularExpressions" property change when the user checks/unchecks * the "Regular Expressions" checkbox. *
  • "SearchDialog.SearchDownward" property change when the user clicks either * the Up or Down direction radio button. *
*

The property events listed can all be ignored in a simple case; the Replace 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 ReplaceDialog extends AbstractFindReplaceDialog implements ActionListener { private static final long serialVersionUID = 1L; private JButton replaceButton; private JButton replaceAllButton; private JLabel replaceFieldLabel; private MaxWidthComboBox replaceWithCombo; // This helps us work around the "bug" where JComboBox eats the first Enter // press. private String lastSearchString; private String lastReplaceString; /** * Creates a new ReplaceDialog. * * @param owner The main window that owns this dialog. * @param actionListener The component that listens for "Replace" actions. */ public ReplaceDialog(Frame owner, ActionListener actionListener) { this(owner, actionListener, ResourceBundle.getBundle("org.fife.ui.search.Search")); } /** * Creates a new ReplaceDialog. * * @param owner The main window that owns this dialog. * @param actionListener The component that listens for "Replace" actions. * @param resources The resource bundle from which to get strings, etc. */ public ReplaceDialog(Frame owner, ActionListener actionListener, ResourceBundle resources) { // Let it be known who the owner of this dialog is. super(owner, resources, true); ComponentOrientation orientation = ComponentOrientation. getOrientation(getLocale()); // Create a panel for the "Find what" and "Replace with" text fields. JPanel searchPanel = new JPanel(new SpringLayout()); // Create listeners for the combo boxes. ReplaceFocusAdapter replaceFocusAdapter = new ReplaceFocusAdapter(); ReplaceKeyListener replaceKeyListener = new ReplaceKeyListener(); ReplaceDocumentListener replaceDocumentListener = new ReplaceDocumentListener(); // Create the "Find what" text field. JTextComponent textField = getTextComponent(findTextCombo); textField.addFocusListener(replaceFocusAdapter); textField.addKeyListener(replaceKeyListener); textField.getDocument().addDocumentListener(replaceDocumentListener); // Create the "Replace with" text field. replaceWithCombo = createSearchComboBox(true); textField = getTextComponent(replaceWithCombo); textField.addFocusListener(replaceFocusAdapter); textField.addKeyListener(replaceKeyListener); textField.getDocument().addDocumentListener(replaceDocumentListener); // Create the "Replace with" label. replaceFieldLabel = createLabel(resources, "ReplaceWith", replaceWithCombo); JPanel temp = new JPanel(new BorderLayout()); temp.add(findTextCombo); AssistanceIconPanel aip = new AssistanceIconPanel(findTextCombo); temp.add(aip, BorderLayout.LINE_START); JPanel temp2 = new JPanel(new BorderLayout()); temp2.add(replaceWithCombo); AssistanceIconPanel aip2 = new AssistanceIconPanel(replaceWithCombo); temp2.add(aip2, BorderLayout.LINE_START); // Orient things properly. if (orientation.isLeftToRight()) { searchPanel.add(findFieldLabel); searchPanel.add(temp); searchPanel.add(replaceFieldLabel); searchPanel.add(temp2); } else { searchPanel.add(temp); searchPanel.add(findFieldLabel); searchPanel.add(temp2); searchPanel.add(replaceFieldLabel); } UIUtil.makeSpringCompactGrid(searchPanel, 2, 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(new BorderLayout()); temp = new JPanel(new BorderLayout()); bottomPanel.setBorder(UIUtil.getEmpty5Border()); temp.add(searchConditionsPanel, BorderLayout.LINE_START); temp.add(dirPanel); bottomPanel.add(temp, BorderLayout.LINE_START); // Now, make a panel containing all the above stuff. JPanel leftPanel = new JPanel(); leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS)); leftPanel.add(searchPanel); leftPanel.add(bottomPanel); // Make a panel containing the action buttons. JPanel buttonPanel = new JPanel(); buttonPanel.setLayout(new GridLayout(4,1, 5,5)); replaceButton = UIUtil.createRButton(resources, "Replace", "ReplaceMnemonic"); replaceButton.setActionCommand("Replace"); replaceButton.addActionListener(this); replaceButton.setEnabled(false); replaceButton.setIcon(null); replaceButton.setToolTipText(null); replaceAllButton = UIUtil.createRButton(resources, "ReplaceAll", "ReplaceAllMnemonic"); replaceAllButton.setActionCommand("ReplaceAll"); replaceAllButton.addActionListener(this); replaceAllButton.setEnabled(false); replaceAllButton.setIcon(null); replaceAllButton.setToolTipText(null); buttonPanel.add(findNextButton); buttonPanel.add(replaceButton); buttonPanel.add(replaceAllButton); buttonPanel.add(cancelButton); // Defined in superclass. JPanel rightPanel = new JPanel(new BorderLayout()); rightPanel.add(buttonPanel, BorderLayout.NORTH); // Put it all together! JPanel contentPane = new JPanel(new BorderLayout()); // contentPane.setBorder(UIUtilities.getEmpty5Border()); contentPane.setBorder(javax.swing.BorderFactory.createEmptyBorder(5,5,0,5)); contentPane.add(leftPanel); contentPane.add(rightPanel, BorderLayout.LINE_END); temp = new ResizableFrameContentPane(new BorderLayout()); temp.add(contentPane, BorderLayout.NORTH); setContentPane(temp); getRootPane().setDefaultButton(findNextButton); setTitle(resources.getString("ReplaceDialogTitle")); setResizable(true); pack(); setLocationRelativeTo(owner); applyComponentOrientation(orientation); } // Listens for an action in this Replace dialog. Note that we don't have to check // the actionCommand since we do the same thing for all things we listen to. public void actionPerformed(ActionEvent e) { super.actionPerformed(e); findTextCombo.addItem(getTextComponent(findTextCombo).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 (findTextCombo.getSelectedIndex()>0) { Object item = findTextCombo.getSelectedItem(); findTextCombo.removeItem(item); findTextCombo.insertItemAt(item, 0); findTextCombo.setSelectedIndex(0); } String replaceWithText =getTextComponent(replaceWithCombo).getText(); if (!replaceWithText.equals("")) replaceWithCombo.addItem(replaceWithText); // If they just searched for an item that's already in the list other // than the first, move it to the first position. if (replaceWithCombo.getSelectedIndex()>0) { Object item = replaceWithCombo.getSelectedItem(); replaceWithCombo.removeItem(item); replaceWithCombo.insertItemAt(item, 0); replaceWithCombo.setSelectedIndex(0); } } /** * Adds an ActionListener to this dialog. The listener will * receive notification when the user clicks the "Find" button with an * actionCommand string of "FindNext", an actionCommand string of "Replace" * when the user clicks the "Replace" button, and an actionCommand string * of "ReplaceAll" when the user clicks the "Replace All" button. * * @param l The listener to add. * @see #removeActionListener */ public void addActionListener(ActionListener l) { findNextButton.addActionListener(l); replaceButton.addActionListener(l); replaceAllButton.addActionListener(l); } protected void escapePressed() { if (replaceWithCombo instanceof RegexAwareComboBox) { RegexAwareComboBox racb = (RegexAwareComboBox)replaceWithCombo; // Workaround for the strange behavior (Java bug?) that sometimes // the Escape keypress "gets through" from the AutoComplete's // registered key Actions, and gets to this EscapableDialog, which // hides the entire dialog. Reproduce by doing the following: // 1. In an empty find field, press Ctrl+Space // 2. Type "\\". // 3. Press Escape. // The entire dialog will hide, instead of the completion popup. // Further, bringing the Find dialog back up, the completion popup // will still be visible. if (racb.hideAutoCompletePopups()) { return; } } super.escapePressed(); } /** * Returns the text on the "Replace" button. * * @return The text on the Replace button. * @see #setReplaceButtonText */ public final String getReplaceButtonText() { return replaceButton.getText(); } /** * Returns the text on the "Replace All" button. * * @return The text on the Replace All button. * @see #setReplaceAllButtonText */ public final String getReplaceAllButtonText() { return replaceAllButton.getText(); } /** * Returns the java.lang.String to replace with. * * @return The java.lang.String the user wants to replace * the text to find with. */ public String getReplaceString() { String text = (String)replaceWithCombo.getSelectedItem(); if (text==null) { // possible from JComboBox text = ""; } return text; } /** * Returns the label on the "Replace with" text field. * * @return The text on the "Replace with" text field. * @see #setReplaceWithLabelText */ public final String getReplaceWithLabelText() { return replaceFieldLabel.getText(); } /** * Called when the regex checkbox is clicked. Subclasses can override * to add custom behavior, but should call the super implementation. */ protected void handleRegExCheckBoxClicked() { super.handleRegExCheckBoxClicked(); // "Content assist" support boolean b = regExpCheckBox.isSelected(); // Always true except when debugging. findTextCombo done in parent if (replaceWithCombo instanceof RegexAwareComboBox) { RegexAwareComboBox racb = (RegexAwareComboBox)replaceWithCombo; racb.setAutoCompleteEnabled(b); } } protected EnableResult handleToggleButtons() { EnableResult er = super.handleToggleButtons(); replaceButton.setEnabled(er.getEnable()); replaceAllButton.setEnabled(er.getEnable()); return er; } /** * Removes an ActionListener from this dialog. * * @param l The listener to remove * @see #addActionListener */ public void removeActionListener(ActionListener l) { findNextButton.removeActionListener(l); replaceButton.removeActionListener(l); replaceAllButton.removeActionListener(l); } /** * Sets the text on the "Replace" button. * * @param text The text for the Replace button. * @see #getReplaceButtonText */ public final void setReplaceButtonText(String text) { replaceButton.setText(text); } /** * Sets the text on the "Replace All" button. * * @param text The text for the Replace All button. * @see #getReplaceAllButtonText */ public final void setReplaceAllButtonText(String text) { replaceAllButton.setText(text); } /** * Sets the label on the "Replace with" text field. * * @param text The text for the "Replace with" text field's label. * @see #getReplaceWithLabelText */ public final void setReplaceWithLabelText(String text) { replaceFieldLabel.setText(text); } /** * Sets the java.lang.String to replace with * * @param newReplaceString The java.lang.String to put into * the replace field. */ public void setReplaceString(String newReplaceString) { replaceWithCombo.addItem(newReplaceString); replaceWithCombo.setSelectedIndex(0); } /** * Overrides JDialog's setVisible 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) { // Make sure content assist is enabled (regex check box might have // been checked in a different search dialog). if (visible) { boolean regexEnabled = regExpCheckBox.isSelected(); // Always true except when debugging. findTextCombo done in parent if (replaceWithCombo instanceof RegexAwareComboBox) { RegexAwareComboBox racb = (RegexAwareComboBox)replaceWithCombo; racb.setAutoCompleteEnabled(regexEnabled); } } String selectedItem = (String)findTextCombo.getSelectedItem(); if (selectedItem==null) { findNextButton.setEnabled(false); replaceButton.setEnabled(false); replaceAllButton.setEnabled(false); } else { handleToggleButtons(); } // Call JDialog's setVisible(). super.setVisible(true); // Make the "Find" text field active. JTextComponent textField = getTextComponent(findTextCombo); 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() { // Create listeners for the combo boxes. ReplaceFocusAdapter replaceFocusAdapter = new ReplaceFocusAdapter(); ReplaceKeyListener replaceKeyListener = new ReplaceKeyListener(); ReplaceDocumentListener replaceDocumentListener = new ReplaceDocumentListener(); // Fix the Find What combo box's listeners. JTextComponent textField = getTextComponent(findTextCombo); textField.addFocusListener(replaceFocusAdapter); textField.addKeyListener(replaceKeyListener); textField.getDocument().addDocumentListener(replaceDocumentListener); // Fix the Replace With combo box's listeners. textField = getTextComponent(replaceWithCombo); textField.addFocusListener(replaceFocusAdapter); textField.addKeyListener(replaceKeyListener); textField.getDocument().addDocumentListener(replaceDocumentListener); } /** * Listens for changes in the text field (find search field). */ private class ReplaceDocumentListener implements DocumentListener { public void insertUpdate(DocumentEvent e) { JTextComponent findWhatTextField = getTextComponent(findTextCombo); if (e.getDocument().equals(findWhatTextField.getDocument())) { handleToggleButtons(); } } public void removeUpdate(DocumentEvent e) { JTextComponent findWhatTextField = getTextComponent(findTextCombo); if (e.getDocument().equals(findWhatTextField.getDocument()) && e.getDocument().getLength()==0) { findNextButton.setEnabled(false); replaceButton.setEnabled(false); replaceAllButton.setEnabled(false); } else { handleToggleButtons(); } } public void changedUpdate(DocumentEvent e) { } } /** * Listens for the text fields gaining focus. */ private class ReplaceFocusAdapter extends FocusAdapter { public void focusGained(FocusEvent e) { JTextComponent textField = (JTextComponent)e.getSource(); textField.selectAll(); if (textField==getTextComponent(findTextCombo)) { // Remember what it originally was, in case they tabbed out. lastSearchString = (String)findTextCombo.getSelectedItem(); } else { // if (textField==getTextComponent(replaceWithComboBox)). // Remember what it originally was, in case they tabbed out. lastReplaceString = (String)replaceWithCombo.getSelectedItem(); } } } /** * Listens for key presses in the replace dialog. */ private class ReplaceKeyListener 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. if (e.getKeyCode()==KeyEvent.VK_ENTER && isPreJava6JRE()) { if (e.getSource()==getTextComponent(findTextCombo)) { String replaceString = (String)replaceWithCombo.getSelectedItem(); lastReplaceString = replaceString; // Just in case it changed too. String searchString = (String)findTextCombo.getSelectedItem(); if (!searchString.equals(lastSearchString)) { findNextButton.doClick(0); lastSearchString = searchString; getTextComponent(findTextCombo).selectAll(); } } else { // if (e.getSource()==getTextComponent(replaceWithComboBox)) { String searchString = (String)findTextCombo.getSelectedItem(); lastSearchString = searchString; // Just in case it changed too. String replaceString = (String)replaceWithCombo.getSelectedItem(); if (!replaceString.equals(lastReplaceString)) { findNextButton.doClick(0); lastReplaceString = replaceString; getTextComponent(replaceWithCombo).selectAll(); } } } } // Listens for a key being typed. public void keyTyped(KeyEvent e) { } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy