package animation3d.editor; import java.awt.Component; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.WindowConstants; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rtextarea.SearchContext; import org.fife.ui.rtextarea.SearchEngine; public class FindAndReplaceDialog extends JDialog implements ActionListener { AnimationEditor textEditor; JTextField searchField, replaceField; JLabel replaceLabel; JCheckBox matchCase, wholeWord, markAll, regex, forward; JButton findNext, replace, replaceAll, cancel; public FindAndReplaceDialog(final AnimationEditor editor) { super(editor); textEditor = editor; final Container root = getContentPane(); root.setLayout(new GridBagLayout()); final JPanel text = new JPanel(new GridBagLayout()); final GridBagConstraints c = new GridBagConstraints(); c.gridx = c.gridy = 0; c.gridwidth = c.gridheight = 1; c.weightx = c.weighty = 1; c.ipadx = c.ipady = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.LINE_START; searchField = createField("Find Next", text, c, null); replaceField = createField("Replace with", text, c, this); c.gridwidth = 4; c.gridheight = c.gridy; c.gridx = c.gridy = 0; c.weightx = c.weighty = 1; c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.LINE_START; root.add(text, c); c.gridy = c.gridheight; c.gridwidth = 1; c.gridheight = 1; c.weightx = 0.001; matchCase = createCheckBox("Match Case", root, c); regex = createCheckBox("Regex", root, c); forward = createCheckBox("Search forward", root, c); forward.setSelected(true); c.gridx = 0; c.gridy++; markAll = createCheckBox("Mark All", root, c); wholeWord = createCheckBox("Whole Word", root, c); c.gridx = 4; c.gridy = 0; findNext = createButton("Find Next", root, c); replace = createButton("Replace", root, c); replaceAll = createButton("Replace All", root, c); cancel = createButton("Cancel", root, c); setResizable(true); pack(); getRootPane().setDefaultButton(findNext); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); final KeyAdapter listener = new KeyAdapter() { @Override public void keyPressed(final KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) dispose(); } }; for (final Component component : getContentPane().getComponents()) component.addKeyListener(listener); searchField.addKeyListener(listener); replaceField.addKeyListener(listener); } protected RSyntaxTextArea getTextArea() { return textEditor.getTextArea(); } @Override public void show(final boolean replace) { setTitle(replace ? "Replace" : "Find"); replaceLabel.setEnabled(replace); replaceField.setEnabled(replace); replaceField.setBackground(replace ? searchField.getBackground() : getRootPane().getBackground()); this.replace.setEnabled(replace); replaceAll.setEnabled(replace); searchField.selectAll(); replaceField.selectAll(); getRootPane().setDefaultButton(findNext); show(); } private JTextField createField(final String name, final Container container, final GridBagConstraints c, final FindAndReplaceDialog replaceDialog) { c.weightx = 0.001; final JLabel label = new JLabel(name); if (replaceDialog != null) replaceDialog.replaceLabel = label; container.add(label, c); c.gridx++; c.weightx = 1; final JTextField field = new JTextField(); container.add(field, c); c.gridx--; c.gridy++; return field; } private JCheckBox createCheckBox(final String name, final Container panel, final GridBagConstraints c) { final JCheckBox checkBox = new JCheckBox(name); checkBox.addActionListener(this); panel.add(checkBox, c); c.gridx++; return checkBox; } private JButton createButton(final String name, final Container panel, final GridBagConstraints c) { final JButton button = new JButton(name); button.addActionListener(this); panel.add(button, c); c.gridy++; return button; } @Override public void actionPerformed(final ActionEvent e) { final Object source = e.getSource(); if (source == cancel) { dispose(); return; } final String text = searchField.getText(); if (text.length() == 0) return; if (source == findNext) searchOrReplace(false); else if (source == replace) searchOrReplace(true); else if (source == replaceAll) { final int replace = SearchEngine.replaceAll(getTextArea(), getSearchContext(true)) .getMarkedCount(); JOptionPane.showMessageDialog(this, replace + " replacements made!"); } } public boolean searchOrReplace(final boolean replace) { return searchOrReplace(replace, forward.isSelected()); } public boolean searchOrReplace(final boolean replace, final boolean forward) { if (searchOrReplaceFromHere(replace, forward)) return true; final RSyntaxTextArea textArea = getTextArea(); final int caret = textArea.getCaretPosition(); textArea.setCaretPosition(forward ? 0 : textArea.getDocument().getLength()); if (searchOrReplaceFromHere(replace, forward)) return true; JOptionPane.showMessageDialog(this, "No match found!"); textArea.setCaretPosition(caret); return false; } protected boolean searchOrReplaceFromHere(final boolean replace) { return searchOrReplaceFromHere(forward.isSelected()); } protected SearchContext getSearchContext(final boolean forward) { final SearchContext context = new SearchContext(); context.setSearchFor(searchField.getText()); context.setReplaceWith(replaceField.getText()); context.setSearchForward(forward); context.setMatchCase(matchCase.isSelected()); context.setWholeWord(wholeWord.isSelected()); context.setRegularExpression(regex.isSelected()); return context; } protected boolean searchOrReplaceFromHere(final boolean replace, final boolean forward) { final RSyntaxTextArea textArea = getTextArea(); final SearchContext context = getSearchContext(forward); return (replace ? SearchEngine.replace(textArea, context) : SearchEngine .find(textArea, context)).wasFound(); } public boolean isReplace() { return replace.isEnabled(); } /** * Sets the content of the search field. * * @param pattern The new content of the search field. */ public void setSearchPattern(final String pattern) { searchField.setText(pattern); } }