JXFindDialog.java
上传用户:zhengdagz
上传日期:2014-03-06
资源大小:1956k
文件大小:16k
源码类别:

xml/soap/webservice

开发平台:

Java

  1. /*
  2.  * $Id: JXFindDialog.java,v 1.9 2005/10/10 18:01:57 rbair Exp $
  3.  *
  4.  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
  5.  * Santa Clara, California 95054, U.S.A. All rights reserved.
  6.  *
  7.  * This library is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  * 
  12.  * This library is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  * Lesser General Public License for more details.
  16.  * 
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this library; if not, write to the Free Software
  19.  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  20.  */
  21. package org.jdesktop.swingx;
  22. import java.awt.Component;
  23. import java.awt.ComponentOrientation;
  24. import java.awt.Dimension;
  25. import java.awt.Frame;
  26. import java.awt.GraphicsConfiguration;
  27. import java.awt.GraphicsEnvironment;
  28. import java.awt.Rectangle;
  29. import java.awt.event.ActionEvent;
  30. import java.awt.event.KeyEvent;
  31. import java.beans.PropertyChangeEvent;
  32. import java.beans.PropertyChangeListener;
  33. import java.util.regex.Pattern;
  34. import javax.swing.AbstractAction;
  35. import javax.swing.Action;
  36. import javax.swing.BorderFactory;
  37. import javax.swing.Box;
  38. import javax.swing.BoxLayout;
  39. import javax.swing.InputMap;
  40. import javax.swing.JButton;
  41. import javax.swing.JCheckBox;
  42. import javax.swing.JComponent;
  43. import javax.swing.JDialog;
  44. import javax.swing.JLabel;
  45. import javax.swing.JOptionPane;
  46. import javax.swing.JPanel;
  47. import javax.swing.JTextField;
  48. import javax.swing.KeyStroke;
  49. import javax.swing.SwingUtilities;
  50. import javax.swing.UIManager;
  51. import javax.swing.event.DocumentEvent;
  52. import javax.swing.event.DocumentListener;
  53. import javax.swing.plaf.basic.BasicOptionPaneUI;
  54. import org.jdesktop.swingx.action.AbstractActionExt;
  55. import org.jdesktop.swingx.action.ActionContainerFactory;
  56. import org.jdesktop.swingx.action.BoundAction;
  57. import org.jdesktop.swingx.plaf.LookAndFeelAddons;
  58. /**
  59.  * Simple FindDialog.
  60.  * 
  61.  * 
  62.  * PENDING: need to extract a common dialog.
  63.  * PENDING: the base search widget need not be a dialog!
  64.  * 
  65.  * @deprecated use SearchFactory.getInstance().showFindDialog() instead
  66.  * @author ??
  67.  * @author Jeanette Winzenburg
  68.  */
  69. public class JXFindDialog extends JDialog {
  70.     static {
  71.         // Hack to enforce loading of SwingX framework ResourceBundle
  72.         LookAndFeelAddons.getAddon();
  73.     }
  74.     
  75.     public static final String MATCH_WRAP_ACTION_COMMAND = "wrapSearch";
  76.     public static final String MATCH_BACKWARDS_ACTION_COMMAND = "backwardsSearch";
  77.     public static final String EXECUTE_FIND_ACTION_COMMAND = "executeSearch";
  78.     public static final String EXECUTE_ACTION_COMMAND = "execute";
  79.     public static final String CLOSE_ACTION_COMMAND = "close";
  80.     private static final String SEARCH_FIELD_LABEL = "searchFieldLabel";
  81.     private static final String SEARCH_FIELD_MNEMONIC = SEARCH_FIELD_LABEL + ".mnemonic";
  82. //    private static final Object ENTER_ACTION_COMMAND = null;
  83. //    private static final Object CANCEL_ACTION_COMMAND = null;
  84.     
  85.     private Searchable searchable;
  86.     private JTextField searchField;
  87.     private JCheckBox matchCheck;
  88.     private JCheckBox wrapCheck;
  89.     private JCheckBox backCheck;
  90.     private PatternModel patternModel;
  91.     public JXFindDialog() {
  92.         this(null, null);
  93.     }
  94.     
  95.     public JXFindDialog(Searchable searchable) {
  96.         this(searchable, 
  97.             (searchable instanceof Component) ? (Component) searchable : null);
  98.      }
  99.     public JXFindDialog(Searchable searchable, Component component) {
  100.         super(component != null ? 
  101.               (Frame)SwingUtilities.getWindowAncestor(component) : JOptionPane.getRootFrame(),
  102.               "Find in this component");
  103.         setSearchable(searchable);
  104.         locate();
  105.         init();
  106.         pack();
  107.     }
  108.     
  109.     /**
  110.      * Sets the Searchable targeted with this dialog.
  111.      * 
  112.      * @param searchable 
  113.      */
  114.     public void setSearchable(Searchable searchable) {
  115.         if ((this.searchable != null) && this.searchable.equals(searchable)) return;
  116.         Object old = this.searchable;
  117.         this.searchable = searchable;
  118.         setLastIndex(-1);
  119.         firePropertyChange("searchable", old, this.searchable);
  120.     }
  121.     
  122.     /**
  123.      * 
  124.      */
  125.     private void locate() {
  126.         GraphicsConfiguration gc =
  127.             GraphicsEnvironment.getLocalGraphicsEnvironment().
  128.             getDefaultScreenDevice().getDefaultConfiguration();
  129.         Rectangle bounds = gc.getBounds();
  130.         int x = bounds.x+bounds.width/3;
  131.         int y = bounds.y+bounds.height/3;
  132.         setLocation(x, y);
  133.     }
  134.     private void init() {
  135.         initActions();
  136.         initComponents();
  137.         build();
  138.         bind();
  139.     }
  140.     //------------------ support synch the model <--> components
  141.     
  142.     /**
  143.      * 
  144.      */
  145.     private PatternModel getPatternModel() {
  146.         if (patternModel == null) {
  147.             patternModel = new PatternModel();
  148.             patternModel.addPropertyChangeListener(getPatternModelListener());
  149.         }
  150.         return patternModel;
  151.     }
  152.     /**
  153.      * creates and returns a PropertyChangeListener to the PatternModel.
  154.      * 
  155.      * NOTE: the patternModel is totally under control of this class - currently
  156.      * there's no need to keep a reference to the listener.
  157.      * 
  158.      * @return
  159.      */
  160.     private PropertyChangeListener getPatternModelListener() {
  161.         PropertyChangeListener l = new PropertyChangeListener() {
  162.             public void propertyChange(PropertyChangeEvent evt) {
  163.                 if ("pattern".equals(evt.getPropertyName())) {
  164.                     refreshPatternMatchersFromModel();
  165.                 }
  166.             }
  167.         };
  168.         return l;
  169.     }
  170.     /**
  171.      * callback method from listening to PatternModel.
  172.      *
  173.      */
  174.     protected void refreshPatternMatchersFromModel() {
  175.     }
  176.     private DocumentListener getSearchFieldListener() {
  177.         DocumentListener l = new DocumentListener() {
  178.             public void changedUpdate(DocumentEvent ev) {
  179.                 // JW - really?? we've a PlainDoc without Attributes
  180.                 refreshModelFromDocument();
  181.             }
  182.             public void insertUpdate(DocumentEvent ev) {
  183.                 refreshModelFromDocument();
  184.             }
  185.             public void removeUpdate(DocumentEvent ev) {
  186.                 refreshModelFromDocument();
  187.             }
  188.         };
  189.         return l;
  190.     }
  191.     /**
  192.      * callback method from listening to searchField.
  193.      *
  194.      */
  195.     protected void refreshModelFromDocument() {
  196.         getPatternModel().setRawText(searchField.getText());
  197.     }
  198.     private void bind() {
  199.         searchField.getDocument().addDocumentListener(getSearchFieldListener());
  200.         ActionContainerFactory factory = new ActionContainerFactory(null);
  201.         factory.configureButton(matchCheck, 
  202.                 (AbstractActionExt) getAction(PatternModel.MATCH_CASE_ACTION_COMMAND),
  203.                 null);
  204.         factory.configureButton(wrapCheck, 
  205.                 (AbstractActionExt) getAction(MATCH_WRAP_ACTION_COMMAND),
  206.                 null);
  207.         factory.configureButton(backCheck, 
  208.                 (AbstractActionExt) getAction(MATCH_BACKWARDS_ACTION_COMMAND),
  209.                 null);
  210.     }
  211. //--------------------- action callbacks
  212.     /**
  213.      * Action callback for Find action.
  214.      */
  215.     public void doFind() {
  216.         doFind(getPatternModel().isBackwards());
  217.     }
  218.     public void doFind(boolean backwards) {
  219.         if (searchable == null) return;
  220.         setLastIndex(searchable.search(getPattern(), getLastIndex(), backwards));
  221.         if (getLastIndex() == -1) {
  222.             boolean notFound = true;
  223.             if (isWrapping()) {
  224.                 setLastIndex(searchable.search(getPattern(), -1, backwards));
  225.                 notFound = getLastIndex() == -1;
  226.             } 
  227.             if (notFound) {
  228.                 JOptionPane.showMessageDialog(this, "Value not found");
  229.             }
  230.         }
  231.     }
  232.     private boolean isWrapping() {
  233.         return getPatternModel().isWrapping();
  234.     }
  235.     /**
  236.      * Action callback for Close action.
  237.      */
  238.     public void doClose() {
  239.         JXFindDialog.this.dispose();
  240.     }
  241.     private void setLastIndex(int i) {
  242.         getPatternModel().setFoundIndex(i);
  243.         
  244.     }
  245.     private int getLastIndex() {
  246.         return getPatternModel().getFoundIndex();
  247.     }
  248.     private Pattern getPattern() {
  249.         return getPatternModel().getPattern();
  250.     }
  251.     //-------------------------- initial
  252.     
  253.     private void initActions() {
  254.         putAction(PatternModel.MATCH_CASE_ACTION_COMMAND, createMatchCaseAction());
  255.         putAction(MATCH_WRAP_ACTION_COMMAND, createWrapAction());
  256.         putAction(MATCH_BACKWARDS_ACTION_COMMAND, createBackwardsAction());
  257.         // PENDING: factor a common dialog containing the following
  258.         putAction(EXECUTE_FIND_ACTION_COMMAND, createFindAction());
  259.         putAction(CLOSE_ACTION_COMMAND, createCloseAction());
  260.     }
  261.     /**
  262.      * 
  263.      * @return
  264.      */
  265.     private AbstractActionExt createMatchCaseAction() {
  266.         String actionName = getUIString(PatternModel.MATCH_CASE_ACTION_COMMAND);
  267.         BoundAction action = new BoundAction(actionName,
  268.                 PatternModel.MATCH_CASE_ACTION_COMMAND);
  269.         action.setStateAction();
  270.         action.registerCallback(getPatternModel(), "setCaseSensitive");
  271.         action.setSelected(getPatternModel().isCaseSensitive());
  272.         return action;
  273.     }
  274.     /**
  275.      * 
  276.      * @return
  277.      */
  278.     private AbstractActionExt createWrapAction() {
  279.         String actionName = getUIString(MATCH_WRAP_ACTION_COMMAND);
  280.         BoundAction action = new BoundAction(actionName,
  281.                 MATCH_WRAP_ACTION_COMMAND);
  282.         action.setStateAction();
  283.         action.registerCallback(getPatternModel(), "setWrapping");
  284.         action.setSelected(getPatternModel().isWrapping());
  285.         return action;
  286.     }
  287.     /**
  288.      * 
  289.      * @return
  290.      */
  291.     private AbstractActionExt createBackwardsAction() {
  292.         String actionName = getUIString(MATCH_BACKWARDS_ACTION_COMMAND);
  293.         BoundAction action = new BoundAction(actionName,
  294.                 MATCH_BACKWARDS_ACTION_COMMAND);
  295.         action.setStateAction();
  296.         action.registerCallback(getPatternModel(), "setBackwards");
  297.         action.setSelected(getPatternModel().isWrapping());
  298.         return action;
  299.     }
  300.     
  301.     /**
  302.      * 
  303.      * @return
  304.      */
  305.     private AbstractActionExt createFindAction() {
  306.         String actionName = getUIString(EXECUTE_FIND_ACTION_COMMAND);
  307.         BoundAction action = new BoundAction(actionName,
  308.                 EXECUTE_FIND_ACTION_COMMAND);
  309.         action.registerCallback(this, "doFind");
  310.         return action;
  311.     }
  312.     
  313.     /**
  314.      * 
  315.      * @return
  316.      */
  317.     private AbstractActionExt createCloseAction() {
  318.         String actionName = getUIString(CLOSE_ACTION_COMMAND);
  319.         BoundAction action = new BoundAction(actionName,
  320.                 CLOSE_ACTION_COMMAND);
  321.         action.registerCallback(this, "doClose");
  322.         return action;
  323.     }
  324.     /**
  325.      * convenience wrapper to access rootPane's actionMap.
  326.      * @param key
  327.      * @param action
  328.      */
  329.     private void putAction(Object key, Action action) {
  330.         getRootPane().getActionMap().put(key, action);
  331.     }
  332.     
  333.     /**
  334.      * convenience wrapper to access rootPane's actionMap.
  335.      * 
  336.      * @param key
  337.      * @return
  338.      */
  339.     private Action getAction(Object key) {
  340.         return getRootPane().getActionMap().get(key);
  341.     }
  342.     /**
  343.      * tries to find a String value from the UIManager, prefixing the
  344.      * given key with the UIPREFIX. 
  345.      * 
  346.      * TODO: move to utilities?
  347.      * 
  348.      * @param key 
  349.      * @return the String as returned by the UIManager or key if the returned
  350.      *   value was null.
  351.      */
  352.     private String getUIString(String key) {
  353.         String text = UIManager.getString(PatternModel.SEARCH_PREFIX + key);
  354.         return text != null ? text : key;
  355.     }
  356.    
  357. //----------------------------- init ui
  358.     
  359.     /** create components.
  360.      * 
  361.      */
  362.     private void initComponents() {
  363.         searchField = new JTextField(30) {
  364.             public Dimension getMaximumSize() {
  365.                 Dimension superMax = super.getMaximumSize();
  366.                 superMax.height = getPreferredSize().height;
  367.                 return superMax;
  368.             }
  369.         };
  370.         matchCheck = new JCheckBox();
  371.         wrapCheck = new JCheckBox();
  372.         backCheck = new JCheckBox();
  373.     }
  374.     private void build() {
  375.         JComponent content = new Box(BoxLayout.PAGE_AXIS); //Box.createVerticalBox();
  376.         JComponent fieldPanel = createFieldPanel();
  377.         content.add(fieldPanel);
  378.         JComponent buttonPanel = createButtonPanel();
  379.         content.add(buttonPanel);
  380.         content.setBorder(BorderFactory.createEmptyBorder(14, 14, 14, 14));
  381. //        content.applyComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
  382.         
  383. //        fieldPanel.setAlignmentX();
  384. //      buttonPanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
  385.         add(content);
  386.     }
  387.     /**
  388.      * TODO: Strings should be removed from the UI
  389.      */
  390.     private JComponent createFieldPanel() {
  391.         // Create components
  392.         JLabel label = new JLabel(getUIString(SEARCH_FIELD_LABEL));
  393.         String mnemonic = getUIString(SEARCH_FIELD_MNEMONIC);
  394.         if (mnemonic != SEARCH_FIELD_MNEMONIC) {
  395.             label.setDisplayedMnemonic(mnemonic.charAt(0));
  396.         }
  397.         label.setLabelFor(searchField);
  398.         Box lBox = new Box(BoxLayout.LINE_AXIS); 
  399.         lBox.add(label);
  400.         lBox.add(new JLabel(":"));
  401.         lBox.add(new JLabel("  "));
  402. //        lBox.add(Box.createGlue());
  403.         lBox.setAlignmentY(Component.TOP_ALIGNMENT);
  404.         Box rBox = new Box(BoxLayout.PAGE_AXIS); 
  405.         rBox.add(searchField);
  406.         rBox.add(matchCheck);
  407.         rBox.add(wrapCheck);
  408.         rBox.add(backCheck);
  409.         rBox.setAlignmentY(Component.TOP_ALIGNMENT);
  410.         Box box = new Box(BoxLayout.LINE_AXIS);
  411.         box.add(lBox);
  412.         box.add(rBox);
  413.         return box;
  414.     }
  415.     /**
  416.      * create the dialog button controls.
  417.      * 
  418.      * PENDING: this should be factored to a common dialog support.
  419.      * 
  420.      * @return
  421.      */
  422.     private JComponent createButtonPanel() {
  423.         JPanel panel = new JPanel(new BasicOptionPaneUI.ButtonAreaLayout(true, 6))
  424.         {
  425.             public Dimension getMaximumSize() {
  426.                 return getPreferredSize();
  427.             }
  428.         };
  429.         panel.setBorder(BorderFactory.createEmptyBorder(9, 0, 0, 0));
  430.         Action findAction = getAction(EXECUTE_FIND_ACTION_COMMAND);
  431.         Action closeAction = getAction(CLOSE_ACTION_COMMAND);
  432.         JButton findButton;
  433.         panel.add(findButton = new JButton(findAction));
  434.         panel.add(new JButton(closeAction));
  435.         KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false);
  436.         KeyStroke escapeKey = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
  437.         InputMap inputMap = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  438.         inputMap.put(enterKey, EXECUTE_FIND_ACTION_COMMAND);
  439.         inputMap.put(escapeKey, CLOSE_ACTION_COMMAND);
  440.         getRootPane().setDefaultButton(findButton);
  441.         return panel;
  442.     }
  443.     //----------------------- obsolete actions - no longer use
  444.     //----------------------- kept here to remember adding names etc to resources
  445.     private abstract class CheckAction extends AbstractAction {
  446.         public CheckAction(String name) {
  447.             super(name);
  448.         }
  449.         public void actionPerformed(ActionEvent evt) {
  450.         }
  451.     }
  452.     private class MatchAction extends CheckAction {
  453.         public MatchAction() {
  454.             super("Match upper/lower case");
  455.             putValue(Action.MNEMONIC_KEY, new Integer('M'));
  456.         }
  457.     }
  458.     private class WrapAction extends CheckAction {
  459.         public WrapAction() {
  460.             super("Wrap around");
  461.             putValue(Action.MNEMONIC_KEY, new Integer('W'));
  462.         }
  463.     }
  464.     private class BackwardAction extends CheckAction {
  465.         public BackwardAction() {
  466.             super("Search Backwards");
  467.             putValue(Action.MNEMONIC_KEY, new Integer('B'));
  468.         }
  469.     }
  470. }