diff --git a/.editorconfig b/.editorconfig index 3603035..e69d731 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,12 +1,13 @@ [*.java] indent_style = tab indent_size = 4 +end_of_line = lf trim_trailing_whitespace = true max_line_length = 120 [*.xml] indent_style = tab indent_size = 4 -trim_trailing_whitespace = true end_of_line = lf +trim_trailing_whitespace = true max_line_length = 120 diff --git a/RSTAUI/build.gradle b/RSTAUI/build.gradle index 304fa99..624776c 100644 --- a/RSTAUI/build.gradle +++ b/RSTAUI/build.gradle @@ -11,10 +11,10 @@ base { dependencies { api 'com.fifesoft:rsyntaxtextarea:4.0.1' api 'com.fifesoft:autocomplete:4.0.0' - testImplementation platform('org.junit:junit-bom:6.0.1') + testImplementation platform('org.junit:junit-bom:6.1.1') testImplementation 'org.junit.jupiter:junit-jupiter' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' - testImplementation 'org.mockito:mockito-core:5.21.0' + testImplementation 'org.mockito:mockito-core:5.23.0' } ext.isReleaseVersion = !project.version.endsWith('SNAPSHOT') diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/DecorativeIconPanel.java b/RSTAUI/src/main/java/org/fife/rsta/ui/DecorativeIconPanel.java index 9d9e90b..a28ebe8 100644 --- a/RSTAUI/src/main/java/org/fife/rsta/ui/DecorativeIconPanel.java +++ b/RSTAUI/src/main/java/org/fife/rsta/ui/DecorativeIconPanel.java @@ -1,185 +1,185 @@ -/* - * 07/30/2011 - * - * DecorativeIconPanel.java - Displays a small decorative icon beside some - * other component. - * This library is distributed under a modified BSD license. See the included - * RSTAUI.License.txt file for details. - */ -package org.fife.rsta.ui; - -import java.awt.BorderLayout; -import java.awt.Graphics; -import java.awt.event.MouseEvent; -import javax.swing.Icon; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.SwingConstants; -import javax.swing.ToolTipManager; - -import org.fife.ui.autocomplete.EmptyIcon; - - -/** - * A panel that displays an 8x8 decorative icon for a component, such as a - * text field or combo box. This can be used to display error icons, warning - * icons, etc. - * - * @author Robert Futrell - * @version 1.1 - * @see AssistanceIconPanel - */ -public class DecorativeIconPanel extends JPanel { - - /** - * The width of this icon panel, to help align the components we're - * listening to with other combo boxes or text fields without a - * DecorativeIconPanel. - */ - public static final int DEFAULT_WIDTH = 8; - - private JLabel iconLabel; - private boolean showIcon; - private String tip; - private EmptyIcon emptyIcon; - - - /** - * Constructor. - */ - public DecorativeIconPanel() { - this(DEFAULT_WIDTH); - } - - - /** - * Constructor. - * - * @param iconWidth The with of decorative icons that will be added to - * this panel. This is used to ensure the proper amount of padding - * when no icon is being shown. - */ - public DecorativeIconPanel(int iconWidth) { - - setLayout(new BorderLayout()); - emptyIcon = new EmptyIcon(iconWidth); - - iconLabel = new JLabel(emptyIcon) { - @Override - public String getToolTipText(MouseEvent e) { - return showIcon ? tip : null; - } - }; - iconLabel.setVerticalAlignment(SwingConstants.TOP); - ToolTipManager.sharedInstance().registerComponent(iconLabel); - add(iconLabel, BorderLayout.NORTH); - } - - - /** - * Returns the icon being displayed. - * - * @return The icon. - * @see #setIcon(Icon) - */ - public Icon getIcon() { - return iconLabel.getIcon(); - } - - - /** - * Returns whether the icon (if any) is being rendered. - * - * @return Whether the icon is being rendered. - * @see #setShowIcon(boolean) - */ - public boolean getShowIcon() { - return showIcon; - } - - - /** - * Returns the tool tip displayed when the mouse hovers over the icon. - * If the icon is not being displayed, this parameter is ignored. - * - * @return The tool tip text. - * @see #setToolTipText(String) - */ - @Override - public String getToolTipText() { - return tip; - } - - - /** - * Paints any child components. Overridden so the user can explicitly - * hide the icon. - * - * @param g The graphics context. - * @see #setShowIcon(boolean) - */ - @Override - protected void paintChildren(Graphics g) { - if (showIcon) { - super.paintChildren(g); - } - } - - - /** - * Sets the icon to display. - * - * @param icon The new icon to display. - * @see #getIcon() - */ - public void setIcon(Icon icon) { - if (icon==null) { - icon = emptyIcon; - } - iconLabel.setIcon(icon); - } - - - /** - * Sets the size of the icon to display. This only needs to be - * called if the icon set being used changes at runtime. - * - * @param iconWidth The new icon size. - */ - public void setIconWidth(int iconWidth) { - if (iconWidth != emptyIcon.getIconWidth()) { - emptyIcon.setSize(iconWidth); - revalidate(); - repaint(); - } - } - - - /** - * Toggles whether the icon should be shown. - * - * @param show Whether to show the icon. - * @see #getShowIcon() - */ - public void setShowIcon(boolean show) { - if (show!=showIcon) { - showIcon = show; - repaint(); - } - } - - - /** - * Sets the tool tip text to display when the mouse is over the icon. - * This parameter is ignored if the icon is not being displayed. - * - * @param tip The tool tip text to display. - * @see #getToolTipText() - */ - @Override - public void setToolTipText(String tip) { - this.tip = tip; - } - - -} +/* + * 07/30/2011 + * + * DecorativeIconPanel.java - Displays a small decorative icon beside some + * other component. + * This library is distributed under a modified BSD license. See the included + * RSTAUI.License.txt file for details. + */ +package org.fife.rsta.ui; + +import java.awt.BorderLayout; +import java.awt.Graphics; +import java.awt.event.MouseEvent; +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.ToolTipManager; + +import org.fife.ui.autocomplete.EmptyIcon; + + +/** + * A panel that displays an 8x8 decorative icon for a component, such as a + * text field or combo box. This can be used to display error icons, warning + * icons, etc. + * + * @author Robert Futrell + * @version 1.1 + * @see AssistanceIconPanel + */ +public class DecorativeIconPanel extends JPanel { + + /** + * The width of this icon panel, to help align the components we're + * listening to with other combo boxes or text fields without a + * DecorativeIconPanel. + */ + public static final int DEFAULT_WIDTH = 8; + + private JLabel iconLabel; + private boolean showIcon; + private String tip; + private EmptyIcon emptyIcon; + + + /** + * Constructor. + */ + public DecorativeIconPanel() { + this(DEFAULT_WIDTH); + } + + + /** + * Constructor. + * + * @param iconWidth The with of decorative icons that will be added to + * this panel. This is used to ensure the proper amount of padding + * when no icon is being shown. + */ + public DecorativeIconPanel(int iconWidth) { + + setLayout(new BorderLayout()); + emptyIcon = new EmptyIcon(iconWidth); + + iconLabel = new JLabel(emptyIcon) { + @Override + public String getToolTipText(MouseEvent e) { + return showIcon ? tip : null; + } + }; + iconLabel.setVerticalAlignment(SwingConstants.TOP); + ToolTipManager.sharedInstance().registerComponent(iconLabel); + add(iconLabel, BorderLayout.NORTH); + } + + + /** + * Returns the icon being displayed. + * + * @return The icon. + * @see #setIcon(Icon) + */ + public Icon getIcon() { + return iconLabel.getIcon(); + } + + + /** + * Returns whether the icon (if any) is being rendered. + * + * @return Whether the icon is being rendered. + * @see #setShowIcon(boolean) + */ + public boolean getShowIcon() { + return showIcon; + } + + + /** + * Returns the tool tip displayed when the mouse hovers over the icon. + * If the icon is not being displayed, this parameter is ignored. + * + * @return The tool tip text. + * @see #setToolTipText(String) + */ + @Override + public String getToolTipText() { + return tip; + } + + + /** + * Paints any child components. Overridden so the user can explicitly + * hide the icon. + * + * @param g The graphics context. + * @see #setShowIcon(boolean) + */ + @Override + protected void paintChildren(Graphics g) { + if (showIcon) { + super.paintChildren(g); + } + } + + + /** + * Sets the icon to display. + * + * @param icon The new icon to display. + * @see #getIcon() + */ + public void setIcon(Icon icon) { + if (icon==null) { + icon = emptyIcon; + } + iconLabel.setIcon(icon); + } + + + /** + * Sets the size of the icon to display. This only needs to be + * called if the icon set being used changes at runtime. + * + * @param iconWidth The new icon size. + */ + public void setIconWidth(int iconWidth) { + if (iconWidth != emptyIcon.getIconWidth()) { + emptyIcon.setSize(iconWidth); + revalidate(); + repaint(); + } + } + + + /** + * Toggles whether the icon should be shown. + * + * @param show Whether to show the icon. + * @see #getShowIcon() + */ + public void setShowIcon(boolean show) { + if (show!=showIcon) { + showIcon = show; + repaint(); + } + } + + + /** + * Sets the tool tip text to display when the mouse is over the icon. + * This parameter is ignored if the icon is not being displayed. + * + * @param tip The tool tip text to display. + * @see #getToolTipText() + */ + @Override + public void setToolTipText(String tip) { + this.tip = tip; + } + + +} diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/GoToDialog.java b/RSTAUI/src/main/java/org/fife/rsta/ui/GoToDialog.java index 0f3c0ab..bb42f49 100644 --- a/RSTAUI/src/main/java/org/fife/rsta/ui/GoToDialog.java +++ b/RSTAUI/src/main/java/org/fife/rsta/ui/GoToDialog.java @@ -1,399 +1,399 @@ -/* - * 11/13/2003 - * - * GoToDialog.java - A dialog allowing you to skip to a specific line number. - * This library is distributed under a modified BSD license. See the included - * RSTAUI.License.txt file for details. - */ -package org.fife.rsta.ui; - -import java.awt.BorderLayout; -import java.awt.ComponentOrientation; -import java.awt.Container; -import java.awt.Dialog; -import java.awt.Frame; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.ResourceBundle; - -import javax.swing.BorderFactory; -import javax.swing.Box; -import javax.swing.BoxLayout; -import javax.swing.JButton; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.JRootPane; -import javax.swing.JTextField; -import javax.swing.SwingUtilities; -import javax.swing.UIManager; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import javax.swing.text.AbstractDocument; -import javax.swing.text.AttributeSet; -import javax.swing.text.BadLocationException; -import javax.swing.text.DocumentFilter; - - -/** - * A "Go To" dialog allowing you to go to a specific line number in an - * instance of RSyntaxTextArea.
- * - * Example usage: - *
- * GoToDialog dialog = new GoToDialog(window);
- * dialog.setMaxLineNumberAllowed(textArea.getLineCount());
- * dialog.setVisible(true);
- * int line = dialog.getLineNumber();
- * if (line > 0) {
- * try {
- * textArea.setCaretPosition(textArea.getLineStartOffset(line-1));
- * } catch (BadLocationException ble) {
- * ble.printStackTrace(); // Never happens
- * }
- * }
- *
- *
- * @author Robert Futrell
- * @version 1.0
- */
-public class GoToDialog extends EscapableDialog {
-
- private JButton okButton;
- private JButton cancelButton;
- private JTextField lineNumberField;
- private int maxLineNumberAllowed; // Number of lines in the document.
- private int lineNumber; // The line to go to, or -1 for Cancel.
- private String errorDialogTitle;
-
- private static final ResourceBundle MSG = ResourceBundle.getBundle("org.fife.rsta.ui.GoToDialog");
-
-
- /**
- * Creates a new GoToDialog.
- *
- * @param owner The parent dialog.
- */
- public GoToDialog(Dialog owner) {
- super(owner);
- init();
- }
-
-
- /**
- * Creates a new GoToDialog.
- *
- * @param owner The parent window.
- */
- public GoToDialog(Frame owner) {
- super(owner);
- init();
- }
-
-
- private void init() {
-
- ComponentOrientation orientation = ComponentOrientation.
- getOrientation(getLocale());
-
- lineNumber = -1;
- maxLineNumberAllowed = 1; // Empty document has 1 line.
- Listener l = new Listener();
-
- // Set the main content pane for the "GoTo" dialog.
- JPanel contentPane = new ResizableFrameContentPane(new BorderLayout());
- contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- setContentPane(contentPane);
-
- // Make a panel containing the "Line Number" edit box.
- Box enterLineNumberPane = new Box(BoxLayout.LINE_AXIS);
- enterLineNumberPane.setBorder(BorderFactory.createEmptyBorder(
- 0, 0, 20, 0));
- lineNumberField = new JTextField(16);
- lineNumberField.setText("1");
- AbstractDocument doc = (AbstractDocument)lineNumberField.getDocument();
- doc.addDocumentListener(l);
- doc.setDocumentFilter(new NumberDocumentFilter());
- JLabel label = UIUtil.newLabel(MSG, "LineNumber", lineNumberField);
- enterLineNumberPane.add(label);
- enterLineNumberPane.add(Box.createHorizontalStrut(15));
- enterLineNumberPane.add(lineNumberField);
-
- // Make a panel containing the OK and Cancel buttons.
- okButton = UIUtil.newButton(MSG, "OK");
- okButton.addActionListener(l);
- cancelButton = UIUtil.newButton(MSG, "Cancel");
- cancelButton.addActionListener(l);
- Container bottomPanel = createButtonPanel(okButton, cancelButton);
-
- // Put everything into a neat little package.
- contentPane.add(enterLineNumberPane, BorderLayout.NORTH);
- contentPane.add(bottomPanel, BorderLayout.SOUTH);
- JRootPane rootPane = getRootPane();
- rootPane.setDefaultButton(okButton);
- setTitle(MSG.getString("GotoDialogTitle"));
- setModal(true);
- applyComponentOrientation(orientation);
- pack();
- setLocationRelativeTo(getParent());
-
- }
-
-
- /**
- * Called when they've clicked OK or pressed Enter; check the line number
- * they entered for validity and if it's okay, close this dialog. If it
- * isn't okay, display an error message.
- *
- * @return Whether the line number was valid. In this case, this dialog
- * will be hidden when this method returns.
- */
- private boolean attemptToGetGoToLine() {
-
- try {
-
- lineNumber = Integer.parseInt(lineNumberField.getText());
-
- if (lineNumber<1 || lineNumber>maxLineNumberAllowed) {
- lineNumber = -1;
- throw new NumberFormatException();
- }
-
- } catch (NumberFormatException nfe) {
- displayInvalidLineNumberMessage();
- return false;
- }
-
- // If we have a valid line number, close the dialog!
- setVisible(false);
- return true;
-
- }
-
-
- /**
- * Programmatically clicks the Cancel button. Used for testing purposes.
- */
- void clickCancelButton() {
- cancelButton.doClick(0);
- }
-
-
- /**
- * Programmatically clicks the OK button. Used for testing purposes.
- */
- protected void clickOkButton() {
- okButton.doClick(0);
- }
-
-
- /**
- * Returns a panel containing the OK and Cancel buttons. This panel is
- * added to the bottom of this dialog. Applications that don't like these
- * buttons right-aligned in the dialog can override this method to change
- * that behavior.
- *
- * @param ok The OK button.
- * @param cancel The Cancel button.
- * @return A panel containing the two buttons.
- */
- protected Container createButtonPanel(JButton ok, JButton cancel) {
- JPanel buttonPanel = new JPanel(new GridLayout(1,2, 5,5));
- buttonPanel.add(ok);
- buttonPanel.add(cancel);
- JPanel bottomPanel = new JPanel(new BorderLayout());
- bottomPanel.add(buttonPanel, BorderLayout.LINE_END);
- return bottomPanel;
- }
-
-
- /**
- * Displays a message to the user that they have entered an invalid line
- * number. The default implementation displays the error message in a
- * modal. Subclasses that wish to have a slicker error delivery mechanism
- * can override.
- */
- protected void displayInvalidLineNumberMessage() {
- JOptionPane.showMessageDialog(this,
- MSG.getString("LineNumberRange") + maxLineNumberAllowed + ".",
- getErrorDialogTitle(),
- JOptionPane.ERROR_MESSAGE);
- }
-
-
- /**
- * Called when the user clicks Cancel or hits the Escape key. This
- * hides the dialog.
- */
- @Override
- protected void escapePressed() {
- lineNumber = -1;
- super.escapePressed();
- }
-
-
- /**
- * Returns the title for the error dialog.
- *
- * @return The title for the error dialog.
- * @see #setErrorDialogTitle(String)
- */
- public String getErrorDialogTitle() {
- String title = errorDialogTitle;
- if (title==null) {
- title = MSG.getString("ErrorDialog.Title");
- }
- return title;
- }
-
-
- /**
- * Gets the line number the user entered to go to.
- *
- * @return The line number the user decided to go to, or -1
- * if the dialog was canceled. If valid, this will be 1-based,
- * not 0-based.
- * @see #setLineNumber(int)
- */
- public int getLineNumber() {
- return lineNumber;
- }
-
-
- /**
- * Returns the maximum line number the user is allowed to enter.
- *
- * @return the maximum line number allowed.
- * @see #setMaxLineNumberAllowed(int)
- */
- public int getMaxLineNumberAllowed() {
- return maxLineNumberAllowed;
- }
-
-
- /**
- * Sets the title for the error dialog.
- *
- * @param title The new title. If this is null, a default
- * value will be used.
- * @see #getErrorDialogTitle()
- */
- public void setErrorDialogTitle(String title) {
- this.errorDialogTitle = title;
- }
-
-
- /**
- * Sets the line number displayed in this dialog.
- *
- * @param lineNumber The new line number.
- * @see #getLineNumber()
- */
- protected void setLineNumber(int lineNumber) {
- this.lineNumber = lineNumber;
- lineNumberField.setText(String.valueOf(lineNumber));
- }
-
-
- /**
- * Sets the maximum line number for them to enter.
- *
- * @param max The new maximum line number value.
- * @see #getMaxLineNumberAllowed()
- */
- public void setMaxLineNumberAllowed(int max) {
- this.maxLineNumberAllowed = max;
- }
-
-
- /**
- * Overrides JDialog's setVisible method; decides
- * whether buttons are enabled if the user is enabling the dialog.
- */
- @Override
- public void setVisible(boolean visible) {
- if (visible) {
- lineNumber = -1;
- okButton.setEnabled(lineNumberField.getDocument().getLength()>0);
- SwingUtilities.invokeLater(() -> {
- lineNumberField.requestFocusInWindow();
- lineNumberField.selectAll();
- });
- }
- super.setVisible(visible);
- }
-
-
- /**
- * Listens for events in this dialog.
- */
- private final class Listener implements ActionListener, DocumentListener {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- Object source = e.getSource();
- if (okButton==source) {
- attemptToGetGoToLine();
- }
- else if (cancelButton==source) {
- escapePressed();
- }
- }
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- okButton.setEnabled(lineNumberField.getDocument().getLength()>0);
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- okButton.setEnabled(lineNumberField.getDocument().getLength()>0);
- }
-
- }
-
-
- /**
- * A document filter that only lets the user enter digits.
- */
- private final class NumberDocumentFilter extends DocumentFilter {
-
- private String fix(String str) {
- if (str!=null) {
- int origLength = str.length();
- for (int i=0; i
+ * GoToDialog dialog = new GoToDialog(window);
+ * dialog.setMaxLineNumberAllowed(textArea.getLineCount());
+ * dialog.setVisible(true);
+ * int line = dialog.getLineNumber();
+ * if (line > 0) {
+ * try {
+ * textArea.setCaretPosition(textArea.getLineStartOffset(line-1));
+ * } catch (BadLocationException ble) {
+ * ble.printStackTrace(); // Never happens
+ * }
+ * }
+ *
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+public class GoToDialog extends EscapableDialog {
+
+ private JButton okButton;
+ private JButton cancelButton;
+ private JTextField lineNumberField;
+ private int maxLineNumberAllowed; // Number of lines in the document.
+ private int lineNumber; // The line to go to, or -1 for Cancel.
+ private String errorDialogTitle;
+
+ private static final ResourceBundle MSG = ResourceBundle.getBundle("org.fife.rsta.ui.GoToDialog");
+
+
+ /**
+ * Creates a new GoToDialog.
+ *
+ * @param owner The parent dialog.
+ */
+ public GoToDialog(Dialog owner) {
+ super(owner);
+ init();
+ }
+
+
+ /**
+ * Creates a new GoToDialog.
+ *
+ * @param owner The parent window.
+ */
+ public GoToDialog(Frame owner) {
+ super(owner);
+ init();
+ }
+
+
+ private void init() {
+
+ ComponentOrientation orientation = ComponentOrientation.
+ getOrientation(getLocale());
+
+ lineNumber = -1;
+ maxLineNumberAllowed = 1; // Empty document has 1 line.
+ Listener l = new Listener();
+
+ // Set the main content pane for the "GoTo" dialog.
+ JPanel contentPane = new ResizableFrameContentPane(new BorderLayout());
+ contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ setContentPane(contentPane);
+
+ // Make a panel containing the "Line Number" edit box.
+ Box enterLineNumberPane = new Box(BoxLayout.LINE_AXIS);
+ enterLineNumberPane.setBorder(BorderFactory.createEmptyBorder(
+ 0, 0, 20, 0));
+ lineNumberField = new JTextField(16);
+ lineNumberField.setText("1");
+ AbstractDocument doc = (AbstractDocument)lineNumberField.getDocument();
+ doc.addDocumentListener(l);
+ doc.setDocumentFilter(new NumberDocumentFilter());
+ JLabel label = UIUtil.newLabel(MSG, "LineNumber", lineNumberField);
+ enterLineNumberPane.add(label);
+ enterLineNumberPane.add(Box.createHorizontalStrut(15));
+ enterLineNumberPane.add(lineNumberField);
+
+ // Make a panel containing the OK and Cancel buttons.
+ okButton = UIUtil.newButton(MSG, "OK");
+ okButton.addActionListener(l);
+ cancelButton = UIUtil.newButton(MSG, "Cancel");
+ cancelButton.addActionListener(l);
+ Container bottomPanel = createButtonPanel(okButton, cancelButton);
+
+ // Put everything into a neat little package.
+ contentPane.add(enterLineNumberPane, BorderLayout.NORTH);
+ contentPane.add(bottomPanel, BorderLayout.SOUTH);
+ JRootPane rootPane = getRootPane();
+ rootPane.setDefaultButton(okButton);
+ setTitle(MSG.getString("GotoDialogTitle"));
+ setModal(true);
+ applyComponentOrientation(orientation);
+ pack();
+ setLocationRelativeTo(getParent());
+
+ }
+
+
+ /**
+ * Called when they've clicked OK or pressed Enter; check the line number
+ * they entered for validity and if it's okay, close this dialog. If it
+ * isn't okay, display an error message.
+ *
+ * @return Whether the line number was valid. In this case, this dialog
+ * will be hidden when this method returns.
+ */
+ private boolean attemptToGetGoToLine() {
+
+ try {
+
+ lineNumber = Integer.parseInt(lineNumberField.getText());
+
+ if (lineNumber<1 || lineNumber>maxLineNumberAllowed) {
+ lineNumber = -1;
+ throw new NumberFormatException();
+ }
+
+ } catch (NumberFormatException nfe) {
+ displayInvalidLineNumberMessage();
+ return false;
+ }
+
+ // If we have a valid line number, close the dialog!
+ setVisible(false);
+ return true;
+
+ }
+
+
+ /**
+ * Programmatically clicks the Cancel button. Used for testing purposes.
+ */
+ void clickCancelButton() {
+ cancelButton.doClick(0);
+ }
+
+
+ /**
+ * Programmatically clicks the OK button. Used for testing purposes.
+ */
+ protected void clickOkButton() {
+ okButton.doClick(0);
+ }
+
+
+ /**
+ * Returns a panel containing the OK and Cancel buttons. This panel is
+ * added to the bottom of this dialog. Applications that don't like these
+ * buttons right-aligned in the dialog can override this method to change
+ * that behavior.
+ *
+ * @param ok The OK button.
+ * @param cancel The Cancel button.
+ * @return A panel containing the two buttons.
+ */
+ protected Container createButtonPanel(JButton ok, JButton cancel) {
+ JPanel buttonPanel = new JPanel(new GridLayout(1,2, 5,5));
+ buttonPanel.add(ok);
+ buttonPanel.add(cancel);
+ JPanel bottomPanel = new JPanel(new BorderLayout());
+ bottomPanel.add(buttonPanel, BorderLayout.LINE_END);
+ return bottomPanel;
+ }
+
+
+ /**
+ * Displays a message to the user that they have entered an invalid line
+ * number. The default implementation displays the error message in a
+ * modal. Subclasses that wish to have a slicker error delivery mechanism
+ * can override.
+ */
+ protected void displayInvalidLineNumberMessage() {
+ JOptionPane.showMessageDialog(this,
+ MSG.getString("LineNumberRange") + maxLineNumberAllowed + ".",
+ getErrorDialogTitle(),
+ JOptionPane.ERROR_MESSAGE);
+ }
+
+
+ /**
+ * Called when the user clicks Cancel or hits the Escape key. This
+ * hides the dialog.
+ */
+ @Override
+ protected void escapePressed() {
+ lineNumber = -1;
+ super.escapePressed();
+ }
+
+
+ /**
+ * Returns the title for the error dialog.
+ *
+ * @return The title for the error dialog.
+ * @see #setErrorDialogTitle(String)
+ */
+ public String getErrorDialogTitle() {
+ String title = errorDialogTitle;
+ if (title==null) {
+ title = MSG.getString("ErrorDialog.Title");
+ }
+ return title;
+ }
+
+
+ /**
+ * Gets the line number the user entered to go to.
+ *
+ * @return The line number the user decided to go to, or -1
+ * if the dialog was canceled. If valid, this will be 1-based,
+ * not 0-based.
+ * @see #setLineNumber(int)
+ */
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+
+ /**
+ * Returns the maximum line number the user is allowed to enter.
+ *
+ * @return the maximum line number allowed.
+ * @see #setMaxLineNumberAllowed(int)
+ */
+ public int getMaxLineNumberAllowed() {
+ return maxLineNumberAllowed;
+ }
+
+
+ /**
+ * Sets the title for the error dialog.
+ *
+ * @param title The new title. If this is null, a default
+ * value will be used.
+ * @see #getErrorDialogTitle()
+ */
+ public void setErrorDialogTitle(String title) {
+ this.errorDialogTitle = title;
+ }
+
+
+ /**
+ * Sets the line number displayed in this dialog.
+ *
+ * @param lineNumber The new line number.
+ * @see #getLineNumber()
+ */
+ protected void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ lineNumberField.setText(String.valueOf(lineNumber));
+ }
+
+
+ /**
+ * Sets the maximum line number for them to enter.
+ *
+ * @param max The new maximum line number value.
+ * @see #getMaxLineNumberAllowed()
+ */
+ public void setMaxLineNumberAllowed(int max) {
+ this.maxLineNumberAllowed = max;
+ }
+
+
+ /**
+ * Overrides JDialog's setVisible method; decides
+ * whether buttons are enabled if the user is enabling the dialog.
+ */
+ @Override
+ public void setVisible(boolean visible) {
+ if (visible) {
+ lineNumber = -1;
+ okButton.setEnabled(lineNumberField.getDocument().getLength()>0);
+ SwingUtilities.invokeLater(() -> {
+ lineNumberField.requestFocusInWindow();
+ lineNumberField.selectAll();
+ });
+ }
+ super.setVisible(visible);
+ }
+
+
+ /**
+ * Listens for events in this dialog.
+ */
+ private final class Listener implements ActionListener, DocumentListener {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Object source = e.getSource();
+ if (okButton==source) {
+ attemptToGetGoToLine();
+ }
+ else if (cancelButton==source) {
+ escapePressed();
+ }
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ okButton.setEnabled(lineNumberField.getDocument().getLength()>0);
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ okButton.setEnabled(lineNumberField.getDocument().getLength()>0);
+ }
+
+ }
+
+
+ /**
+ * A document filter that only lets the user enter digits.
+ */
+ private final class NumberDocumentFilter extends DocumentFilter {
+
+ private String fix(String str) {
+ if (str!=null) {
+ int origLength = str.length();
+ for (int i=0; iJFrames that are resizable. This panel has
- * a size grip that can be dragged and cause a resize of the window,
- * similar to that found on resizable Microsoft Windows dialogs.
- *
- * @author Robert Futrell
- * @version 1.0
- */
-public class ResizableFrameContentPane extends JPanel {
-
- private static final long serialVersionUID = 1L;
-
- private SizeGripIcon gripIcon;
-
-
- /**
- * Constructor.
- */
- public ResizableFrameContentPane() {
- gripIcon = new SizeGripIcon();
- }
-
-
- /**
- * Constructor.
- *
- * @param layout The layout manager.
- */
- public ResizableFrameContentPane(LayoutManager layout) {
- super(layout);
- gripIcon = new SizeGripIcon();
- }
-
-
- /**
- * Paints this panel.
- *
- * @param g The graphics context.
- */
- /*
- * We override paint() instead of paintComponent() as if we do the latter,
- * sometimes child panels will be painted over our size grip, rendering it
- * invisible.
- */
- @Override
- public void paint(Graphics g) {
- super.paint(g);
- gripIcon.paintIcon(this, g, this.getX(), this.getY());
- }
-
-
+/*
+ * 09/07/2006
+ *
+ * ResizableFrameContentPane.java - A content pane with a size grip that
+ * can be used to resize a sizable dialog or frame.
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.License.txt file for details.
+ */
+package org.fife.rsta.ui;
+
+import java.awt.*;
+import javax.swing.*;
+
+
+
+/**
+ * A panel to be used as the content pane for JDialogs
+ * and JFrames that are resizable. This panel has
+ * a size grip that can be dragged and cause a resize of the window,
+ * similar to that found on resizable Microsoft Windows dialogs.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+public class ResizableFrameContentPane extends JPanel {
+
+ private static final long serialVersionUID = 1L;
+
+ private SizeGripIcon gripIcon;
+
+
+ /**
+ * Constructor.
+ */
+ public ResizableFrameContentPane() {
+ gripIcon = new SizeGripIcon();
+ }
+
+
+ /**
+ * Constructor.
+ *
+ * @param layout The layout manager.
+ */
+ public ResizableFrameContentPane(LayoutManager layout) {
+ super(layout);
+ gripIcon = new SizeGripIcon();
+ }
+
+
+ /**
+ * Paints this panel.
+ *
+ * @param g The graphics context.
+ */
+ /*
+ * We override paint() instead of paintComponent() as if we do the latter,
+ * sometimes child panels will be painted over our size grip, rendering it
+ * invisible.
+ */
+ @Override
+ public void paint(Graphics g) {
+ super.paint(g);
+ gripIcon.paintIcon(this, g, this.getX(), this.getY());
+ }
+
+
}
\ No newline at end of file
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/SizeGripIcon.java b/RSTAUI/src/main/java/org/fife/rsta/ui/SizeGripIcon.java
index 1034785..d5a5040 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/SizeGripIcon.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/SizeGripIcon.java
@@ -1,102 +1,102 @@
-/*
- * 09/07/2006
- *
- * SizeGripIcon.java - An icon that paints a size grip.
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.License.txt file for details.
- */
-package org.fife.rsta.ui;
-
-import java.awt.*;
-import javax.swing.*;
-
-
-/**
- * An icon that looks like a Windows 98 or XP-style size grip.
- *
- * @author Robert Futrell
- * @version 1.0
- */
-public class SizeGripIcon implements Icon {
-
- private static final int SIZE = 16;
-
-
- /**
- * Returns the height of this icon.
- *
- * @return This icon's height.
- */
- @Override
- public int getIconHeight() {
- return SIZE;
- }
-
-
- /**
- * Returns the width of this icon.
- *
- * @return This icon's width.
- */
- @Override
- public int getIconWidth() {
- return SIZE;
- }
-
-
- /**
- * Paints this icon.
- *
- * @param c The component to paint on.
- * @param g The graphics context.
- * @param x The x-coordinate at which to paint.
- * @param y The y-coordinate at which to paint.
- */
- @Override
- public void paintIcon(Component c, Graphics g, int x, int y) {
-
- Dimension dim = c.getSize();
- Color c1 = UIManager.getColor("Label.disabledShadow");
- Color c2 = UIManager.getColor("Label.disabledForeground");
-
- ComponentOrientation orientation = c.getComponentOrientation();
- int height = dim.height -= 3;
-
- if (orientation.isLeftToRight()) {
- int width = dim.width -= 3;
- g.setColor(c1);
- g.fillRect(width-9,height-1, 3,3);
- g.fillRect(width-5,height-1, 3,3);
- g.fillRect(width-1,height-1, 3,3);
- g.fillRect(width-5,height-5, 3,3);
- g.fillRect(width-1,height-5, 3,3);
- g.fillRect(width-1,height-9, 3,3);
- g.setColor(c2);
- g.fillRect(width-9,height-1, 2,2);
- g.fillRect(width-5,height-1, 2,2);
- g.fillRect(width-1,height-1, 2,2);
- g.fillRect(width-5,height-5, 2,2);
- g.fillRect(width-1,height-5, 2,2);
- g.fillRect(width-1,height-9, 2,2);
- }
- else {
- g.setColor(c1);
- g.fillRect(10,height-1, 3,3);
- g.fillRect(6,height-1, 3,3);
- g.fillRect(2,height-1, 3,3);
- g.fillRect(6,height-5, 3,3);
- g.fillRect(2,height-5, 3,3);
- g.fillRect(2,height-9, 3,3);
- g.setColor(c2);
- g.fillRect(10,height-1, 2,2);
- g.fillRect(6,height-1, 2,2);
- g.fillRect(2,height-1, 2,2);
- g.fillRect(6,height-5, 2,2);
- g.fillRect(2,height-5, 2,2);
- g.fillRect(2,height-9, 2,2);
- }
-
- }
-
-
+/*
+ * 09/07/2006
+ *
+ * SizeGripIcon.java - An icon that paints a size grip.
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.License.txt file for details.
+ */
+package org.fife.rsta.ui;
+
+import java.awt.*;
+import javax.swing.*;
+
+
+/**
+ * An icon that looks like a Windows 98 or XP-style size grip.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+public class SizeGripIcon implements Icon {
+
+ private static final int SIZE = 16;
+
+
+ /**
+ * Returns the height of this icon.
+ *
+ * @return This icon's height.
+ */
+ @Override
+ public int getIconHeight() {
+ return SIZE;
+ }
+
+
+ /**
+ * Returns the width of this icon.
+ *
+ * @return This icon's width.
+ */
+ @Override
+ public int getIconWidth() {
+ return SIZE;
+ }
+
+
+ /**
+ * Paints this icon.
+ *
+ * @param c The component to paint on.
+ * @param g The graphics context.
+ * @param x The x-coordinate at which to paint.
+ * @param y The y-coordinate at which to paint.
+ */
+ @Override
+ public void paintIcon(Component c, Graphics g, int x, int y) {
+
+ Dimension dim = c.getSize();
+ Color c1 = UIManager.getColor("Label.disabledShadow");
+ Color c2 = UIManager.getColor("Label.disabledForeground");
+
+ ComponentOrientation orientation = c.getComponentOrientation();
+ int height = dim.height -= 3;
+
+ if (orientation.isLeftToRight()) {
+ int width = dim.width -= 3;
+ g.setColor(c1);
+ g.fillRect(width-9,height-1, 3,3);
+ g.fillRect(width-5,height-1, 3,3);
+ g.fillRect(width-1,height-1, 3,3);
+ g.fillRect(width-5,height-5, 3,3);
+ g.fillRect(width-1,height-5, 3,3);
+ g.fillRect(width-1,height-9, 3,3);
+ g.setColor(c2);
+ g.fillRect(width-9,height-1, 2,2);
+ g.fillRect(width-5,height-1, 2,2);
+ g.fillRect(width-1,height-1, 2,2);
+ g.fillRect(width-5,height-5, 2,2);
+ g.fillRect(width-1,height-5, 2,2);
+ g.fillRect(width-1,height-9, 2,2);
+ }
+ else {
+ g.setColor(c1);
+ g.fillRect(10,height-1, 3,3);
+ g.fillRect(6,height-1, 3,3);
+ g.fillRect(2,height-1, 3,3);
+ g.fillRect(6,height-5, 3,3);
+ g.fillRect(2,height-5, 3,3);
+ g.fillRect(2,height-9, 3,3);
+ g.setColor(c2);
+ g.fillRect(10,height-1, 2,2);
+ g.fillRect(6,height-1, 2,2);
+ g.fillRect(2,height-1, 2,2);
+ g.fillRect(6,height-5, 2,2);
+ g.fillRect(2,height-5, 2,2);
+ g.fillRect(2,height-9, 2,2);
+ }
+
+ }
+
+
}
\ No newline at end of file
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/search/AbstractFindReplaceDialog.java b/RSTAUI/src/main/java/org/fife/rsta/ui/search/AbstractFindReplaceDialog.java
index 6f52fb2..ed92c68 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/search/AbstractFindReplaceDialog.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/search/AbstractFindReplaceDialog.java
@@ -1,485 +1,485 @@
-/*
- * 04/08/2004
- *
- * AbstractFindReplaceSearchDialog.java - Base class for FindDialog and
- * ReplaceDialog.
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.License.txt file for details.
- */
-package org.fife.rsta.ui.search;
-
-import java.awt.BorderLayout;
-import java.awt.Dialog;
-import java.awt.Frame;
-import java.awt.event.ActionEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.beans.PropertyChangeEvent;
-import javax.swing.AbstractAction;
-import javax.swing.ActionMap;
-import javax.swing.BoxLayout;
-import javax.swing.ButtonGroup;
-import javax.swing.InputMap;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JRadioButton;
-import javax.swing.JRootPane;
-import javax.swing.KeyStroke;
-import javax.swing.UIManager;
-import javax.swing.event.EventListenerList;
-import javax.swing.text.JTextComponent;
-
-import org.fife.rsta.ui.UIUtil;
-import org.fife.ui.rtextarea.SearchContext;
-
-
-/**
- * This is the base class for {@link FindDialog} and {@link ReplaceDialog}. It
- * is basically all the features common to the two dialogs that weren't
- * taken care of in {@link AbstractSearchDialog}.
- *
- * @author Robert Futrell
- * @version 0.1
- */
-public abstract class AbstractFindReplaceDialog extends AbstractSearchDialog {
-
- /**
- * Property fired when the user toggles the search direction radio buttons.
- */
- public static final String SEARCH_DOWNWARD_PROPERTY = "SearchDialog.SearchDownward";
-
- // The radio buttons for changing the search direction.
- protected JRadioButton upButton;
- protected JRadioButton downButton;
- protected JPanel dirPanel;
- private String dirPanelTitle;
- protected JLabel findFieldLabel;
- protected JButton findNextButton;
-
- /**
- * The "mark all" check box.
- */
- protected JCheckBox markAllCheckBox;
-
- /**
- * Folks listening for events in this dialog.
- */
- private EventListenerList listenerList;
-
-
- /**
- * Constructor.
- *
- * @param owner The dialog that owns this search dialog.
- */
- public AbstractFindReplaceDialog(Dialog owner) {
- super(owner);
- init();
- }
-
- /**
- * Constructor. Does the initializing for parts common to
- * FindDialog and ReplaceDialog that isn't
- * taken care of in AbstractSearchDialog's constructor.
- *
- * @param owner The window that owns this search dialog.
- */
- public AbstractFindReplaceDialog(Frame owner) {
- super(owner);
- init();
- }
-
-
- /**
- * Listens for action events in this dialog.
- *
- * @param e The event that occurred.
- */
- @Override
- public void actionPerformed(ActionEvent e) {
-
- String command = e.getActionCommand();
-
- if ("UpRadioButtonClicked".equals(command)) {
- context.setSearchForward(false);
- }
-
- else if ("DownRadioButtonClicked".equals(command)) {
- context.setSearchForward(true);
- }
-
- else if ("MarkAll".equals(command)) {
- boolean checked = markAllCheckBox.isSelected();
- context.setMarkAll(checked);
- }
-
- else if (SearchEvent.Type.FIND.name().equals(command)) {
- doSearch(context.getSearchForward()); // Keep current direction
- }
-
- else {
- super.actionPerformed(e);
- }
-
- }
-
-
- /**
- * Adds a {@link SearchListener} to this dialog. This listener will
- * be notified when find or replace operations are triggered. For
- * example, for a Replace dialog, a listener will receive notification
- * when the user clicks "Find", "Replace", or "Replace All".
- *
- * @param l The listener to add.
- * @see #removeSearchListener(SearchListener)
- */
- public void addSearchListener(SearchListener l) {
- listenerList.add(SearchListener.class, l);
- }
-
-
- private void doSearch(boolean forward) {
-
- // Add the item to the combo box's list, if it isn't already there.
- JTextComponent tc = UIUtil.getTextComponent(findTextCombo);
- findTextCombo.addItem(tc.getText());
- context.setSearchFor(getSearchString());
-
- // If the ask is to search in the opposite direction from the UI's
- // current direction, use a cloned search context to avoid updating
- // the UI when we shouldn't (e.g. from a keyboard shortcut to search
- // backward).
- SearchContext contextToFire = context;
- if (forward != context.getSearchForward()) {
- contextToFire = context.clone();
- contextToFire.setSearchForward(forward);
- }
-
- // Let parent application know
- fireSearchEvent(SearchEvent.Type.FIND, contextToFire);
- }
-
- /**
- * Notifies all listeners that have registered interest in notification for
- * this event type. The event instance is lazily created using the
- * event parameter.
- *
- * @param type The type of search.
- * @param context The search context to fire. If this is {@code null}, this
- * dialog's current context (e.g. its current state) is used. This
- * parameter allows for scenarios where we want to search differently
- * than what our UI displays; for example, binding a keyboard
- * shortcut to "search backwards" no matter what.
- */
- protected void fireSearchEvent(SearchEvent.Type type, SearchContext context) {
-
- if (context == null) {
- context = this.context;
- }
-
- // Guaranteed to return a non-null array
- Object[] listeners = listenerList.getListenerList();
- SearchEvent e = null;
- // Process the listeners last to first, notifying
- // those that are interested in this event
- for (int i = listeners.length - 2; i >= 0; i -= 2) {
- if (listeners[i] == SearchListener.class) {
- // Lazily create the event:
- if (e == null) {
- e = new SearchEvent(this, type, context);
- }
- ((SearchListener)listeners[i+1]).searchEvent(e);
- }
- }
- }
-
-
- /**
- * Returns the text for the "Down" radio button.
- *
- * @return The text for the "Down" radio button.
- * @see #setDownRadioButtonText
- */
- public final String getDownRadioButtonText() {
- return downButton.getText();
- }
-
-
- /**
- * 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();
- }
-
-
- /**
- * Returns the text for the search direction's radio buttons' border.
- *
- * @return The text for the search radio buttons' border.
- * @see #setSearchButtonsBorderText
- */
- public final String getSearchButtonsBorderText() {
- return dirPanelTitle;
- }
-
-
- /**
- * Returns the text for the "Up" radio button.
- *
- * @return The text for the "Up" radio button.
- * @see #setUpRadioButtonText
- */
- public final String getUpRadioButtonText() {
- return upButton.getText();
- }
-
-
- /**
- * Called whenever a property in the search context is modified.
- * Subclasses should override if they listen for additional properties.
- *
- * @param e The property change event fired.
- */
- @Override
- protected void handleSearchContextPropertyChanged(PropertyChangeEvent e) {
-
- String prop = e.getPropertyName();
-
- if (SearchContext.PROPERTY_SEARCH_FORWARD.equals(prop)) {
- boolean newValue = (Boolean) e.getNewValue();
- JRadioButton button = newValue ? downButton : upButton;
- button.setSelected(true);
- }
-
- else if (SearchContext.PROPERTY_MARK_ALL.equals(prop)) {
- boolean newValue = (Boolean) e.getNewValue();
- markAllCheckBox.setSelected(newValue);
- }
-
- else {
- super.handleSearchContextPropertyChanged(e);
- }
-
- }
-
-
- @Override
- protected FindReplaceButtonsEnableResult handleToggleButtons() {
-
- FindReplaceButtonsEnableResult er = super.handleToggleButtons();
- boolean enable = er.getEnable();
-
- findNextButton.setEnabled(enable);
-
- // setBackground doesn't show up with XP Look and Feel!
- JTextComponent tc = UIUtil.getTextComponent(findTextCombo);
- tc.setForeground(enable ? UIManager.getColor("TextField.foreground") :
- UIUtil.getErrorTextForeground());
-
- String tooltip = SearchUtil.getToolTip(er);
- tc.setToolTipText(tooltip); // Always set, even if null
-
- return er;
-
- }
-
-
- private void init() {
-
- listenerList = new EventListenerList();
-
- // Make a panel containing the "search up/down" radio buttons.
- dirPanel = new JPanel();
- dirPanel.setLayout(new BoxLayout(dirPanel, BoxLayout.LINE_AXIS));
- setSearchButtonsBorderText(getString("Direction"));
- ButtonGroup bg = new ButtonGroup();
- upButton = new JRadioButton(getString("Up"), false);
- upButton.setMnemonic((int)getString("UpMnemonic").charAt(0));
- downButton = new JRadioButton(getString("Down"), true);
- downButton.setMnemonic((int)getString("DownMnemonic").charAt(0));
- upButton.setActionCommand("UpRadioButtonClicked");
- upButton.addActionListener(this);
- downButton.setActionCommand("DownRadioButtonClicked");
- downButton.addActionListener(this);
- bg.add(upButton);
- bg.add(downButton);
- dirPanel.add(upButton);
- dirPanel.add(downButton);
-
- // Initialize the "mark all" button.
- markAllCheckBox = new JCheckBox(getString("MarkAll"));
- markAllCheckBox.setMnemonic((int)getString("MarkAllMnemonic").charAt(0));
- markAllCheckBox.setActionCommand("MarkAll");
- markAllCheckBox.addActionListener(this);
-
- // Rearrange the search conditions panel.
- searchConditionsPanel.removeAll();
- searchConditionsPanel.setLayout(new BorderLayout());
- JPanel temp = new JPanel();
- temp.setLayout(new BoxLayout(temp, BoxLayout.PAGE_AXIS));
- temp.add(caseCheckBox);
- temp.add(wholeWordCheckBox);
- temp.add(wrapCheckBox);
- searchConditionsPanel.add(temp, BorderLayout.LINE_START);
- temp = new JPanel();
- temp.setLayout(new BoxLayout(temp, BoxLayout.PAGE_AXIS));
- temp.add(regexCheckBox);
- temp.add(markAllCheckBox);
- searchConditionsPanel.add(temp, BorderLayout.LINE_END);
-
- // Create the "Find what" label.
- findFieldLabel = UIUtil.newLabel(getBundle(), "FindWhat",findTextCombo);
-
- // Create a "Find Next" button.
- findNextButton = UIUtil.newButton(getBundle(), "Find");
- findNextButton.setActionCommand(SearchEvent.Type.FIND.name());
- findNextButton.addActionListener(this);
- findNextButton.setDefaultCapable(true);
- findNextButton.setEnabled(false); // Initially, nothing to look for.
-
- installKeyboardActions();
-
- }
-
-
- /**
- * Adds extra keyboard actions for Find and Replace dialogs.
- */
- private void installKeyboardActions() {
-
- JRootPane rootPane = getRootPane();
- InputMap im = rootPane.getInputMap(
- JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
- ActionMap am = rootPane.getActionMap();
-
- int modifier = getToolkit().getMenuShortcutKeyMaskEx();
- KeyStroke ctrlF = KeyStroke.getKeyStroke(KeyEvent.VK_F, modifier);
- im.put(ctrlF, "focusSearchForField");
- am.put("focusSearchForField", new AbstractAction() {
- @Override
- public void actionPerformed(ActionEvent e) {
- AbstractFindReplaceDialog.this.requestFocus();
- }
- });
-
- // Shift+Enter and Ctrl+Enter both do a backwards/opposite search
- int shift = InputEvent.SHIFT_DOWN_MASK;
- int ctrl = InputEvent.CTRL_DOWN_MASK;
- if (System.getProperty("os.name").toLowerCase().contains("os x")) {
- ctrl = InputEvent.META_DOWN_MASK;
- }
- KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, shift);
- im.put(ks, "searchBackward");
- ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ctrl);
- im.put(ks, "searchBackward");
- am.put("searchBackward", new AbstractAction() {
- @Override
- public void actionPerformed(ActionEvent e) {
- doSearch(!context.getSearchForward());
- }
- });
- }
-
-
- /**
- * Overridden to initialize UI elements specific to this subclass.
- */
- @Override
- protected void refreshUIFromContext() {
- if (this.markAllCheckBox==null) {
- return; // First time through, UI not realized yet
- }
- super.refreshUIFromContext();
- markAllCheckBox.setSelected(context.getMarkAll());
- boolean searchForward = context.getSearchForward();
- upButton.setSelected(!searchForward);
- downButton.setSelected(searchForward);
- }
-
-
- /**
- * Removes a {@link SearchListener} from this dialog.
- *
- * @param l The listener to remove
- * @see #addSearchListener(SearchListener)
- */
- public void removeSearchListener(SearchListener l) {
- listenerList.remove(SearchListener.class, l);
- }
-
-
- /**
- * Sets the text label for the "Down" radio button.
- *
- * @param text The new text label for the "Down" radio button.
- * @see #getDownRadioButtonText
- */
- public void setDownRadioButtonText(String text) {
- downButton.setText(text);
- }
-
-
- /**
- * 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 void setFindWhatLabelText(String text) {
- findFieldLabel.setText(text);
- }
-
-
- /**
- * Sets the text for the search direction's radio buttons' border.
- *
- * @param text The text for the search radio buttons' border.
- * @see #getSearchButtonsBorderText
- */
- public final void setSearchButtonsBorderText(String text) {
- dirPanelTitle = text;
- dirPanel.setBorder(createTitledBorder(dirPanelTitle));
- }
-
-
- /**
- * Sets the text label for the "Up" radio button.
- *
- * @param text The new text label for the "Up" radio button.
- * @see #getUpRadioButtonText
- */
- public void setUpRadioButtonText(String text) {
- upButton.setText(text);
- }
-
-
-}
+/*
+ * 04/08/2004
+ *
+ * AbstractFindReplaceSearchDialog.java - Base class for FindDialog and
+ * ReplaceDialog.
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.License.txt file for details.
+ */
+package org.fife.rsta.ui.search;
+
+import java.awt.BorderLayout;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.beans.PropertyChangeEvent;
+import javax.swing.AbstractAction;
+import javax.swing.ActionMap;
+import javax.swing.BoxLayout;
+import javax.swing.ButtonGroup;
+import javax.swing.InputMap;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JRootPane;
+import javax.swing.KeyStroke;
+import javax.swing.UIManager;
+import javax.swing.event.EventListenerList;
+import javax.swing.text.JTextComponent;
+
+import org.fife.rsta.ui.UIUtil;
+import org.fife.ui.rtextarea.SearchContext;
+
+
+/**
+ * This is the base class for {@link FindDialog} and {@link ReplaceDialog}. It
+ * is basically all the features common to the two dialogs that weren't
+ * taken care of in {@link AbstractSearchDialog}.
+ *
+ * @author Robert Futrell
+ * @version 0.1
+ */
+public abstract class AbstractFindReplaceDialog extends AbstractSearchDialog {
+
+ /**
+ * Property fired when the user toggles the search direction radio buttons.
+ */
+ public static final String SEARCH_DOWNWARD_PROPERTY = "SearchDialog.SearchDownward";
+
+ // The radio buttons for changing the search direction.
+ protected JRadioButton upButton;
+ protected JRadioButton downButton;
+ protected JPanel dirPanel;
+ private String dirPanelTitle;
+ protected JLabel findFieldLabel;
+ protected JButton findNextButton;
+
+ /**
+ * The "mark all" check box.
+ */
+ protected JCheckBox markAllCheckBox;
+
+ /**
+ * Folks listening for events in this dialog.
+ */
+ private EventListenerList listenerList;
+
+
+ /**
+ * Constructor.
+ *
+ * @param owner The dialog that owns this search dialog.
+ */
+ public AbstractFindReplaceDialog(Dialog owner) {
+ super(owner);
+ init();
+ }
+
+ /**
+ * Constructor. Does the initializing for parts common to
+ * FindDialog and ReplaceDialog that isn't
+ * taken care of in AbstractSearchDialog's constructor.
+ *
+ * @param owner The window that owns this search dialog.
+ */
+ public AbstractFindReplaceDialog(Frame owner) {
+ super(owner);
+ init();
+ }
+
+
+ /**
+ * Listens for action events in this dialog.
+ *
+ * @param e The event that occurred.
+ */
+ @Override
+ public void actionPerformed(ActionEvent e) {
+
+ String command = e.getActionCommand();
+
+ if ("UpRadioButtonClicked".equals(command)) {
+ context.setSearchForward(false);
+ }
+
+ else if ("DownRadioButtonClicked".equals(command)) {
+ context.setSearchForward(true);
+ }
+
+ else if ("MarkAll".equals(command)) {
+ boolean checked = markAllCheckBox.isSelected();
+ context.setMarkAll(checked);
+ }
+
+ else if (SearchEvent.Type.FIND.name().equals(command)) {
+ doSearch(context.getSearchForward()); // Keep current direction
+ }
+
+ else {
+ super.actionPerformed(e);
+ }
+
+ }
+
+
+ /**
+ * Adds a {@link SearchListener} to this dialog. This listener will
+ * be notified when find or replace operations are triggered. For
+ * example, for a Replace dialog, a listener will receive notification
+ * when the user clicks "Find", "Replace", or "Replace All".
+ *
+ * @param l The listener to add.
+ * @see #removeSearchListener(SearchListener)
+ */
+ public void addSearchListener(SearchListener l) {
+ listenerList.add(SearchListener.class, l);
+ }
+
+
+ private void doSearch(boolean forward) {
+
+ // Add the item to the combo box's list, if it isn't already there.
+ JTextComponent tc = UIUtil.getTextComponent(findTextCombo);
+ findTextCombo.addItem(tc.getText());
+ context.setSearchFor(getSearchString());
+
+ // If the ask is to search in the opposite direction from the UI's
+ // current direction, use a cloned search context to avoid updating
+ // the UI when we shouldn't (e.g. from a keyboard shortcut to search
+ // backward).
+ SearchContext contextToFire = context;
+ if (forward != context.getSearchForward()) {
+ contextToFire = context.clone();
+ contextToFire.setSearchForward(forward);
+ }
+
+ // Let parent application know
+ fireSearchEvent(SearchEvent.Type.FIND, contextToFire);
+ }
+
+ /**
+ * Notifies all listeners that have registered interest in notification for
+ * this event type. The event instance is lazily created using the
+ * event parameter.
+ *
+ * @param type The type of search.
+ * @param context The search context to fire. If this is {@code null}, this
+ * dialog's current context (e.g. its current state) is used. This
+ * parameter allows for scenarios where we want to search differently
+ * than what our UI displays; for example, binding a keyboard
+ * shortcut to "search backwards" no matter what.
+ */
+ protected void fireSearchEvent(SearchEvent.Type type, SearchContext context) {
+
+ if (context == null) {
+ context = this.context;
+ }
+
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ SearchEvent e = null;
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length - 2; i >= 0; i -= 2) {
+ if (listeners[i] == SearchListener.class) {
+ // Lazily create the event:
+ if (e == null) {
+ e = new SearchEvent(this, type, context);
+ }
+ ((SearchListener)listeners[i+1]).searchEvent(e);
+ }
+ }
+ }
+
+
+ /**
+ * Returns the text for the "Down" radio button.
+ *
+ * @return The text for the "Down" radio button.
+ * @see #setDownRadioButtonText
+ */
+ public final String getDownRadioButtonText() {
+ return downButton.getText();
+ }
+
+
+ /**
+ * 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();
+ }
+
+
+ /**
+ * Returns the text for the search direction's radio buttons' border.
+ *
+ * @return The text for the search radio buttons' border.
+ * @see #setSearchButtonsBorderText
+ */
+ public final String getSearchButtonsBorderText() {
+ return dirPanelTitle;
+ }
+
+
+ /**
+ * Returns the text for the "Up" radio button.
+ *
+ * @return The text for the "Up" radio button.
+ * @see #setUpRadioButtonText
+ */
+ public final String getUpRadioButtonText() {
+ return upButton.getText();
+ }
+
+
+ /**
+ * Called whenever a property in the search context is modified.
+ * Subclasses should override if they listen for additional properties.
+ *
+ * @param e The property change event fired.
+ */
+ @Override
+ protected void handleSearchContextPropertyChanged(PropertyChangeEvent e) {
+
+ String prop = e.getPropertyName();
+
+ if (SearchContext.PROPERTY_SEARCH_FORWARD.equals(prop)) {
+ boolean newValue = (Boolean) e.getNewValue();
+ JRadioButton button = newValue ? downButton : upButton;
+ button.setSelected(true);
+ }
+
+ else if (SearchContext.PROPERTY_MARK_ALL.equals(prop)) {
+ boolean newValue = (Boolean) e.getNewValue();
+ markAllCheckBox.setSelected(newValue);
+ }
+
+ else {
+ super.handleSearchContextPropertyChanged(e);
+ }
+
+ }
+
+
+ @Override
+ protected FindReplaceButtonsEnableResult handleToggleButtons() {
+
+ FindReplaceButtonsEnableResult er = super.handleToggleButtons();
+ boolean enable = er.getEnable();
+
+ findNextButton.setEnabled(enable);
+
+ // setBackground doesn't show up with XP Look and Feel!
+ JTextComponent tc = UIUtil.getTextComponent(findTextCombo);
+ tc.setForeground(enable ? UIManager.getColor("TextField.foreground") :
+ UIUtil.getErrorTextForeground());
+
+ String tooltip = SearchUtil.getToolTip(er);
+ tc.setToolTipText(tooltip); // Always set, even if null
+
+ return er;
+
+ }
+
+
+ private void init() {
+
+ listenerList = new EventListenerList();
+
+ // Make a panel containing the "search up/down" radio buttons.
+ dirPanel = new JPanel();
+ dirPanel.setLayout(new BoxLayout(dirPanel, BoxLayout.LINE_AXIS));
+ setSearchButtonsBorderText(getString("Direction"));
+ ButtonGroup bg = new ButtonGroup();
+ upButton = new JRadioButton(getString("Up"), false);
+ upButton.setMnemonic((int)getString("UpMnemonic").charAt(0));
+ downButton = new JRadioButton(getString("Down"), true);
+ downButton.setMnemonic((int)getString("DownMnemonic").charAt(0));
+ upButton.setActionCommand("UpRadioButtonClicked");
+ upButton.addActionListener(this);
+ downButton.setActionCommand("DownRadioButtonClicked");
+ downButton.addActionListener(this);
+ bg.add(upButton);
+ bg.add(downButton);
+ dirPanel.add(upButton);
+ dirPanel.add(downButton);
+
+ // Initialize the "mark all" button.
+ markAllCheckBox = new JCheckBox(getString("MarkAll"));
+ markAllCheckBox.setMnemonic((int)getString("MarkAllMnemonic").charAt(0));
+ markAllCheckBox.setActionCommand("MarkAll");
+ markAllCheckBox.addActionListener(this);
+
+ // Rearrange the search conditions panel.
+ searchConditionsPanel.removeAll();
+ searchConditionsPanel.setLayout(new BorderLayout());
+ JPanel temp = new JPanel();
+ temp.setLayout(new BoxLayout(temp, BoxLayout.PAGE_AXIS));
+ temp.add(caseCheckBox);
+ temp.add(wholeWordCheckBox);
+ temp.add(wrapCheckBox);
+ searchConditionsPanel.add(temp, BorderLayout.LINE_START);
+ temp = new JPanel();
+ temp.setLayout(new BoxLayout(temp, BoxLayout.PAGE_AXIS));
+ temp.add(regexCheckBox);
+ temp.add(markAllCheckBox);
+ searchConditionsPanel.add(temp, BorderLayout.LINE_END);
+
+ // Create the "Find what" label.
+ findFieldLabel = UIUtil.newLabel(getBundle(), "FindWhat",findTextCombo);
+
+ // Create a "Find Next" button.
+ findNextButton = UIUtil.newButton(getBundle(), "Find");
+ findNextButton.setActionCommand(SearchEvent.Type.FIND.name());
+ findNextButton.addActionListener(this);
+ findNextButton.setDefaultCapable(true);
+ findNextButton.setEnabled(false); // Initially, nothing to look for.
+
+ installKeyboardActions();
+
+ }
+
+
+ /**
+ * Adds extra keyboard actions for Find and Replace dialogs.
+ */
+ private void installKeyboardActions() {
+
+ JRootPane rootPane = getRootPane();
+ InputMap im = rootPane.getInputMap(
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ ActionMap am = rootPane.getActionMap();
+
+ int modifier = getToolkit().getMenuShortcutKeyMaskEx();
+ KeyStroke ctrlF = KeyStroke.getKeyStroke(KeyEvent.VK_F, modifier);
+ im.put(ctrlF, "focusSearchForField");
+ am.put("focusSearchForField", new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ AbstractFindReplaceDialog.this.requestFocus();
+ }
+ });
+
+ // Shift+Enter and Ctrl+Enter both do a backwards/opposite search
+ int shift = InputEvent.SHIFT_DOWN_MASK;
+ int ctrl = InputEvent.CTRL_DOWN_MASK;
+ if (System.getProperty("os.name").toLowerCase().contains("os x")) {
+ ctrl = InputEvent.META_DOWN_MASK;
+ }
+ KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, shift);
+ im.put(ks, "searchBackward");
+ ks = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, ctrl);
+ im.put(ks, "searchBackward");
+ am.put("searchBackward", new AbstractAction() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ doSearch(!context.getSearchForward());
+ }
+ });
+ }
+
+
+ /**
+ * Overridden to initialize UI elements specific to this subclass.
+ */
+ @Override
+ protected void refreshUIFromContext() {
+ if (this.markAllCheckBox==null) {
+ return; // First time through, UI not realized yet
+ }
+ super.refreshUIFromContext();
+ markAllCheckBox.setSelected(context.getMarkAll());
+ boolean searchForward = context.getSearchForward();
+ upButton.setSelected(!searchForward);
+ downButton.setSelected(searchForward);
+ }
+
+
+ /**
+ * Removes a {@link SearchListener} from this dialog.
+ *
+ * @param l The listener to remove
+ * @see #addSearchListener(SearchListener)
+ */
+ public void removeSearchListener(SearchListener l) {
+ listenerList.remove(SearchListener.class, l);
+ }
+
+
+ /**
+ * Sets the text label for the "Down" radio button.
+ *
+ * @param text The new text label for the "Down" radio button.
+ * @see #getDownRadioButtonText
+ */
+ public void setDownRadioButtonText(String text) {
+ downButton.setText(text);
+ }
+
+
+ /**
+ * 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 void setFindWhatLabelText(String text) {
+ findFieldLabel.setText(text);
+ }
+
+
+ /**
+ * Sets the text for the search direction's radio buttons' border.
+ *
+ * @param text The text for the search radio buttons' border.
+ * @see #getSearchButtonsBorderText
+ */
+ public final void setSearchButtonsBorderText(String text) {
+ dirPanelTitle = text;
+ dirPanel.setBorder(createTitledBorder(dirPanelTitle));
+ }
+
+
+ /**
+ * Sets the text label for the "Up" radio button.
+ *
+ * @param text The new text label for the "Up" radio button.
+ * @see #getUpRadioButtonText
+ */
+ public void setUpRadioButtonText(String text) {
+ upButton.setText(text);
+ }
+
+
+}
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindDialog.java b/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindDialog.java
index 5a84950..c71ccea 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindDialog.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindDialog.java
@@ -1,271 +1,271 @@
-/*
- * 11/14/2003
- *
- * FindDialog - Dialog for finding text in a GUI.
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.License.txt file for details.
- */
-package org.fife.rsta.ui.search;
-
-import java.awt.BorderLayout;
-import java.awt.ComponentOrientation;
-import java.awt.Dialog;
-import java.awt.Frame;
-import java.awt.GridLayout;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
-import javax.swing.BorderFactory;
-import javax.swing.BoxLayout;
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-import javax.swing.text.JTextComponent;
-import javax.swing.SpringLayout;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-
-import org.fife.rsta.ui.AssistanceIconPanel;
-import org.fife.rsta.ui.ResizableFrameContentPane;
-import org.fife.rsta.ui.UIUtil;
-import org.fife.ui.rtextarea.SearchContext;
-import org.fife.ui.rtextarea.SearchEngine;
-
-
-/**
- * A "Find" dialog similar to those found in most Windows text editing
- * applications. Contains many search options, including:An application can use a FindDialog as follows. It is
- * suggested that you create an Action or something similar to
- * facilitate "bringing up" the Find dialog. Have the main application contain
- * an object that implements {@link SearchListener}. This object will receive
- * {@link SearchEvent}s of the following types from the Find dialog:
- *
FindDialog.
- *
- * @param owner The parent dialog.
- * @param listener The component that listens for {@link SearchEvent}s.
- */
- public FindDialog(Dialog owner, SearchListener listener) {
- super(owner);
- init(listener);
- }
-
-
- /**
- * Creates a new FindDialog.
- *
- * @param owner The main window that owns this dialog.
- * @param listener The component that listens for {@link SearchEvent}s.
- */
- public FindDialog(Frame owner, SearchListener listener) {
- super(owner);
- init(listener);
- }
-
-
- /**
- * Initializes find dialog-specific initialization stuff.
- *
- * @param listener The component that listens for {@link SearchEvent}s.
- */
- private void init(SearchListener listener) {
-
- this.searchListener = listener;
-
- ComponentOrientation orientation = ComponentOrientation.
- getOrientation(getLocale());
-
- // Make a panel containing the "Find" edit box.
- JPanel enterTextPane = new JPanel(new SpringLayout());
- enterTextPane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
- JTextComponent textField = UIUtil.getTextComponent(findTextCombo);
- textField.addFocusListener(new FindFocusAdapter());
- textField.getDocument().addDocumentListener(new FindDocumentListener());
- JPanel temp = new JPanel(new BorderLayout());
- temp.add(findTextCombo);
- AssistanceIconPanel aip = new AssistanceIconPanel(findTextCombo);
- temp.add(aip, BorderLayout.LINE_START);
- if (orientation.isLeftToRight()) {
- enterTextPane.add(findFieldLabel);
- enterTextPane.add(temp);
- }
- else {
- enterTextPane.add(temp);
- enterTextPane.add(findFieldLabel);
- }
-
- UIUtil.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(new BorderLayout());
- temp = new JPanel(new BorderLayout());
- bottomPanel.setBorder(UIUtil.getEmpty5Border());
- temp.add(searchConditionsPanel, BorderLayout.LINE_START);
- JPanel temp2 = new JPanel(new BorderLayout());
- temp2.add(dirPanel, BorderLayout.NORTH);
- temp.add(temp2);
- 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(enterTextPane);
- leftPanel.add(bottomPanel);
-
- // Make a panel containing the action buttons.
- JPanel buttonPanel = new JPanel();
- buttonPanel.setLayout(new GridLayout(2,1, 5,5));
- buttonPanel.add(findNextButton);
- buttonPanel.add(cancelButton);
- 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());
- if (orientation.isLeftToRight()) {
- contentPane.setBorder(BorderFactory.createEmptyBorder(5,0,0,5));
- }
- else {
- contentPane.setBorder(BorderFactory.createEmptyBorder(5,5,0,0));
- }
- 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(getString("FindDialogTitle"));
- setResizable(true);
- pack();
- setLocationRelativeTo(getParent());
-
- setSearchContext(new SearchContext());
- addSearchListener(listener);
-
- applyComponentOrientation(orientation);
-
- }
-
-
- /**
- * Overrides JDialog's setVisible method; decides
- * whether buttons are enabled.
- *
- * @param visible Whether the dialog should be visible.
- */
- @Override
- public void setVisible(boolean visible) {
-
- if (visible) {
-
- // Select text entered into the UI
- String text = searchListener.getSelectedText();
- if (text!=null) {
- findTextCombo.addItem(text);
- }
-
- String selectedItem = findTextCombo.getSelectedString();
- boolean nonEmpty = selectedItem!=null && !selectedItem.isEmpty();
- findNextButton.setEnabled(nonEmpty);
- super.setVisible(true);
- focusFindTextField();
-
- }
-
- else {
- super.setVisible(false);
- }
-
- }
-
- /**
- * This method should be called whenever the LookAndFeel of
- * the application changes. This calls
- * SwingUtilities.updateComponentTreeUI(this) and does
- * other necessary things.
- * Note that this is not an override, as JDialogs don't have an
- * updateUI() method.
- */
- public void updateUI() {
- SwingUtilities.updateComponentTreeUI(this);
- pack();
- JTextComponent textField = UIUtil.getTextComponent(findTextCombo);
- textField.addFocusListener(new FindFocusAdapter());
- textField.getDocument().addDocumentListener(new FindDocumentListener());
- }
-
-
- /**
- * Listens for changes in the text field (find search field).
- */
- private final class FindDocumentListener implements DocumentListener {
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- handleToggleButtons();
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- JTextComponent comp = UIUtil.getTextComponent(findTextCombo);
- if (comp.getDocument().getLength()==0) {
- findNextButton.setEnabled(false);
- }
- else {
- handleToggleButtons();
- }
- }
-
- @Override
- 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 final class FindFocusAdapter extends FocusAdapter {
-
- @Override
- public void focusGained(FocusEvent e) {
- UIUtil.getTextComponent(findTextCombo).selectAll();
- }
-
- }
-}
+/*
+ * 11/14/2003
+ *
+ * FindDialog - Dialog for finding text in a GUI.
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.License.txt file for details.
+ */
+package org.fife.rsta.ui.search;
+
+import java.awt.BorderLayout;
+import java.awt.ComponentOrientation;
+import java.awt.Dialog;
+import java.awt.Frame;
+import java.awt.GridLayout;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.text.JTextComponent;
+import javax.swing.SpringLayout;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import org.fife.rsta.ui.AssistanceIconPanel;
+import org.fife.rsta.ui.ResizableFrameContentPane;
+import org.fife.rsta.ui.UIUtil;
+import org.fife.ui.rtextarea.SearchContext;
+import org.fife.ui.rtextarea.SearchEngine;
+
+
+/**
+ * A "Find" dialog similar to those found in most Windows text editing
+ * applications. Contains many search options, including:
+ *
An application can use a FindDialog as follows. It is
+ * suggested that you create an Action or something similar to
+ * facilitate "bringing up" the Find dialog. Have the main application contain
+ * an object that implements {@link SearchListener}. This object will receive
+ * {@link SearchEvent}s of the following types from the Find dialog:
+ *
FindDialog.
+ *
+ * @param owner The parent dialog.
+ * @param listener The component that listens for {@link SearchEvent}s.
+ */
+ public FindDialog(Dialog owner, SearchListener listener) {
+ super(owner);
+ init(listener);
+ }
+
+
+ /**
+ * Creates a new FindDialog.
+ *
+ * @param owner The main window that owns this dialog.
+ * @param listener The component that listens for {@link SearchEvent}s.
+ */
+ public FindDialog(Frame owner, SearchListener listener) {
+ super(owner);
+ init(listener);
+ }
+
+
+ /**
+ * Initializes find dialog-specific initialization stuff.
+ *
+ * @param listener The component that listens for {@link SearchEvent}s.
+ */
+ private void init(SearchListener listener) {
+
+ this.searchListener = listener;
+
+ ComponentOrientation orientation = ComponentOrientation.
+ getOrientation(getLocale());
+
+ // Make a panel containing the "Find" edit box.
+ JPanel enterTextPane = new JPanel(new SpringLayout());
+ enterTextPane.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
+ JTextComponent textField = UIUtil.getTextComponent(findTextCombo);
+ textField.addFocusListener(new FindFocusAdapter());
+ textField.getDocument().addDocumentListener(new FindDocumentListener());
+ JPanel temp = new JPanel(new BorderLayout());
+ temp.add(findTextCombo);
+ AssistanceIconPanel aip = new AssistanceIconPanel(findTextCombo);
+ temp.add(aip, BorderLayout.LINE_START);
+ if (orientation.isLeftToRight()) {
+ enterTextPane.add(findFieldLabel);
+ enterTextPane.add(temp);
+ }
+ else {
+ enterTextPane.add(temp);
+ enterTextPane.add(findFieldLabel);
+ }
+
+ UIUtil.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(new BorderLayout());
+ temp = new JPanel(new BorderLayout());
+ bottomPanel.setBorder(UIUtil.getEmpty5Border());
+ temp.add(searchConditionsPanel, BorderLayout.LINE_START);
+ JPanel temp2 = new JPanel(new BorderLayout());
+ temp2.add(dirPanel, BorderLayout.NORTH);
+ temp.add(temp2);
+ 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(enterTextPane);
+ leftPanel.add(bottomPanel);
+
+ // Make a panel containing the action buttons.
+ JPanel buttonPanel = new JPanel();
+ buttonPanel.setLayout(new GridLayout(2,1, 5,5));
+ buttonPanel.add(findNextButton);
+ buttonPanel.add(cancelButton);
+ 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());
+ if (orientation.isLeftToRight()) {
+ contentPane.setBorder(BorderFactory.createEmptyBorder(5,0,0,5));
+ }
+ else {
+ contentPane.setBorder(BorderFactory.createEmptyBorder(5,5,0,0));
+ }
+ 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(getString("FindDialogTitle"));
+ setResizable(true);
+ pack();
+ setLocationRelativeTo(getParent());
+
+ setSearchContext(new SearchContext());
+ addSearchListener(listener);
+
+ applyComponentOrientation(orientation);
+
+ }
+
+
+ /**
+ * Overrides JDialog's setVisible method; decides
+ * whether buttons are enabled.
+ *
+ * @param visible Whether the dialog should be visible.
+ */
+ @Override
+ public void setVisible(boolean visible) {
+
+ if (visible) {
+
+ // Select text entered into the UI
+ String text = searchListener.getSelectedText();
+ if (text!=null) {
+ findTextCombo.addItem(text);
+ }
+
+ String selectedItem = findTextCombo.getSelectedString();
+ boolean nonEmpty = selectedItem!=null && !selectedItem.isEmpty();
+ findNextButton.setEnabled(nonEmpty);
+ super.setVisible(true);
+ focusFindTextField();
+
+ }
+
+ else {
+ super.setVisible(false);
+ }
+
+ }
+
+ /**
+ * This method should be called whenever the LookAndFeel of
+ * the application changes. This calls
+ * SwingUtilities.updateComponentTreeUI(this) and does
+ * other necessary things.
+ * Note that this is not an override, as JDialogs don't have an
+ * updateUI() method.
+ */
+ public void updateUI() {
+ SwingUtilities.updateComponentTreeUI(this);
+ pack();
+ JTextComponent textField = UIUtil.getTextComponent(findTextCombo);
+ textField.addFocusListener(new FindFocusAdapter());
+ textField.getDocument().addDocumentListener(new FindDocumentListener());
+ }
+
+
+ /**
+ * Listens for changes in the text field (find search field).
+ */
+ private final class FindDocumentListener implements DocumentListener {
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ handleToggleButtons();
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ JTextComponent comp = UIUtil.getTextComponent(findTextCombo);
+ if (comp.getDocument().getLength()==0) {
+ findNextButton.setEnabled(false);
+ }
+ else {
+ handleToggleButtons();
+ }
+ }
+
+ @Override
+ 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 final class FindFocusAdapter extends FocusAdapter {
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ UIUtil.getTextComponent(findTextCombo).selectAll();
+ }
+
+ }
+}
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindReplaceButtonsEnableResult.java b/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindReplaceButtonsEnableResult.java
index 109cabf..7a61b51 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindReplaceButtonsEnableResult.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindReplaceButtonsEnableResult.java
@@ -1,43 +1,43 @@
-/*
- * 09/20/2013
- *
- * FindReplaceButtonsEnableResult - Whether "find" and "replace" buttons
- * should be enabled.
- *
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.license.txt file for details.
- */
-package org.fife.rsta.ui.search;
-
-/**
- * Returns the result of whether the "action" buttons such as "Find"
- * and "Replace" should be enabled.
- *
- * @author Robert Futrell
- * @version 1.0
- */
-// NOTE: This class is public to enable applications to create custom search
-// dialogs that extend AbstractSearchDialog, such as a FindInFilesDialog.
-public class FindReplaceButtonsEnableResult {
-
- private boolean enable;
- private String error;
-
- public FindReplaceButtonsEnableResult(boolean enable, String error) {
- this.enable = enable;
- this.error = error;
- }
-
- public boolean getEnable() {
- return enable;
- }
-
- public String getError() {
- return error;
- }
-
- public void setEnable(boolean enable) {
- this.enable = enable;
- }
-
-}
+/*
+ * 09/20/2013
+ *
+ * FindReplaceButtonsEnableResult - Whether "find" and "replace" buttons
+ * should be enabled.
+ *
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.license.txt file for details.
+ */
+package org.fife.rsta.ui.search;
+
+/**
+ * Returns the result of whether the "action" buttons such as "Find"
+ * and "Replace" should be enabled.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+// NOTE: This class is public to enable applications to create custom search
+// dialogs that extend AbstractSearchDialog, such as a FindInFilesDialog.
+public class FindReplaceButtonsEnableResult {
+
+ private boolean enable;
+ private String error;
+
+ public FindReplaceButtonsEnableResult(boolean enable, String error) {
+ this.enable = enable;
+ this.error = error;
+ }
+
+ public boolean getEnable() {
+ return enable;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public void setEnable(boolean enable) {
+ this.enable = enable;
+ }
+
+}
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindToolBar.java b/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindToolBar.java
index 53009c3..4ca0b85 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindToolBar.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/search/FindToolBar.java
@@ -1,805 +1,805 @@
-/*
- * 09/20/2013
- *
- * FindToolBar - A toolbar for "find" operations in text areas.
- *
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.license.txt file for details.
- */
-package org.fife.rsta.ui.search;
-
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.ResourceBundle;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import javax.swing.BorderFactory;
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.InputMap;
-import javax.swing.JButton;
-import javax.swing.JCheckBox;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import javax.swing.KeyStroke;
-import javax.swing.Timer;
-import javax.swing.UIManager;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.JTextComponent;
-
-import org.fife.rsta.ui.AssistanceIconPanel;
-import org.fife.rsta.ui.UIUtil;
-import org.fife.ui.rtextarea.SearchContext;
-
-
-/**
- * A toolbar for search operations in a text editor application. This provides
- * a more seamless experience than using a Find or Replace dialog.
- *
- * @author Robert Futrell
- * @version 0.5
- * @see FindDialog
- */
-public class FindToolBar extends JPanel {
-
- private SearchContext context;
- protected ToolBarListener listener;
- protected FindFieldListener findFieldListener;
- protected SearchComboBox findCombo;
- protected SearchComboBox replaceCombo;
- protected JButton findButton;
- protected JButton findPrevButton;
- protected JCheckBox matchCaseCheckBox;
- protected JCheckBox wholeWordCheckBox;
- protected JCheckBox regexCheckBox;
- protected JCheckBox markAllCheckBox;
- protected JCheckBox wrapCheckBox;
- private JLabel infoLabel;
- private Timer markAllTimer;
-
- /**
- * Flag to prevent double-modification of SearchContext when e.g. a
- * FindToolBar and ReplaceToolBar share the same SearchContext.
- */
- private boolean settingFindTextFromEvent;
-
- protected static final ResourceBundle SEARCH_MSG = ResourceBundle.getBundle(
- "org.fife.rsta.ui.search.Search");
- protected static final ResourceBundle MSG = ResourceBundle.getBundle(
- "org.fife.rsta.ui.search.SearchToolBar");
-
- /**
- * Creates the toolbar.
- *
- * @param listener An entity listening for search events.
- */
- public FindToolBar(SearchListener listener) {
-
- // Keep focus in this component when tabbing through search controls
- setFocusCycleRoot(true);
-
- markAllTimer = new Timer(300, new MarkAllEventNotifier());
- markAllTimer.setRepeats(false);
-
- setLayout(new BorderLayout());
- setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
- addSearchListener(listener);
- this.listener = new ToolBarListener();
-
- // The user should set a shared instance between all subclass
- // instances, but to be safe we set individual ones.
- setSearchContext(new SearchContext());
-
- ComponentOrientation orientation = ComponentOrientation.
- getOrientation(getLocale());
-
- add(Box.createHorizontalStrut(5));
-
- add(createFieldPanel());
-
- Box rest = new Box(BoxLayout.LINE_AXIS);
- add(rest, BorderLayout.LINE_END);
-
- rest.add(Box.createHorizontalStrut(5));
- rest.add(createButtonPanel());
- rest.add(Box.createHorizontalStrut(15));
-
- JLabel infoLabel = new JLabel();
- rest.add(infoLabel);
-
- rest.add(Box.createHorizontalGlue());
-
- // Get ready to go.
- applyComponentOrientation(orientation);
- }
-
-
- /**
- * Adds a {@link SearchListener} to this toolbar. This listener will
- * be notified when find or replace operations are triggered.
- *
- * @param l The listener to add.
- * @see #removeSearchListener(SearchListener)
- */
- public void addSearchListener(SearchListener l) {
- listenerList.add(SearchListener.class, l);
- }
-
-
- protected Container createButtonPanel() {
-
- Box panel = new Box(BoxLayout.LINE_AXIS);
- createFindButtons();
-
- JPanel filler = new JPanel(new BorderLayout());
- filler.setBorder(BorderFactory.createEmptyBorder());
- filler.add(findButton);//bp);
- panel.add(filler);
- panel.add(Box.createHorizontalStrut(6));
-
- matchCaseCheckBox = createCB("MatchCase");
- panel.add(matchCaseCheckBox);
-
- regexCheckBox = createCB("RegEx");
- panel.add(regexCheckBox);
-
- wholeWordCheckBox = createCB("WholeWord");
- panel.add(wholeWordCheckBox);
-
- markAllCheckBox = createCB("MarkAll");
- panel.add(markAllCheckBox);
-
- wrapCheckBox = createCB("Wrap");
- panel.add(wrapCheckBox);
-
- return panel;
-
- }
-
-
- protected JCheckBox createCB(String key) {
- JCheckBox cb = new JCheckBox(SEARCH_MSG.getString(key));
- cb.addActionListener(listener);
- cb.addMouseListener(listener);
- return cb;
- }
-
-
- /**
- * Wraps the specified component in a panel with a leading "content assist
- * available" icon in front of it.
- *
- * @param comp The component with content assist.
- * @return The wrapper panel.
- */
- protected Container createContentAssistablePanel(JComponent comp) {
- JPanel temp = new JPanel(new BorderLayout());
- temp.add(comp);
- AssistanceIconPanel aip = new AssistanceIconPanel(comp);
- temp.add(aip, BorderLayout.LINE_START);
- return temp;
- }
-
-
- protected Container createFieldPanel() {
-
- findFieldListener = new FindFieldListener();
- JPanel temp = new JPanel(new BorderLayout());
-
- findCombo = new SearchComboBox(this, false);
- JTextComponent findField = UIUtil.getTextComponent(findCombo);
- findFieldListener.install(findField);
- temp.add(createContentAssistablePanel(findCombo));
-
- return temp;
- }
-
-
- /**
- * Creates the buttons for this toolbar.
- */
- protected void createFindButtons() {
-
- findPrevButton = new JButton(MSG.getString("FindPrev"));
- makeEnterActivateButton(findPrevButton);
- findPrevButton.setActionCommand("FindPrevious");
- findPrevButton.addActionListener(listener);
- findPrevButton.setEnabled(false);
-
- findButton = new JButton(SEARCH_MSG.getString("Find")) {
- @Override
- public Dimension getPreferredSize() {
- return findPrevButton.getPreferredSize(); // Always bigger
- }
- };
- makeEnterActivateButton(findButton);
- findButton.setToolTipText(MSG.getString("Find.ToolTip"));
- findButton.setActionCommand("FindNext");
- findButton.addActionListener(listener);
- findButton.setEnabled(false);
-
- }
-
-
- /**
- * Forces a "mark all" event to be sent out, if "mark all" is enabled.
- *
- * @param delay If the delay should be honored.
- */
- protected void doMarkAll(boolean delay) {
- if (context.getMarkAll() && !settingFindTextFromEvent) {
- if (delay) {
- markAllTimer.restart();
- }
- else {
- fireMarkAllEvent();
- }
- }
- }
-
-
- void doSearch(boolean forward) {
- if (forward) {
- findButton.doClick(0);
- }
- else {
- findPrevButton.doClick(0);
- }
- }
-
-
- /**
- * Fires a "mark all" search event.
- */
- private void fireMarkAllEvent() {
- SearchEvent se = new SearchEvent(this, SearchEvent.Type.MARK_ALL,
- context);
- fireSearchEvent(se);
- }
-
-
- /**
- * Notifies all listeners that have registered interest in notification of
- * this event type. The event instance is lazily created using the
- * event parameter.
- *
- * @param e The ActionEvent object coming from a
- * child component.
- */
- protected void fireSearchEvent(SearchEvent e) {
- // Process the listeners last to first, notifying
- // those that are interested in this event
- SearchListener[] listeners = listenerList.
- getListeners(SearchListener.class);
- int count = listeners==null ? 0 : listeners.length;
- for (int i=count-1; i>=0; i--) {
- listeners[i].searchEvent(e);
- }
- }
-
-
- protected String getFindText() {
- return UIUtil.getTextComponent(findCombo).getText();
- }
-
-
- /**
- * Returns the delay between when the user types and when a "mark all"
- * event is fired (assuming "mark all" is enabled), in milliseconds.
- *
- * @return The delay.
- * @see #setMarkAllDelay(int)
- */
- public int getMarkAllDelay() {
- return markAllTimer.getInitialDelay();
- }
-
-
- protected String getReplaceText() {
- if (replaceCombo==null) {
- return null;
- }
- return UIUtil.getTextComponent(replaceCombo).getText();
- }
-
-
- /**
- * Returns the search context for this toolbar.
- *
- * @return The search context.
- * @see #setSearchContext(SearchContext)
- */
- public SearchContext getSearchContext() {
- return context;
- }
-
-
- /**
- * Called when the regex checkbox is clicked (or its value is modified
- * via a change to the search context). Subclasses can override
- * to add custom behavior, but should call the super implementation.
- */
- protected void handleRegExCheckBoxClicked() {
- handleToggleButtons();
- // "Content assist" support
- boolean b = regexCheckBox.isSelected();
- findCombo.setAutoCompleteEnabled(b);
- }
-
-
- /**
- * Creates a search event object and notifies all registered listeners.
- *
- * @param e The event.
- */
- protected void handleSearchAction(ActionEvent e) {
-
- SearchEvent.Type type = null;
- boolean forward = true;
- String action = e.getActionCommand();
- // JTextField returns *_DOWN_* modifiers, JButton returns the others (!)
- int allowedModifiers =
- InputEvent.CTRL_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK | // field
- ActionEvent.CTRL_MASK|ActionEvent.SHIFT_MASK; // JButton
-
- if ("FindNext".equals(action)) {
- type = SearchEvent.Type.FIND;
- int mods = e.getModifiers();
- forward = (mods&allowedModifiers)==0;
- // Add the item to the combo box's list, if it isn't already there.
- JTextComponent tc = UIUtil.getTextComponent(findCombo);
- findCombo.addItem(tc.getText());
- }
- else if ("FindPrevious".equals(action)) {
- type = SearchEvent.Type.FIND;
- forward = false;
- // Add the item to the combo box's list, if it isn't already there.
- JTextComponent tc = UIUtil.getTextComponent(findCombo);
- findCombo.addItem(tc.getText());
- }
- else if ("Replace".equals(action)) {
- type = SearchEvent.Type.REPLACE;
- int mods = e.getModifiers();
- forward = (mods&allowedModifiers)==0;
- // Add the item to the combo box's list, if it isn't already there.
- JTextComponent tc = UIUtil.getTextComponent(findCombo);
- findCombo.addItem(tc.getText());
- tc = UIUtil.getTextComponent(replaceCombo);
- replaceCombo.addItem(tc.getText());
- }
- else if ("ReplaceAll".equals(action)) {
- type = SearchEvent.Type.REPLACE_ALL;
- // Add the item to the combo box's list, if it isn't already there.
- JTextComponent tc = UIUtil.getTextComponent(findCombo);
- findCombo.addItem(tc.getText());
- tc = UIUtil.getTextComponent(replaceCombo);
- replaceCombo.addItem(tc.getText());
- }
-
- context.setSearchFor(getFindText());
- if (replaceCombo!=null) {
- context.setReplaceWith(replaceCombo.getSelectedString());
- }
-
- // If the ask is to search in the opposite direction from the UI's
- // current direction, use a cloned search context to avoid updating
- // the UI when we shouldn't (e.g. from a keyboard shortcut to search
- // backward).
- SearchContext contextToFire = context;
- if (forward != context.getSearchForward()) {
- contextToFire = context.clone();
- contextToFire.setSearchForward(forward);
- }
-
- SearchEvent se = new SearchEvent(this, type, contextToFire);
- fireSearchEvent(se);
- handleToggleButtons(); // Replace button could toggle state
-
- }
-
-
- /**
- * Returns whether any action-related buttons (Find Next, Replace, etc.)
- * should be enabled. Subclasses can call this method when the "Find What"
- * or "Replace With" text fields are modified. They can then
- * enable/disable any components as appropriate.
- *
- * @return Whether the buttons should be enabled.
- */
- protected FindReplaceButtonsEnableResult handleToggleButtons() {
-
- FindReplaceButtonsEnableResult result =
- new FindReplaceButtonsEnableResult(true, null);
-
- String text = getFindText();
- if (text.isEmpty()) {
- result = new FindReplaceButtonsEnableResult(false, null);
- }
- else if (regexCheckBox.isSelected()) {
- try {
- Pattern.compile(text);
- } catch (PatternSyntaxException pse) {
- result = new FindReplaceButtonsEnableResult(false,
- pse.getMessage());
- }
- }
-
- boolean enable = result.getEnable();
- findButton.setEnabled(enable);
- findPrevButton.setEnabled(enable);
-
- // setBackground doesn't show up with XP Look and Feel!
- JTextComponent tc = UIUtil.getTextComponent(findCombo);
- tc.setForeground(enable ? UIManager.getColor("TextField.foreground") :
- UIUtil.getErrorTextForeground());
-
- String tooltip = SearchUtil.getToolTip(result);
- tc.setToolTipText(tooltip); // Always set, even if null
-
- return result;
-
- }
-
-
- /**
- * Initializes the UI in this toolbar from a search context. This is
- * called whenever a new search context is installed on this toolbar
- * (which should practically be never).
- */
- private void initUIFromContext() {
- if (findCombo==null) { // First time through, stuff not initialized yet
- return;
- }
- setFindText(context.getSearchFor());
- if (replaceCombo!=null) {
- setReplaceText(context.getReplaceWith());
- }
- matchCaseCheckBox.setSelected(context.getMatchCase());
- wholeWordCheckBox.setSelected(context.getWholeWord());
- regexCheckBox.setSelected(context.isRegularExpression());
- markAllCheckBox.setSelected(context.getMarkAll());
- wrapCheckBox.setSelected(context.getSearchWrap());
- }
-
-
- /**
- * Makes the Enter key activate the button. In Swing, this is a
- * complicated thing. It's LAF-dependent whether this works
- * automatically; on most LAFs, it doesn't happen. In WindowsLookAndFeel
- * it does, but *only* if the current window has a "default" button
- * specified. Since these toolbars will typically be used in "main"
- * application windows, which don't have default buttons, we'll just
- * enable this property here and now.
- *
- * @param button The button that should respond to the Enter key.
- */
- protected void makeEnterActivateButton(JButton button) {
-
- InputMap im = button.getInputMap();
-
- // Make "enter" being typed simulate clicking
- im.put(KeyStroke.getKeyStroke("ENTER"), "pressed");
- im.put(KeyStroke.getKeyStroke("released ENTER"), "released");
-
- // Make "shift+enter" being typed simulate clicking also. The listener
- // will handle the backwards searching. Not sure why the commented-out
- // versions don't work, possibly SHIFT_MASK vs. SHIFT_DOWN_MASK issue.
- //im.put(KeyStroke.getKeyStroke("pressed SHIFT ENTER"), "pressed");
- //im.put(KeyStroke.getKeyStroke("released SHIFT ENTER"), "released");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK,
- false), "pressed");
- im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK,
- true), "released");
-
- }
-
-
- /**
- * Removes a {@link SearchListener} from this toolbar.
- *
- * @param l The listener to remove
- * @see #addSearchListener(SearchListener)
- */
- public void removeSearchListener(SearchListener l) {
- listenerList.remove(SearchListener.class, l);
- }
-
-
- /**
- * Makes the find field on this toolbar request focus. If it is already
- * focused, its text is selected.
- */
- @Override
- public boolean requestFocusInWindow() {
- JTextComponent findField = UIUtil.getTextComponent(findCombo);
- findField.selectAll();
- return findField.requestFocusInWindow();
- }
-
-
- /**
- * Callback called when a contained combo box has its LookAndFeel
- * modified. This is a hack for us to add listeners back to it.
- *
- * @param combo The combo box.
- */
- void searchComboUpdateUICallback(SearchComboBox combo) {
- findFieldListener.install(UIUtil.getTextComponent(combo));
- }
-
-
- /**
- * Sets the image to display by this dialog's text fields when content
- * assistance is available.
- *
- * @param image The image. If this is {@code null}, a default image
- * (a light bulb) is used. This should be kept small, around
- * 8x8 for standard resolution monitors.
- */
- public void setContentAssistImage(Image image) {
- findCombo.setContentAssistImage(image);
- }
-
-
- protected void setFindText(String text) {
- UIUtil.getTextComponent(findCombo).setText(text);
- //findCombo.setSelectedItem(text);
- }
-
-
- /**
- * Sets the delay between when the user types and when a "mark all"
- * event is fired (assuming "mark all" is enabled), in milliseconds.
- *
- * @param millis The new delay. This should be >= zero.
- * @see #getMarkAllDelay()
- */
- public void setMarkAllDelay(int millis) {
- markAllTimer.setInitialDelay(millis);
- }
-
-
- protected void setReplaceText(String text) {
- if (replaceCombo!=null) {
- UIUtil.getTextComponent(replaceCombo).setText(text);
- //replaceCombo.setSelectedItem(text);
- }
- }
-
-
- /**
- * Sets the search context for this toolbar. You'll usually want to call
- * this method for all toolbars and give them the same search context,
- * so that their options (match case, etc.) stay in sync with one another.
- *
- * @param context The new search context. This cannot be null.
- * @see #getSearchContext()
- */
- public void setSearchContext(SearchContext context) {
- if (this.context!=null) {
- this.context.removePropertyChangeListener(listener);
- }
- this.context = context;
- this.context.addPropertyChangeListener(listener);
- initUIFromContext();
- }
-
-
- /**
- * Listens for events in this toolbar. Keeps the UI in sync with the
- * search context and vice versa.
- */
- private final class ToolBarListener extends MouseAdapter
- implements ActionListener, PropertyChangeListener {
-
- @Override
- public void actionPerformed(ActionEvent e) {
-
- Object source = e.getSource();
-
- if (source==matchCaseCheckBox) {
- context.setMatchCase(matchCaseCheckBox.isSelected());
- if (markAllCheckBox.isSelected()) {
- doMarkAll(false);
- }
- }
- else if (source==wholeWordCheckBox) {
- context.setWholeWord(wholeWordCheckBox.isSelected());
- if (markAllCheckBox.isSelected()) {
- doMarkAll(false);
- }
- }
- else if (source==regexCheckBox) {
- context.setRegularExpression(regexCheckBox.isSelected());
- if (markAllCheckBox.isSelected()) {
- doMarkAll(false);
- }
- }
- else if (source==markAllCheckBox) {
- context.setMarkAll(markAllCheckBox.isSelected());
- fireMarkAllEvent(); // Force an event to be fired
- }
- else if (source == wrapCheckBox) {
- context.setSearchWrap(wrapCheckBox.isSelected());
- }
- else {
- handleSearchAction(e);
- }
-
- }
-
- @Override
- public void mouseClicked(MouseEvent e) {
- if (e.getSource() instanceof JCheckBox) { // Always true
- findFieldListener.selectAll = false;
- findCombo.requestFocusInWindow();
- }
- }
-
- @Override
- public void propertyChange(PropertyChangeEvent e) {
-
- // A property changed on the context itself.
- String prop = e.getPropertyName();
-
- if (SearchContext.PROPERTY_MATCH_CASE.equals(prop)) {
- boolean newValue = (Boolean) e.getNewValue();
- matchCaseCheckBox.setSelected(newValue);
- }
- else if (SearchContext.PROPERTY_MATCH_WHOLE_WORD.equals(prop)) {
- boolean newValue = (Boolean) e.getNewValue();
- wholeWordCheckBox.setSelected(newValue);
- }
- //else if (SearchContext.PROPERTY_SEARCH_FORWARD.equals(prop)) {
- // boolean newValue = ((Boolean)e.getNewValue()).booleanValue();
- // ...
- //}
- //else if (SearchContext.PROPERTY_SELECTION_ONLY.equals(prop)) {
- // boolean newValue = ((Boolean)e.getNewValue()).booleanValue();
- // ...
- //}
- else if (SearchContext.PROPERTY_USE_REGEX.equals(prop)) {
- boolean newValue = (Boolean) e.getNewValue();
- regexCheckBox.setSelected(newValue);
- handleRegExCheckBoxClicked();
- }
- else if (SearchContext.PROPERTY_MARK_ALL.equals(prop)) {
- boolean newValue = (Boolean) e.getNewValue();
- markAllCheckBox.setSelected(newValue);
- // firing event handled in ActionListener, to prevent "other"
- // toolbar from firing a second event
- }
- else if (SearchContext.PROPERTY_SEARCH_FOR.equals(prop)) {
- String newValue = (String)e.getNewValue();
- String oldValue = getFindText();
- // Prevents IllegalStateExceptions
- if (!newValue.equals(oldValue)) {
- settingFindTextFromEvent = true;
- setFindText(newValue);
- settingFindTextFromEvent = false;
- }
- }
- else if (SearchContext.PROPERTY_REPLACE_WITH.equals(prop)) {
- String newValue = (String)e.getNewValue();
- String oldValue = getReplaceText();
- // Prevents IllegalStateExceptions
- if (!newValue.equals(oldValue)) {
- settingFindTextFromEvent = true;
- setReplaceText(newValue);
- settingFindTextFromEvent = false;
- }
- }
- else if (SearchContext.PROPERTY_SEARCH_WRAP.equals(prop)) {
- boolean newValue = (Boolean)e.getNewValue();
- wrapCheckBox.setSelected(newValue);
- }
-
- }
-
- }
-
-
- /**
- * Listens for events in the Find (and Replace, in the subclass) search
- * field.
- */
- protected class FindFieldListener extends KeyAdapter
- implements DocumentListener, FocusListener {
-
- protected boolean selectAll;
-
- @Override
- public void changedUpdate(DocumentEvent e) {
- }
-
- @Override
- public void focusGained(FocusEvent e) {
- JTextField field = (JTextField)e.getComponent();
- if (selectAll) {
- field.selectAll();
- }
- selectAll = true;
- }
-
- @Override
- public void focusLost(FocusEvent e) {
- }
-
- protected void handleDocumentEvent(DocumentEvent e) {
- handleToggleButtons();
- if (!settingFindTextFromEvent) {
- JTextComponent findField = UIUtil.getTextComponent(findCombo);
- if (e.getDocument()==findField.getDocument()) {
- context.setSearchFor(findField.getText());
- if (context.getMarkAll()) {
- doMarkAll(true);
- }
- }
- else { // Replace field's document
- JTextComponent replaceField = UIUtil.getTextComponent(
- replaceCombo);
- context.setReplaceWith(replaceField.getText());
- // Don't re-fire "mark all" events for "replace" text edits
- }
- }
- }
-
- @Override
- public void insertUpdate(DocumentEvent e) {
- handleDocumentEvent(e);
- }
-
- public void install(JTextComponent field) {
- field.getDocument().addDocumentListener(this);
- field.addKeyListener(this);
- field.addFocusListener(this);
- }
-
- @Override
- public void keyTyped(KeyEvent e) {
- if (e.getKeyChar()=='\n') {
- int mod = e.getModifiersEx();
- int ctrlShift = InputEvent.CTRL_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK;
- boolean forward = (mod&ctrlShift) == 0;
- doSearch(forward);
- }
- }
-
- @Override
- public void removeUpdate(DocumentEvent e) {
- handleDocumentEvent(e);
- }
-
- }
-
-
- /**
- * Called when the user edits the "Find" field's contents, after a slight
- * delay. Fires a "mark all" search event for applications that want to
- * display "mark all" results on the fly.
- */
- private final class MarkAllEventNotifier implements ActionListener {
-
- @Override
- public void actionPerformed(ActionEvent e) {
- fireMarkAllEvent();
- }
-
- }
-
-
-}
+/*
+ * 09/20/2013
+ *
+ * FindToolBar - A toolbar for "find" operations in text areas.
+ *
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.license.txt file for details.
+ */
+package org.fife.rsta.ui.search;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ResourceBundle;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.InputMap;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.KeyStroke;
+import javax.swing.Timer;
+import javax.swing.UIManager;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
+
+import org.fife.rsta.ui.AssistanceIconPanel;
+import org.fife.rsta.ui.UIUtil;
+import org.fife.ui.rtextarea.SearchContext;
+
+
+/**
+ * A toolbar for search operations in a text editor application. This provides
+ * a more seamless experience than using a Find or Replace dialog.
+ *
+ * @author Robert Futrell
+ * @version 0.5
+ * @see FindDialog
+ */
+public class FindToolBar extends JPanel {
+
+ private SearchContext context;
+ protected ToolBarListener listener;
+ protected FindFieldListener findFieldListener;
+ protected SearchComboBox findCombo;
+ protected SearchComboBox replaceCombo;
+ protected JButton findButton;
+ protected JButton findPrevButton;
+ protected JCheckBox matchCaseCheckBox;
+ protected JCheckBox wholeWordCheckBox;
+ protected JCheckBox regexCheckBox;
+ protected JCheckBox markAllCheckBox;
+ protected JCheckBox wrapCheckBox;
+ private JLabel infoLabel;
+ private Timer markAllTimer;
+
+ /**
+ * Flag to prevent double-modification of SearchContext when e.g. a
+ * FindToolBar and ReplaceToolBar share the same SearchContext.
+ */
+ private boolean settingFindTextFromEvent;
+
+ protected static final ResourceBundle SEARCH_MSG = ResourceBundle.getBundle(
+ "org.fife.rsta.ui.search.Search");
+ protected static final ResourceBundle MSG = ResourceBundle.getBundle(
+ "org.fife.rsta.ui.search.SearchToolBar");
+
+ /**
+ * Creates the toolbar.
+ *
+ * @param listener An entity listening for search events.
+ */
+ public FindToolBar(SearchListener listener) {
+
+ // Keep focus in this component when tabbing through search controls
+ setFocusCycleRoot(true);
+
+ markAllTimer = new Timer(300, new MarkAllEventNotifier());
+ markAllTimer.setRepeats(false);
+
+ setLayout(new BorderLayout());
+ setBorder(BorderFactory.createEmptyBorder(2, 5, 2, 5));
+ addSearchListener(listener);
+ this.listener = new ToolBarListener();
+
+ // The user should set a shared instance between all subclass
+ // instances, but to be safe we set individual ones.
+ setSearchContext(new SearchContext());
+
+ ComponentOrientation orientation = ComponentOrientation.
+ getOrientation(getLocale());
+
+ add(Box.createHorizontalStrut(5));
+
+ add(createFieldPanel());
+
+ Box rest = new Box(BoxLayout.LINE_AXIS);
+ add(rest, BorderLayout.LINE_END);
+
+ rest.add(Box.createHorizontalStrut(5));
+ rest.add(createButtonPanel());
+ rest.add(Box.createHorizontalStrut(15));
+
+ JLabel infoLabel = new JLabel();
+ rest.add(infoLabel);
+
+ rest.add(Box.createHorizontalGlue());
+
+ // Get ready to go.
+ applyComponentOrientation(orientation);
+ }
+
+
+ /**
+ * Adds a {@link SearchListener} to this toolbar. This listener will
+ * be notified when find or replace operations are triggered.
+ *
+ * @param l The listener to add.
+ * @see #removeSearchListener(SearchListener)
+ */
+ public void addSearchListener(SearchListener l) {
+ listenerList.add(SearchListener.class, l);
+ }
+
+
+ protected Container createButtonPanel() {
+
+ Box panel = new Box(BoxLayout.LINE_AXIS);
+ createFindButtons();
+
+ JPanel filler = new JPanel(new BorderLayout());
+ filler.setBorder(BorderFactory.createEmptyBorder());
+ filler.add(findButton);//bp);
+ panel.add(filler);
+ panel.add(Box.createHorizontalStrut(6));
+
+ matchCaseCheckBox = createCB("MatchCase");
+ panel.add(matchCaseCheckBox);
+
+ regexCheckBox = createCB("RegEx");
+ panel.add(regexCheckBox);
+
+ wholeWordCheckBox = createCB("WholeWord");
+ panel.add(wholeWordCheckBox);
+
+ markAllCheckBox = createCB("MarkAll");
+ panel.add(markAllCheckBox);
+
+ wrapCheckBox = createCB("Wrap");
+ panel.add(wrapCheckBox);
+
+ return panel;
+
+ }
+
+
+ protected JCheckBox createCB(String key) {
+ JCheckBox cb = new JCheckBox(SEARCH_MSG.getString(key));
+ cb.addActionListener(listener);
+ cb.addMouseListener(listener);
+ return cb;
+ }
+
+
+ /**
+ * Wraps the specified component in a panel with a leading "content assist
+ * available" icon in front of it.
+ *
+ * @param comp The component with content assist.
+ * @return The wrapper panel.
+ */
+ protected Container createContentAssistablePanel(JComponent comp) {
+ JPanel temp = new JPanel(new BorderLayout());
+ temp.add(comp);
+ AssistanceIconPanel aip = new AssistanceIconPanel(comp);
+ temp.add(aip, BorderLayout.LINE_START);
+ return temp;
+ }
+
+
+ protected Container createFieldPanel() {
+
+ findFieldListener = new FindFieldListener();
+ JPanel temp = new JPanel(new BorderLayout());
+
+ findCombo = new SearchComboBox(this, false);
+ JTextComponent findField = UIUtil.getTextComponent(findCombo);
+ findFieldListener.install(findField);
+ temp.add(createContentAssistablePanel(findCombo));
+
+ return temp;
+ }
+
+
+ /**
+ * Creates the buttons for this toolbar.
+ */
+ protected void createFindButtons() {
+
+ findPrevButton = new JButton(MSG.getString("FindPrev"));
+ makeEnterActivateButton(findPrevButton);
+ findPrevButton.setActionCommand("FindPrevious");
+ findPrevButton.addActionListener(listener);
+ findPrevButton.setEnabled(false);
+
+ findButton = new JButton(SEARCH_MSG.getString("Find")) {
+ @Override
+ public Dimension getPreferredSize() {
+ return findPrevButton.getPreferredSize(); // Always bigger
+ }
+ };
+ makeEnterActivateButton(findButton);
+ findButton.setToolTipText(MSG.getString("Find.ToolTip"));
+ findButton.setActionCommand("FindNext");
+ findButton.addActionListener(listener);
+ findButton.setEnabled(false);
+
+ }
+
+
+ /**
+ * Forces a "mark all" event to be sent out, if "mark all" is enabled.
+ *
+ * @param delay If the delay should be honored.
+ */
+ protected void doMarkAll(boolean delay) {
+ if (context.getMarkAll() && !settingFindTextFromEvent) {
+ if (delay) {
+ markAllTimer.restart();
+ }
+ else {
+ fireMarkAllEvent();
+ }
+ }
+ }
+
+
+ void doSearch(boolean forward) {
+ if (forward) {
+ findButton.doClick(0);
+ }
+ else {
+ findPrevButton.doClick(0);
+ }
+ }
+
+
+ /**
+ * Fires a "mark all" search event.
+ */
+ private void fireMarkAllEvent() {
+ SearchEvent se = new SearchEvent(this, SearchEvent.Type.MARK_ALL,
+ context);
+ fireSearchEvent(se);
+ }
+
+
+ /**
+ * Notifies all listeners that have registered interest in notification of
+ * this event type. The event instance is lazily created using the
+ * event parameter.
+ *
+ * @param e The ActionEvent object coming from a
+ * child component.
+ */
+ protected void fireSearchEvent(SearchEvent e) {
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ SearchListener[] listeners = listenerList.
+ getListeners(SearchListener.class);
+ int count = listeners==null ? 0 : listeners.length;
+ for (int i=count-1; i>=0; i--) {
+ listeners[i].searchEvent(e);
+ }
+ }
+
+
+ protected String getFindText() {
+ return UIUtil.getTextComponent(findCombo).getText();
+ }
+
+
+ /**
+ * Returns the delay between when the user types and when a "mark all"
+ * event is fired (assuming "mark all" is enabled), in milliseconds.
+ *
+ * @return The delay.
+ * @see #setMarkAllDelay(int)
+ */
+ public int getMarkAllDelay() {
+ return markAllTimer.getInitialDelay();
+ }
+
+
+ protected String getReplaceText() {
+ if (replaceCombo==null) {
+ return null;
+ }
+ return UIUtil.getTextComponent(replaceCombo).getText();
+ }
+
+
+ /**
+ * Returns the search context for this toolbar.
+ *
+ * @return The search context.
+ * @see #setSearchContext(SearchContext)
+ */
+ public SearchContext getSearchContext() {
+ return context;
+ }
+
+
+ /**
+ * Called when the regex checkbox is clicked (or its value is modified
+ * via a change to the search context). Subclasses can override
+ * to add custom behavior, but should call the super implementation.
+ */
+ protected void handleRegExCheckBoxClicked() {
+ handleToggleButtons();
+ // "Content assist" support
+ boolean b = regexCheckBox.isSelected();
+ findCombo.setAutoCompleteEnabled(b);
+ }
+
+
+ /**
+ * Creates a search event object and notifies all registered listeners.
+ *
+ * @param e The event.
+ */
+ protected void handleSearchAction(ActionEvent e) {
+
+ SearchEvent.Type type = null;
+ boolean forward = true;
+ String action = e.getActionCommand();
+ // JTextField returns *_DOWN_* modifiers, JButton returns the others (!)
+ int allowedModifiers =
+ InputEvent.CTRL_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK | // field
+ ActionEvent.CTRL_MASK|ActionEvent.SHIFT_MASK; // JButton
+
+ if ("FindNext".equals(action)) {
+ type = SearchEvent.Type.FIND;
+ int mods = e.getModifiers();
+ forward = (mods&allowedModifiers)==0;
+ // Add the item to the combo box's list, if it isn't already there.
+ JTextComponent tc = UIUtil.getTextComponent(findCombo);
+ findCombo.addItem(tc.getText());
+ }
+ else if ("FindPrevious".equals(action)) {
+ type = SearchEvent.Type.FIND;
+ forward = false;
+ // Add the item to the combo box's list, if it isn't already there.
+ JTextComponent tc = UIUtil.getTextComponent(findCombo);
+ findCombo.addItem(tc.getText());
+ }
+ else if ("Replace".equals(action)) {
+ type = SearchEvent.Type.REPLACE;
+ int mods = e.getModifiers();
+ forward = (mods&allowedModifiers)==0;
+ // Add the item to the combo box's list, if it isn't already there.
+ JTextComponent tc = UIUtil.getTextComponent(findCombo);
+ findCombo.addItem(tc.getText());
+ tc = UIUtil.getTextComponent(replaceCombo);
+ replaceCombo.addItem(tc.getText());
+ }
+ else if ("ReplaceAll".equals(action)) {
+ type = SearchEvent.Type.REPLACE_ALL;
+ // Add the item to the combo box's list, if it isn't already there.
+ JTextComponent tc = UIUtil.getTextComponent(findCombo);
+ findCombo.addItem(tc.getText());
+ tc = UIUtil.getTextComponent(replaceCombo);
+ replaceCombo.addItem(tc.getText());
+ }
+
+ context.setSearchFor(getFindText());
+ if (replaceCombo!=null) {
+ context.setReplaceWith(replaceCombo.getSelectedString());
+ }
+
+ // If the ask is to search in the opposite direction from the UI's
+ // current direction, use a cloned search context to avoid updating
+ // the UI when we shouldn't (e.g. from a keyboard shortcut to search
+ // backward).
+ SearchContext contextToFire = context;
+ if (forward != context.getSearchForward()) {
+ contextToFire = context.clone();
+ contextToFire.setSearchForward(forward);
+ }
+
+ SearchEvent se = new SearchEvent(this, type, contextToFire);
+ fireSearchEvent(se);
+ handleToggleButtons(); // Replace button could toggle state
+
+ }
+
+
+ /**
+ * Returns whether any action-related buttons (Find Next, Replace, etc.)
+ * should be enabled. Subclasses can call this method when the "Find What"
+ * or "Replace With" text fields are modified. They can then
+ * enable/disable any components as appropriate.
+ *
+ * @return Whether the buttons should be enabled.
+ */
+ protected FindReplaceButtonsEnableResult handleToggleButtons() {
+
+ FindReplaceButtonsEnableResult result =
+ new FindReplaceButtonsEnableResult(true, null);
+
+ String text = getFindText();
+ if (text.isEmpty()) {
+ result = new FindReplaceButtonsEnableResult(false, null);
+ }
+ else if (regexCheckBox.isSelected()) {
+ try {
+ Pattern.compile(text);
+ } catch (PatternSyntaxException pse) {
+ result = new FindReplaceButtonsEnableResult(false,
+ pse.getMessage());
+ }
+ }
+
+ boolean enable = result.getEnable();
+ findButton.setEnabled(enable);
+ findPrevButton.setEnabled(enable);
+
+ // setBackground doesn't show up with XP Look and Feel!
+ JTextComponent tc = UIUtil.getTextComponent(findCombo);
+ tc.setForeground(enable ? UIManager.getColor("TextField.foreground") :
+ UIUtil.getErrorTextForeground());
+
+ String tooltip = SearchUtil.getToolTip(result);
+ tc.setToolTipText(tooltip); // Always set, even if null
+
+ return result;
+
+ }
+
+
+ /**
+ * Initializes the UI in this toolbar from a search context. This is
+ * called whenever a new search context is installed on this toolbar
+ * (which should practically be never).
+ */
+ private void initUIFromContext() {
+ if (findCombo==null) { // First time through, stuff not initialized yet
+ return;
+ }
+ setFindText(context.getSearchFor());
+ if (replaceCombo!=null) {
+ setReplaceText(context.getReplaceWith());
+ }
+ matchCaseCheckBox.setSelected(context.getMatchCase());
+ wholeWordCheckBox.setSelected(context.getWholeWord());
+ regexCheckBox.setSelected(context.isRegularExpression());
+ markAllCheckBox.setSelected(context.getMarkAll());
+ wrapCheckBox.setSelected(context.getSearchWrap());
+ }
+
+
+ /**
+ * Makes the Enter key activate the button. In Swing, this is a
+ * complicated thing. It's LAF-dependent whether this works
+ * automatically; on most LAFs, it doesn't happen. In WindowsLookAndFeel
+ * it does, but *only* if the current window has a "default" button
+ * specified. Since these toolbars will typically be used in "main"
+ * application windows, which don't have default buttons, we'll just
+ * enable this property here and now.
+ *
+ * @param button The button that should respond to the Enter key.
+ */
+ protected void makeEnterActivateButton(JButton button) {
+
+ InputMap im = button.getInputMap();
+
+ // Make "enter" being typed simulate clicking
+ im.put(KeyStroke.getKeyStroke("ENTER"), "pressed");
+ im.put(KeyStroke.getKeyStroke("released ENTER"), "released");
+
+ // Make "shift+enter" being typed simulate clicking also. The listener
+ // will handle the backwards searching. Not sure why the commented-out
+ // versions don't work, possibly SHIFT_MASK vs. SHIFT_DOWN_MASK issue.
+ //im.put(KeyStroke.getKeyStroke("pressed SHIFT ENTER"), "pressed");
+ //im.put(KeyStroke.getKeyStroke("released SHIFT ENTER"), "released");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK,
+ false), "pressed");
+ im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK,
+ true), "released");
+
+ }
+
+
+ /**
+ * Removes a {@link SearchListener} from this toolbar.
+ *
+ * @param l The listener to remove
+ * @see #addSearchListener(SearchListener)
+ */
+ public void removeSearchListener(SearchListener l) {
+ listenerList.remove(SearchListener.class, l);
+ }
+
+
+ /**
+ * Makes the find field on this toolbar request focus. If it is already
+ * focused, its text is selected.
+ */
+ @Override
+ public boolean requestFocusInWindow() {
+ JTextComponent findField = UIUtil.getTextComponent(findCombo);
+ findField.selectAll();
+ return findField.requestFocusInWindow();
+ }
+
+
+ /**
+ * Callback called when a contained combo box has its LookAndFeel
+ * modified. This is a hack for us to add listeners back to it.
+ *
+ * @param combo The combo box.
+ */
+ void searchComboUpdateUICallback(SearchComboBox combo) {
+ findFieldListener.install(UIUtil.getTextComponent(combo));
+ }
+
+
+ /**
+ * Sets the image to display by this dialog's text fields when content
+ * assistance is available.
+ *
+ * @param image The image. If this is {@code null}, a default image
+ * (a light bulb) is used. This should be kept small, around
+ * 8x8 for standard resolution monitors.
+ */
+ public void setContentAssistImage(Image image) {
+ findCombo.setContentAssistImage(image);
+ }
+
+
+ protected void setFindText(String text) {
+ UIUtil.getTextComponent(findCombo).setText(text);
+ //findCombo.setSelectedItem(text);
+ }
+
+
+ /**
+ * Sets the delay between when the user types and when a "mark all"
+ * event is fired (assuming "mark all" is enabled), in milliseconds.
+ *
+ * @param millis The new delay. This should be >= zero.
+ * @see #getMarkAllDelay()
+ */
+ public void setMarkAllDelay(int millis) {
+ markAllTimer.setInitialDelay(millis);
+ }
+
+
+ protected void setReplaceText(String text) {
+ if (replaceCombo!=null) {
+ UIUtil.getTextComponent(replaceCombo).setText(text);
+ //replaceCombo.setSelectedItem(text);
+ }
+ }
+
+
+ /**
+ * Sets the search context for this toolbar. You'll usually want to call
+ * this method for all toolbars and give them the same search context,
+ * so that their options (match case, etc.) stay in sync with one another.
+ *
+ * @param context The new search context. This cannot be null.
+ * @see #getSearchContext()
+ */
+ public void setSearchContext(SearchContext context) {
+ if (this.context!=null) {
+ this.context.removePropertyChangeListener(listener);
+ }
+ this.context = context;
+ this.context.addPropertyChangeListener(listener);
+ initUIFromContext();
+ }
+
+
+ /**
+ * Listens for events in this toolbar. Keeps the UI in sync with the
+ * search context and vice versa.
+ */
+ private final class ToolBarListener extends MouseAdapter
+ implements ActionListener, PropertyChangeListener {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+
+ Object source = e.getSource();
+
+ if (source==matchCaseCheckBox) {
+ context.setMatchCase(matchCaseCheckBox.isSelected());
+ if (markAllCheckBox.isSelected()) {
+ doMarkAll(false);
+ }
+ }
+ else if (source==wholeWordCheckBox) {
+ context.setWholeWord(wholeWordCheckBox.isSelected());
+ if (markAllCheckBox.isSelected()) {
+ doMarkAll(false);
+ }
+ }
+ else if (source==regexCheckBox) {
+ context.setRegularExpression(regexCheckBox.isSelected());
+ if (markAllCheckBox.isSelected()) {
+ doMarkAll(false);
+ }
+ }
+ else if (source==markAllCheckBox) {
+ context.setMarkAll(markAllCheckBox.isSelected());
+ fireMarkAllEvent(); // Force an event to be fired
+ }
+ else if (source == wrapCheckBox) {
+ context.setSearchWrap(wrapCheckBox.isSelected());
+ }
+ else {
+ handleSearchAction(e);
+ }
+
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getSource() instanceof JCheckBox) { // Always true
+ findFieldListener.selectAll = false;
+ findCombo.requestFocusInWindow();
+ }
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent e) {
+
+ // A property changed on the context itself.
+ String prop = e.getPropertyName();
+
+ if (SearchContext.PROPERTY_MATCH_CASE.equals(prop)) {
+ boolean newValue = (Boolean) e.getNewValue();
+ matchCaseCheckBox.setSelected(newValue);
+ }
+ else if (SearchContext.PROPERTY_MATCH_WHOLE_WORD.equals(prop)) {
+ boolean newValue = (Boolean) e.getNewValue();
+ wholeWordCheckBox.setSelected(newValue);
+ }
+ //else if (SearchContext.PROPERTY_SEARCH_FORWARD.equals(prop)) {
+ // boolean newValue = ((Boolean)e.getNewValue()).booleanValue();
+ // ...
+ //}
+ //else if (SearchContext.PROPERTY_SELECTION_ONLY.equals(prop)) {
+ // boolean newValue = ((Boolean)e.getNewValue()).booleanValue();
+ // ...
+ //}
+ else if (SearchContext.PROPERTY_USE_REGEX.equals(prop)) {
+ boolean newValue = (Boolean) e.getNewValue();
+ regexCheckBox.setSelected(newValue);
+ handleRegExCheckBoxClicked();
+ }
+ else if (SearchContext.PROPERTY_MARK_ALL.equals(prop)) {
+ boolean newValue = (Boolean) e.getNewValue();
+ markAllCheckBox.setSelected(newValue);
+ // firing event handled in ActionListener, to prevent "other"
+ // toolbar from firing a second event
+ }
+ else if (SearchContext.PROPERTY_SEARCH_FOR.equals(prop)) {
+ String newValue = (String)e.getNewValue();
+ String oldValue = getFindText();
+ // Prevents IllegalStateExceptions
+ if (!newValue.equals(oldValue)) {
+ settingFindTextFromEvent = true;
+ setFindText(newValue);
+ settingFindTextFromEvent = false;
+ }
+ }
+ else if (SearchContext.PROPERTY_REPLACE_WITH.equals(prop)) {
+ String newValue = (String)e.getNewValue();
+ String oldValue = getReplaceText();
+ // Prevents IllegalStateExceptions
+ if (!newValue.equals(oldValue)) {
+ settingFindTextFromEvent = true;
+ setReplaceText(newValue);
+ settingFindTextFromEvent = false;
+ }
+ }
+ else if (SearchContext.PROPERTY_SEARCH_WRAP.equals(prop)) {
+ boolean newValue = (Boolean)e.getNewValue();
+ wrapCheckBox.setSelected(newValue);
+ }
+
+ }
+
+ }
+
+
+ /**
+ * Listens for events in the Find (and Replace, in the subclass) search
+ * field.
+ */
+ protected class FindFieldListener extends KeyAdapter
+ implements DocumentListener, FocusListener {
+
+ protected boolean selectAll;
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ }
+
+ @Override
+ public void focusGained(FocusEvent e) {
+ JTextField field = (JTextField)e.getComponent();
+ if (selectAll) {
+ field.selectAll();
+ }
+ selectAll = true;
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ }
+
+ protected void handleDocumentEvent(DocumentEvent e) {
+ handleToggleButtons();
+ if (!settingFindTextFromEvent) {
+ JTextComponent findField = UIUtil.getTextComponent(findCombo);
+ if (e.getDocument()==findField.getDocument()) {
+ context.setSearchFor(findField.getText());
+ if (context.getMarkAll()) {
+ doMarkAll(true);
+ }
+ }
+ else { // Replace field's document
+ JTextComponent replaceField = UIUtil.getTextComponent(
+ replaceCombo);
+ context.setReplaceWith(replaceField.getText());
+ // Don't re-fire "mark all" events for "replace" text edits
+ }
+ }
+ }
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ handleDocumentEvent(e);
+ }
+
+ public void install(JTextComponent field) {
+ field.getDocument().addDocumentListener(this);
+ field.addKeyListener(this);
+ field.addFocusListener(this);
+ }
+
+ @Override
+ public void keyTyped(KeyEvent e) {
+ if (e.getKeyChar()=='\n') {
+ int mod = e.getModifiersEx();
+ int ctrlShift = InputEvent.CTRL_DOWN_MASK|InputEvent.SHIFT_DOWN_MASK;
+ boolean forward = (mod&ctrlShift) == 0;
+ doSearch(forward);
+ }
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ handleDocumentEvent(e);
+ }
+
+ }
+
+
+ /**
+ * Called when the user edits the "Find" field's contents, after a slight
+ * delay. Fires a "mark all" search event for applications that want to
+ * display "mark all" results on the fly.
+ */
+ private final class MarkAllEventNotifier implements ActionListener {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ fireMarkAllEvent();
+ }
+
+ }
+
+
+}
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/search/ReplaceToolBar.java b/RSTAUI/src/main/java/org/fife/rsta/ui/search/ReplaceToolBar.java
index 8daaf06..100c5e9 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/search/ReplaceToolBar.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/search/ReplaceToolBar.java
@@ -1,295 +1,295 @@
-/*
- * 09/20/2013
- *
- * ReplaceToolBar - A toolbar for "replace" operations in text areas.
- *
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.license.txt file for details.
- */
-package org.fife.rsta.ui.search;
-
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-import javax.swing.Box;
-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.text.JTextComponent;
-
-import org.fife.rsta.ui.UIUtil;
-import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
-
-
-/**
- * A toolbar for replace operations in a text editor application. This provides
- * a more seamless experience than using a Find or Replace dialog.
- *
- * @author Robert Futrell
- * @version 0.5
- * @see FindToolBar
- * @see ReplaceDialog
- */
-public class ReplaceToolBar extends FindToolBar {
-
- private JButton replaceButton;
- private JButton replaceAllButton;
-
- /**
- * Our search listener, cached, so we can grab its selected text easily.
- */
- protected SearchListener searchListener;
-
-
- /**
- * Creates the toolbar.
- *
- * @param listener An entity listening for search events.
- */
- public ReplaceToolBar(SearchListener listener) {
- super(listener);
- this.searchListener = listener;
- }
-
-
- @Override
- public void addNotify() {
- super.addNotify();
- handleToggleButtons();
- }
-
-
- @Override
- protected Container createButtonPanel() {
-
- Box panel = new Box(BoxLayout.LINE_AXIS);
-
- JPanel bp = new JPanel(new GridLayout(2,2, 5,5));
- panel.add(bp);
-
- createFindButtons();
-
- Component filler = Box.createRigidArea(new Dimension(5, 5));
-
- bp.add(findButton); bp.add(replaceButton);
- bp.add(replaceAllButton); bp.add(filler);
- panel.add(bp);
-
- JPanel optionPanel = new JPanel(new SpringLayout());
- matchCaseCheckBox = createCB("MatchCase");
- regexCheckBox = createCB("RegEx");
- wholeWordCheckBox = createCB("WholeWord");
- markAllCheckBox = createCB("MarkAll");
- wrapCheckBox = createCB("Wrap");
- // We use a "spacing" middle row, instead of spacing in the call to
- // UIUtil.makeSpringCompactGrid(), as the latter adds trailing
- // spacing after the final "row", which screws up our alignment.
- Dimension spacing = new Dimension(1, 5);
- Component space1 = Box.createRigidArea(spacing);
- Component space2 = Box.createRigidArea(spacing);
- Component space3 = Box.createRigidArea(spacing);
- Component space4 = Box.createRigidArea(spacing);
-
- ComponentOrientation orientation = ComponentOrientation.
- getOrientation(getLocale());
-
- if (orientation.isLeftToRight()) {
- optionPanel.add(matchCaseCheckBox); optionPanel.add(wholeWordCheckBox); optionPanel.add(wrapCheckBox);
- optionPanel.add(space1); optionPanel.add(space2); optionPanel.add(space3);
- optionPanel.add(regexCheckBox); optionPanel.add(markAllCheckBox); optionPanel.add(space4);
- }
- else {
- optionPanel.add(wrapCheckBox); optionPanel.add(wholeWordCheckBox); optionPanel.add(matchCaseCheckBox);
- optionPanel.add(space3); optionPanel.add(space2); optionPanel.add(space1);
- optionPanel.add(space4); optionPanel.add(markAllCheckBox); optionPanel.add(regexCheckBox);
- }
- UIUtil.makeSpringCompactGrid(optionPanel, 3,3, 0,0, 0,0);
- panel.add(optionPanel);
-
- return panel;
-
- }
-
-
- @Override
- protected Container createFieldPanel() {
-
- findFieldListener = new ReplaceFindFieldListener();
-
- JPanel temp = new JPanel(new SpringLayout());
-
- JLabel findLabel = new JLabel(MSG.getString("FindWhat"));
- JLabel replaceLabel = new JLabel(MSG.getString("ReplaceWith"));
-
- findCombo = new SearchComboBox(this, false);
- JTextComponent findField = UIUtil.getTextComponent(findCombo);
- findFieldListener.install(findField);
- Container fcp = createContentAssistablePanel(findCombo);
-
- replaceCombo = new SearchComboBox(this, true);
- JTextComponent replaceField = UIUtil.getTextComponent(replaceCombo);
- findFieldListener.install(replaceField);
- Container rcp = createContentAssistablePanel(replaceCombo);
-
- // We use a "spacing" middle row, instead of spacing in the call to
- // UIUtil.makeSpringCompactGrid(), as the latter adds trailing
- // spacing after the final "row", which screws up our alignment.
- Dimension spacing = new Dimension(1, 5);
- Component space1 = Box.createRigidArea(spacing);
- Component space2 = Box.createRigidArea(spacing);
-
- if (getComponentOrientation().isLeftToRight()) {
- temp.add(findLabel); temp.add(fcp);
- temp.add(space1); temp.add(space2);
- temp.add(replaceLabel); temp.add(rcp);
- }
- else {
- temp.add(fcp); temp.add(findLabel);
- temp.add(space2); temp.add(space1);
- temp.add(rcp); temp.add(replaceLabel);
- }
- UIUtil.makeSpringCompactGrid(temp, 3,2, 0,0, 0,0);
-
- return temp;
- }
-
-
- @Override
- protected void createFindButtons() {
-
- super.createFindButtons();
-
- replaceButton = new JButton(SEARCH_MSG.getString("Replace"));
- makeEnterActivateButton(replaceButton);
- replaceButton.setToolTipText(MSG.getString("Replace.ToolTip"));
- replaceButton.setActionCommand("Replace");
- replaceButton.addActionListener(listener);
- replaceButton.setEnabled(false);
-
- replaceAllButton = new JButton(SEARCH_MSG.getString("ReplaceAll"));
- makeEnterActivateButton(replaceAllButton);
- replaceAllButton.setActionCommand("ReplaceAll");
- replaceAllButton.addActionListener(listener);
- replaceAllButton.setEnabled(false);
-
- }
-
-
- /**
- * Called when the regex checkbox is clicked (or its value is modified
- * via a change to the search context). Subclasses can override
- * to add custom behavior, but should call the super implementation.
- */
- @Override
- protected void handleRegExCheckBoxClicked() {
- super.handleRegExCheckBoxClicked();
- // "Content assist" support
- boolean b = regexCheckBox.isSelected();
- replaceCombo.setAutoCompleteEnabled(b);
- }
-
-
- @Override
- protected void handleSearchAction(ActionEvent e) {
- String command = e.getActionCommand();
- super.handleSearchAction(e);
- if ("FindNext".equals(command) || "FindPrevious".equals(command)) {
- handleToggleButtons(); // Replace button could toggle state
- }
- }
-
-
- @Override
- protected FindReplaceButtonsEnableResult handleToggleButtons() {
-
- FindReplaceButtonsEnableResult er = super.handleToggleButtons();
- boolean shouldReplace = er.getEnable();
- replaceAllButton.setEnabled(shouldReplace);
-
- // "Replace" is only enabled if text to search for is selected in
- // the UI.
- if (shouldReplace) {
- String text = searchListener.getSelectedText();
- shouldReplace = matchesSearchFor(text);
- }
- replaceButton.setEnabled(shouldReplace);
-
- return er;
- }
-
-
- // TODO: Share this code with AbstractSearchDialog
- protected boolean matchesSearchFor(String text) {
- if (text==null || text.isEmpty()) {
- return false;
- }
- String searchFor = findCombo.getSelectedString();
- if (searchFor!=null && !searchFor.isEmpty()) {
- boolean matchCase = matchCaseCheckBox.isSelected();
- if (regexCheckBox.isSelected()) {
- int flags = Pattern.MULTILINE; // '^' and '$' are done per line.
- flags = RSyntaxUtilities.getPatternFlags(matchCase, flags);
- Pattern pattern;
- try {
- pattern = Pattern.compile(searchFor, flags);
- } catch (PatternSyntaxException pse) {
- pse.printStackTrace(); // Never happens
- return false;
- }
- return pattern.matcher(text).matches();
- }
- else {
- if (matchCase) {
- return searchFor.equals(text);
- }
- return searchFor.equalsIgnoreCase(text);
- }
- }
- return false;
- }
-
-
- /**
- * Overridden to possibly toggle the enabled state of the replace button.
- */
- @Override
- public boolean requestFocusInWindow() {
- boolean result = super.requestFocusInWindow();
- handleToggleButtons(); // Replace button state may change
- return result;
- }
-
- @Override
- public void setContentAssistImage(Image image) {
- super.setContentAssistImage(image);
- replaceCombo.setContentAssistImage(image);
- }
-
-
- /**
- * Listens for the user typing into the search field.
- */
- protected class ReplaceFindFieldListener extends FindFieldListener {
-
- @Override
- protected void handleDocumentEvent(DocumentEvent e) {
- super.handleDocumentEvent(e);
- JTextComponent findField = UIUtil.getTextComponent(findCombo);
- JTextComponent replaceField = UIUtil.getTextComponent(replaceCombo);
- if (e.getDocument().equals(findField.getDocument())) {
- handleToggleButtons();
- }
- if (e.getDocument()==replaceField.getDocument()) {
- getSearchContext().setReplaceWith(replaceField.getText());
- }
- }
-
- }
-
-
-}
+/*
+ * 09/20/2013
+ *
+ * ReplaceToolBar - A toolbar for "replace" operations in text areas.
+ *
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.license.txt file for details.
+ */
+package org.fife.rsta.ui.search;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+import javax.swing.Box;
+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.text.JTextComponent;
+
+import org.fife.rsta.ui.UIUtil;
+import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities;
+
+
+/**
+ * A toolbar for replace operations in a text editor application. This provides
+ * a more seamless experience than using a Find or Replace dialog.
+ *
+ * @author Robert Futrell
+ * @version 0.5
+ * @see FindToolBar
+ * @see ReplaceDialog
+ */
+public class ReplaceToolBar extends FindToolBar {
+
+ private JButton replaceButton;
+ private JButton replaceAllButton;
+
+ /**
+ * Our search listener, cached, so we can grab its selected text easily.
+ */
+ protected SearchListener searchListener;
+
+
+ /**
+ * Creates the toolbar.
+ *
+ * @param listener An entity listening for search events.
+ */
+ public ReplaceToolBar(SearchListener listener) {
+ super(listener);
+ this.searchListener = listener;
+ }
+
+
+ @Override
+ public void addNotify() {
+ super.addNotify();
+ handleToggleButtons();
+ }
+
+
+ @Override
+ protected Container createButtonPanel() {
+
+ Box panel = new Box(BoxLayout.LINE_AXIS);
+
+ JPanel bp = new JPanel(new GridLayout(2,2, 5,5));
+ panel.add(bp);
+
+ createFindButtons();
+
+ Component filler = Box.createRigidArea(new Dimension(5, 5));
+
+ bp.add(findButton); bp.add(replaceButton);
+ bp.add(replaceAllButton); bp.add(filler);
+ panel.add(bp);
+
+ JPanel optionPanel = new JPanel(new SpringLayout());
+ matchCaseCheckBox = createCB("MatchCase");
+ regexCheckBox = createCB("RegEx");
+ wholeWordCheckBox = createCB("WholeWord");
+ markAllCheckBox = createCB("MarkAll");
+ wrapCheckBox = createCB("Wrap");
+ // We use a "spacing" middle row, instead of spacing in the call to
+ // UIUtil.makeSpringCompactGrid(), as the latter adds trailing
+ // spacing after the final "row", which screws up our alignment.
+ Dimension spacing = new Dimension(1, 5);
+ Component space1 = Box.createRigidArea(spacing);
+ Component space2 = Box.createRigidArea(spacing);
+ Component space3 = Box.createRigidArea(spacing);
+ Component space4 = Box.createRigidArea(spacing);
+
+ ComponentOrientation orientation = ComponentOrientation.
+ getOrientation(getLocale());
+
+ if (orientation.isLeftToRight()) {
+ optionPanel.add(matchCaseCheckBox); optionPanel.add(wholeWordCheckBox); optionPanel.add(wrapCheckBox);
+ optionPanel.add(space1); optionPanel.add(space2); optionPanel.add(space3);
+ optionPanel.add(regexCheckBox); optionPanel.add(markAllCheckBox); optionPanel.add(space4);
+ }
+ else {
+ optionPanel.add(wrapCheckBox); optionPanel.add(wholeWordCheckBox); optionPanel.add(matchCaseCheckBox);
+ optionPanel.add(space3); optionPanel.add(space2); optionPanel.add(space1);
+ optionPanel.add(space4); optionPanel.add(markAllCheckBox); optionPanel.add(regexCheckBox);
+ }
+ UIUtil.makeSpringCompactGrid(optionPanel, 3,3, 0,0, 0,0);
+ panel.add(optionPanel);
+
+ return panel;
+
+ }
+
+
+ @Override
+ protected Container createFieldPanel() {
+
+ findFieldListener = new ReplaceFindFieldListener();
+
+ JPanel temp = new JPanel(new SpringLayout());
+
+ JLabel findLabel = new JLabel(MSG.getString("FindWhat"));
+ JLabel replaceLabel = new JLabel(MSG.getString("ReplaceWith"));
+
+ findCombo = new SearchComboBox(this, false);
+ JTextComponent findField = UIUtil.getTextComponent(findCombo);
+ findFieldListener.install(findField);
+ Container fcp = createContentAssistablePanel(findCombo);
+
+ replaceCombo = new SearchComboBox(this, true);
+ JTextComponent replaceField = UIUtil.getTextComponent(replaceCombo);
+ findFieldListener.install(replaceField);
+ Container rcp = createContentAssistablePanel(replaceCombo);
+
+ // We use a "spacing" middle row, instead of spacing in the call to
+ // UIUtil.makeSpringCompactGrid(), as the latter adds trailing
+ // spacing after the final "row", which screws up our alignment.
+ Dimension spacing = new Dimension(1, 5);
+ Component space1 = Box.createRigidArea(spacing);
+ Component space2 = Box.createRigidArea(spacing);
+
+ if (getComponentOrientation().isLeftToRight()) {
+ temp.add(findLabel); temp.add(fcp);
+ temp.add(space1); temp.add(space2);
+ temp.add(replaceLabel); temp.add(rcp);
+ }
+ else {
+ temp.add(fcp); temp.add(findLabel);
+ temp.add(space2); temp.add(space1);
+ temp.add(rcp); temp.add(replaceLabel);
+ }
+ UIUtil.makeSpringCompactGrid(temp, 3,2, 0,0, 0,0);
+
+ return temp;
+ }
+
+
+ @Override
+ protected void createFindButtons() {
+
+ super.createFindButtons();
+
+ replaceButton = new JButton(SEARCH_MSG.getString("Replace"));
+ makeEnterActivateButton(replaceButton);
+ replaceButton.setToolTipText(MSG.getString("Replace.ToolTip"));
+ replaceButton.setActionCommand("Replace");
+ replaceButton.addActionListener(listener);
+ replaceButton.setEnabled(false);
+
+ replaceAllButton = new JButton(SEARCH_MSG.getString("ReplaceAll"));
+ makeEnterActivateButton(replaceAllButton);
+ replaceAllButton.setActionCommand("ReplaceAll");
+ replaceAllButton.addActionListener(listener);
+ replaceAllButton.setEnabled(false);
+
+ }
+
+
+ /**
+ * Called when the regex checkbox is clicked (or its value is modified
+ * via a change to the search context). Subclasses can override
+ * to add custom behavior, but should call the super implementation.
+ */
+ @Override
+ protected void handleRegExCheckBoxClicked() {
+ super.handleRegExCheckBoxClicked();
+ // "Content assist" support
+ boolean b = regexCheckBox.isSelected();
+ replaceCombo.setAutoCompleteEnabled(b);
+ }
+
+
+ @Override
+ protected void handleSearchAction(ActionEvent e) {
+ String command = e.getActionCommand();
+ super.handleSearchAction(e);
+ if ("FindNext".equals(command) || "FindPrevious".equals(command)) {
+ handleToggleButtons(); // Replace button could toggle state
+ }
+ }
+
+
+ @Override
+ protected FindReplaceButtonsEnableResult handleToggleButtons() {
+
+ FindReplaceButtonsEnableResult er = super.handleToggleButtons();
+ boolean shouldReplace = er.getEnable();
+ replaceAllButton.setEnabled(shouldReplace);
+
+ // "Replace" is only enabled if text to search for is selected in
+ // the UI.
+ if (shouldReplace) {
+ String text = searchListener.getSelectedText();
+ shouldReplace = matchesSearchFor(text);
+ }
+ replaceButton.setEnabled(shouldReplace);
+
+ return er;
+ }
+
+
+ // TODO: Share this code with AbstractSearchDialog
+ protected boolean matchesSearchFor(String text) {
+ if (text==null || text.isEmpty()) {
+ return false;
+ }
+ String searchFor = findCombo.getSelectedString();
+ if (searchFor!=null && !searchFor.isEmpty()) {
+ boolean matchCase = matchCaseCheckBox.isSelected();
+ if (regexCheckBox.isSelected()) {
+ int flags = Pattern.MULTILINE; // '^' and '$' are done per line.
+ flags = RSyntaxUtilities.getPatternFlags(matchCase, flags);
+ Pattern pattern;
+ try {
+ pattern = Pattern.compile(searchFor, flags);
+ } catch (PatternSyntaxException pse) {
+ pse.printStackTrace(); // Never happens
+ return false;
+ }
+ return pattern.matcher(text).matches();
+ }
+ else {
+ if (matchCase) {
+ return searchFor.equals(text);
+ }
+ return searchFor.equalsIgnoreCase(text);
+ }
+ }
+ return false;
+ }
+
+
+ /**
+ * Overridden to possibly toggle the enabled state of the replace button.
+ */
+ @Override
+ public boolean requestFocusInWindow() {
+ boolean result = super.requestFocusInWindow();
+ handleToggleButtons(); // Replace button state may change
+ return result;
+ }
+
+ @Override
+ public void setContentAssistImage(Image image) {
+ super.setContentAssistImage(image);
+ replaceCombo.setContentAssistImage(image);
+ }
+
+
+ /**
+ * Listens for the user typing into the search field.
+ */
+ protected class ReplaceFindFieldListener extends FindFieldListener {
+
+ @Override
+ protected void handleDocumentEvent(DocumentEvent e) {
+ super.handleDocumentEvent(e);
+ JTextComponent findField = UIUtil.getTextComponent(findCombo);
+ JTextComponent replaceField = UIUtil.getTextComponent(replaceCombo);
+ if (e.getDocument().equals(findField.getDocument())) {
+ handleToggleButtons();
+ }
+ if (e.getDocument()==replaceField.getDocument()) {
+ getSearchContext().setReplaceWith(replaceField.getText());
+ }
+ }
+
+ }
+
+
+}
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchEvent.java b/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchEvent.java
index bb10995..f182919 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchEvent.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchEvent.java
@@ -1,73 +1,73 @@
-/*
- * 09/20/2013
- *
- * SearchEvent - The event fired for find/replace/mark all operations.
- *
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.license.txt file for details.
- */
-package org.fife.rsta.ui.search;
-
-import java.util.EventObject;
-
-import org.fife.ui.rtextarea.SearchContext;
-
-
-/**
- * The event fired whenever a user wants to search for or replace text in a
- * Find or Replace dialog/toolbar.
- *
- * @author Robert Futrell
- * @version 1.0
- */
-public class SearchEvent extends EventObject {
-
- private SearchContext context;
- private Type type;
-
- public SearchEvent(Object source, Type type, SearchContext context) {
- super(source);
- this.type = type;
- this.context = context;
- }
-
-
- public Type getType() {
- return type;
- }
-
-
- public SearchContext getSearchContext() {
- return context;
- }
-
-
- /**
- * Types of search events.
- */
- public enum Type {
-
- /**
- * The event fired when the text to "mark all" has changed.
- */
- MARK_ALL,
-
- /**
- * The event fired when the user wants to find text in the editor.
- */
- FIND,
-
- /**
- * The event fired when the user wants to replace text in the editor.
- */
- REPLACE,
-
- /**
- * The event fired when the user wants to replace all instances of
- * specific text with new text in the editor.
- */
- REPLACE_ALL
-
- }
-
-}
+/*
+ * 09/20/2013
+ *
+ * SearchEvent - The event fired for find/replace/mark all operations.
+ *
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.license.txt file for details.
+ */
+package org.fife.rsta.ui.search;
+
+import java.util.EventObject;
+
+import org.fife.ui.rtextarea.SearchContext;
+
+
+/**
+ * The event fired whenever a user wants to search for or replace text in a
+ * Find or Replace dialog/toolbar.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+public class SearchEvent extends EventObject {
+
+ private SearchContext context;
+ private Type type;
+
+ public SearchEvent(Object source, Type type, SearchContext context) {
+ super(source);
+ this.type = type;
+ this.context = context;
+ }
+
+
+ public Type getType() {
+ return type;
+ }
+
+
+ public SearchContext getSearchContext() {
+ return context;
+ }
+
+
+ /**
+ * Types of search events.
+ */
+ public enum Type {
+
+ /**
+ * The event fired when the text to "mark all" has changed.
+ */
+ MARK_ALL,
+
+ /**
+ * The event fired when the user wants to find text in the editor.
+ */
+ FIND,
+
+ /**
+ * The event fired when the user wants to replace text in the editor.
+ */
+ REPLACE,
+
+ /**
+ * The event fired when the user wants to replace all instances of
+ * specific text with new text in the editor.
+ */
+ REPLACE_ALL
+
+ }
+
+}
diff --git a/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchUtil.java b/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchUtil.java
index e3aca81..086e41a 100644
--- a/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchUtil.java
+++ b/RSTAUI/src/main/java/org/fife/rsta/ui/search/SearchUtil.java
@@ -1,46 +1,46 @@
-/*
- * 09/20/2013
- *
- * SearchUtil - Utility methods for this package.
- *
- * This library is distributed under a modified BSD license. See the included
- * RSTAUI.license.txt file for details.
- */
-package org.fife.rsta.ui.search;
-
-
-/**
- * Utility methods for this package.
- *
- * @author Robert Futrell
- * @version 1.0
- */
-final class SearchUtil {
-
-
- /**
- * Private constructor to prevent instantiation.
- */
- private SearchUtil() {
- }
-
- /**
- * Formats an error message from a find/replace button enable result for
- * use in a tool tip. This assumes the error (if any) came from a
- * PatternSyntaxException.
- *
- * @param res The result.
- * @return The tool tip, or null if no error message was
- * specified in res.
- */
- public static String getToolTip(FindReplaceButtonsEnableResult res) {
- String tooltip = res.getError();
- if (tooltip!=null && tooltip.indexOf('\n')>-1) {
- tooltip = tooltip.replaceFirst("\\\n", "
");
- tooltip = "" + tooltip;
- }
- return tooltip;
- }
-
-
-}
+/*
+ * 09/20/2013
+ *
+ * SearchUtil - Utility methods for this package.
+ *
+ * This library is distributed under a modified BSD license. See the included
+ * RSTAUI.license.txt file for details.
+ */
+package org.fife.rsta.ui.search;
+
+
+/**
+ * Utility methods for this package.
+ *
+ * @author Robert Futrell
+ * @version 1.0
+ */
+final class SearchUtil {
+
+
+ /**
+ * Private constructor to prevent instantiation.
+ */
+ private SearchUtil() {
+ }
+
+ /**
+ * Formats an error message from a find/replace button enable result for
+ * use in a tool tip. This assumes the error (if any) came from a
+ * PatternSyntaxException.
+ *
+ * @param res The result.
+ * @return The tool tip, or null if no error message was
+ * specified in res.
+ */
+ public static String getToolTip(FindReplaceButtonsEnableResult res) {
+ String tooltip = res.getError();
+ if (tooltip!=null && tooltip.indexOf('\n')>-1) {
+ tooltip = tooltip.replaceFirst("\\\n", "
");
+ tooltip = "" + tooltip;
+ }
+ return tooltip;
+ }
+
+
+}
diff --git a/build.gradle b/build.gradle
index 8caf6ec..4ae881f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,5 +1,5 @@
plugins {
- id 'com.github.spotbugs' version '6.4.8'
+ id 'com.github.spotbugs' version '6.5.9'
id 'io.github.gradle-nexus.publish-plugin' version '2.0.0'
}
@@ -48,7 +48,7 @@ subprojects {
}
checkstyle {
- toolVersion = '12.3.0'
+ toolVersion = '13.8.0'
}
spotbugs {
diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml
index c6dffd9..dff9fda 100644
--- a/config/checkstyle/checkstyle.xml
+++ b/config/checkstyle/checkstyle.xml
@@ -67,6 +67,7 @@
+
@@ -233,12 +234,16 @@
-->
+
+
+
+
@@ -249,6 +254,8 @@
+
+
@@ -268,6 +275,7 @@
+