Package org.webharvest.gui

Source Code of org.webharvest.gui.FindReplaceDialog

/*  Copyright (c) 2006-2007, Vladimir Nikic
    All rights reserved.

    Redistribution and use of this software in source and binary forms,
    with or without modification, are permitted provided that the following
    conditions are met:

    * Redistributions of source code must retain the above
      copyright notice, this list of conditions and the
      following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the
      following disclaimer in the documentation and/or other
      materials provided with the distribution.

    * The name of Web-Harvest may not be used to endorse or promote
      products derived from this software without specific prior
      written permission.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

    You can contact Vladimir Nikic by sending e-mail to
    nikic_vladimir@yahoo.com. Please include the word "Web-Harvest" in the
    subject line.
*/
package org.webharvest.gui;

import org.webharvest.gui.component.CommonDialog;
import org.webharvest.gui.component.WHComboBox;
import org.webharvest.gui.component.WHCheckBox;
import org.webharvest.gui.component.WHRadioButton;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import javax.swing.text.Document;
import javax.swing.text.BadLocationException;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class FindReplaceDialog extends CommonDialog {

    private static final int OPERATION_FIND = 1;
    private static final int OPERATION_REPLACE = 2;

    private int operation = OPERATION_FIND;

    // Ide instance where this dialog belongs.
    private Frame parentFrame;

    // settiongs fields
    private JComboBox searchComboBox;
    private JLabel replaceLabel;
    private JComboBox replaceComboBox;
    private JTextComponent textComponent;

    private JCheckBox caseSensitiveCheckBox;
    private JCheckBox regularExpressionsCheckBox;
    private JRadioButton forwardRadioButton;
    private JRadioButton backwordRadioButton;
    private JRadioButton entireScopeRadioButton;

    public FindReplaceDialog(Frame parentFrame) throws HeadlessException {
        super("Find Text");
        this.parentFrame = parentFrame;

        addWindowListener( new WindowAdapter() {
           public void windowActivated( WindowEvent e ){
                searchComboBox.requestFocus();
                searchComboBox.getEditor().selectAll();
             }
        } );

        createGui();
    }

    private void createGui() {
        Container contentPane = this.getContentPane();

        JPanel topPanel = new JPanel(new GridBagLayout());

        contentPane.setLayout( new BorderLayout() );

        GridBagConstraints constraints = new GridBagConstraints();
        constraints.fill = GridBagConstraints.HORIZONTAL;
        constraints.insets = new Insets(2, 5, 2, 5);

        searchComboBox = new WHComboBox(new Object[] {}) {
            public Dimension getPreferredSize() {
                return new Dimension(300, 20);
            }
        };
        searchComboBox.setEditable(true);
        searchComboBox.getEditor().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                searchComboBox.setSelectedItem(e.getActionCommand());
            }
        });
       
        replaceLabel = new JLabel("Replace with: ");
        replaceComboBox = new WHComboBox(new Object[] {}) {
            public Dimension getPreferredSize() {
                return new Dimension(300, 20);
            }
        };
        replaceComboBox.setEditable(true);
        replaceComboBox.getEditor().addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                replaceComboBox.setSelectedItem(e.getActionCommand());
            }
        });

        caseSensitiveCheckBox = new WHCheckBox("Case sensitive", false);

        constraints.gridx = 0;
        constraints.gridy = 0;
        topPanel.add( new JLabel("Text to find: "), constraints );

        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.weightx = 1;
        topPanel.add(searchComboBox, constraints );

        constraints.gridx = 0;
        constraints.gridy = 1;
        topPanel.add( replaceLabel, constraints );

        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.weightx = 1;
        topPanel.add(replaceComboBox, constraints );

        JPanel optionsPanel = createOptionsPanel();
        JPanel directionsPanel = createDirectionsPanel();

        JPanel middlePanel = new JPanel(new GridLayout(1, 2));
        middlePanel.add(optionsPanel);
        middlePanel.add(directionsPanel);

        JPanel mainPanel = new JPanel(new BorderLayout());
        mainPanel.setBorder(new EmptyBorder(new Insets(4, 4, 4, 4)));
        mainPanel.add(topPanel, BorderLayout.NORTH);
        mainPanel.add(middlePanel, BorderLayout.CENTER);

        JPanel buttonPanel = new JPanel( new FlowLayout(FlowLayout.CENTER) );
       
        JButton okButton = createOkButton();
        okButton.setText("Find");
        buttonPanel.add(okButton);
        buttonPanel.add(createCancelButton());

        mainPanel.add(buttonPanel, BorderLayout.SOUTH);
        contentPane.add(mainPanel, BorderLayout.CENTER);

        this.pack();
    }

    private JPanel createDirectionsPanel() {
        JPanel directionsPanel = new JPanel(new GridLayout(3, 1));
        directionsPanel.setBorder( new TitledBorder("Direction") );

        ButtonGroup group = new ButtonGroup();

        this.forwardRadioButton = new WHRadioButton("Forward");
        this.forwardRadioButton.setSelected(true);
        this.backwordRadioButton = new WHRadioButton("Backword");
        this.entireScopeRadioButton = new WHRadioButton("Entire scope");

        group.add(this.forwardRadioButton);
        group.add(this.backwordRadioButton);
        group.add(this.entireScopeRadioButton);

        directionsPanel.add(this.forwardRadioButton);
        directionsPanel.add(this.backwordRadioButton);
        directionsPanel.add(this.entireScopeRadioButton);

        return directionsPanel;
    }

    private JPanel createOptionsPanel() {
        JPanel optionsPanel = new JPanel(new GridLayout(3, 1));
        optionsPanel.setBorder(new TitledBorder("Options"));
        this.caseSensitiveCheckBox = new WHCheckBox("Case sensitive");
        optionsPanel.add(this.caseSensitiveCheckBox);
        this.regularExpressionsCheckBox = new WHCheckBox("Regular expressions");
        optionsPanel.add(this.regularExpressionsCheckBox);
        return optionsPanel;
    }

    protected JRootPane createRootPane() {
        KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
        JRootPane rootPane = new JRootPane();
        ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                setVisible(false);
            }
        };
        rootPane.registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);

        stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
        actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                if (operation == OPERATION_FIND) {
                    find(false);
                } else {
                    replace(false);
                }
            }
        };
        rootPane.registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);


        return rootPane;
    }

    public void open(JTextComponent textComponent, boolean isReplace) {
        setTextComponent(textComponent);
        this.operation = isReplace ? OPERATION_REPLACE : OPERATION_FIND;
        this.replaceLabel.setVisible(isReplace);
        this.replaceComboBox.setVisible(isReplace);
        this.setTitle(isReplace ? "Replace Text" : "Find Text");
        this.pack();

        setLocationRelativeTo(parentFrame);
        setVisible(true);
    }

    public boolean find(boolean backward) {
        return find(backward, true);
    }

    public boolean find(boolean backward, boolean showMessageIfNotFound) {
        String searchText = this.searchComboBox.getEditor().getItem().toString();
        if (searchText == null) {
            return false;
        }

        // there should be something to perform search on and something to search
        if ( this.textComponent == null || "".equals(searchText) ) {
            return false;
        }

        if (this.isVisible()) {
            this.searchComboBox.removeItem(searchText);
            this.searchComboBox.insertItemAt(searchText, 0);
            this.searchComboBox.setSelectedItem(searchText);
        }

        // if find/replace dialog is opened only radio button is relevant
        if ( this.isVisible() ) {
            backward = this.backwordRadioButton.isSelected();
        }

        int startPosition = this.textComponent.getCaretPosition();
        Document doc = this.textComponent.getDocument();
        int len = doc.getLength();

        String content = "";
        try {
            if (backward) {
                content = doc.getText(0, startPosition > 1 ? startPosition - 1 : 0);
                startPosition = 0;
            } else if ( this.isVisible() && this.entireScopeRadioButton.isSelected() ) {
                content = doc.getText(0, len);
                startPosition = 0;
            } else {
                content = doc.getText(startPosition, len - startPosition);
            }
        } catch (BadLocationException e) {
            e.printStackTrace();
            return false;
        }

        // hide this find/replace dialog
        this.setVisible(false);

        boolean isRegexp = this.regularExpressionsCheckBox.isSelected();
        boolean isCaseSensitive = this.caseSensitiveCheckBox.isSelected();
       
        if ( !isCaseSensitive && !isRegexp) {
            content = content.toLowerCase();
            searchText = searchText.toLowerCase();
        }

        // search for occurence
        int index = -1;
        int foundLen = 0;
        if (isRegexp) {
            int flags = Pattern.DOTALL;
            if (!isCaseSensitive) {
                flags |= Pattern.CASE_INSENSITIVE;
            }
            Pattern pattern = Pattern.compile(searchText, flags);
            Matcher matcher = pattern.matcher(content);

            if (!backward) {
                if (matcher.find()) {
                    index = matcher.start();
                    foundLen = matcher.end() - index;
                }
            } else {
                while (matcher.find()) {
                    index = matcher.start();
                    foundLen = matcher.end() - index;
                }
            }
        } else {
            index = backward ? content.lastIndexOf(searchText) : content.indexOf(searchText);
            foundLen = searchText.length();
        }

        if (index >= 0) {
            textComponent.requestFocusInWindow();
            textComponent.select(startPosition + index, startPosition + index + foundLen);
           
            return true;
        } else if (showMessageIfNotFound) {
            Component top = findTopComponent();
            JOptionPane.showMessageDialog(top, "Next occurrence of \"" + searchText + "\" not found.", "Information", JOptionPane.INFORMATION_MESSAGE);
        }

        return false;
    }

    /**
     * Finds the top component in the hierarchy.
     */
    private Component findTopComponent() {
        Component top = textComponent;
        while (top.getParent() != null) {
            top = top.getParent();
        }
        return top;
    }

    public void replace(boolean backward) {
        final String searchText = (String)this.searchComboBox.getSelectedItem();
        final String replaceText = (String)this.replaceComboBox.getSelectedItem();

        if (this.isVisible()) {
            if ( !"".equals(searchText) ) {
                this.searchComboBox.removeItem(searchText);
                this.searchComboBox.insertItemAt(searchText, 0);
                this.searchComboBox.setSelectedItem(searchText);
            }
            this.replaceComboBox.removeItem(replaceText);
            this.replaceComboBox.insertItemAt(replaceText, 0);
            this.replaceComboBox.setSelectedItem(replaceText);
        }

        // there should be something to perform search on and something to search
        if ( this.textComponent == null || "".equals(searchText) ) {
            this.setVisible(false);
            return;
        }

        final Object[] options = {"Replace", "Skip", "All", "Cancel"};
        final JOptionPane optionPane = new JOptionPane("Do you want to replace this occurence?",
                                                 JOptionPane.QUESTION_MESSAGE,
                                                 JOptionPane.YES_NO_CANCEL_OPTION,
                                                 null,
                                                 options,
                                                 options[0] );

        final Frame topFrame = (Frame) findTopComponent();
        final JDialog dialog = new JDialog(topFrame, "Replace", true) {
            protected JRootPane createRootPane() {
                KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
                JRootPane rootPane = new JRootPane();
                ActionListener actionListener = new ActionListener() {
                    public void actionPerformed(ActionEvent actionEvent) {
                        optionPane.setValue("Cancel");
                        setVisible(false);
                    }
                };
                rootPane.registerKeyboardAction(actionListener, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
                return rootPane;
            }
        };
        dialog.setContentPane(optionPane);
        optionPane.addPropertyChangeListener(
            new PropertyChangeListener() {
                public void propertyChange(PropertyChangeEvent e) {
                    String prop = e.getPropertyName();
                    if ( dialog.isVisible() && (e.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY)) ) {
                        dialog.setVisible(false);
                    }
                }
            }
        );

        dialog.pack();

        Object result = null;
        boolean found;
        do {
            found = find(false);
            if (found) {
                optionPane.setValue(null);
                dialog.setVisible(true);
                result = optionPane.getValue();
                if ("Replace".equals(result)) {
                    this.textComponent.replaceSelection(replaceText);
                } else if ("All".equals(result)) {
                    int count = 0;
                    do {
                        this.textComponent.replaceSelection(replaceText);
                        count++;
                        found = find(false, false);
                    } while (found);
                    JOptionPane.showMessageDialog(topFrame, count + " occurence(s) replaced.", "Information", JOptionPane.INFORMATION_MESSAGE);
                }
            }
        } while ( found && !"All".equals(result) && !"Cancel".equals(result) );
    }

    public String getSearchText() {
        return (String) this.searchComboBox.getSelectedItem();
    }

    public void setTextComponent(JTextComponent textComponent) {
        this.textComponent = textComponent;
    }

    public void findNext(JTextComponent textComponent) {
        setTextComponent(textComponent);
        find(false);
    }

    public void findPrev(JTextComponent textComponent) {
        this.textComponent = textComponent;
        find(true);
    }

    public static void main(String[] args) {
        String s = "1ABCDEEEEHIEUIRFEEewgfuiewhf";
        Pattern pattern = Pattern.compile("\\d", Pattern.DOTALL|Pattern.UNICODE_CASE);
        Matcher matcher = pattern.matcher(s);

        boolean found = matcher.find();
        if (found) {
            System.out.println(matcher.start() + ", " + matcher.end());
        }

    }

    protected void onOk() {
        if (operation == OPERATION_FIND) {
            find(false);
        } else {
            replace(false);
        }
    }

}
TOP

Related Classes of org.webharvest.gui.FindReplaceDialog

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.