001    /*
002     * $Id: JXSearchPanel.java,v 1.11 2006/05/14 08:12:17 dmouse Exp $
003     *
004     * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005     * Santa Clara, California 95054, U.S.A. All rights reserved.
006     *
007     * This library is free software; you can redistribute it and/or
008     * modify it under the terms of the GNU Lesser General Public
009     * License as published by the Free Software Foundation; either
010     * version 2.1 of the License, or (at your option) any later version.
011     * 
012     * This library is distributed in the hope that it will be useful,
013     * but WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015     * Lesser General Public License for more details.
016     * 
017     * You should have received a copy of the GNU Lesser General Public
018     * License along with this library; if not, write to the Free Software
019     * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
020     */
021    
022    package org.jdesktop.swingx;
023    
024    import java.util.ArrayList;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.regex.Pattern;
028    
029    import javax.swing.ComboBoxModel;
030    import javax.swing.DefaultComboBoxModel;
031    import javax.swing.JComboBox;
032    
033    import org.jdesktop.swingx.decorator.PatternFilter;
034    import org.jdesktop.swingx.decorator.PatternHighlighter;
035    import org.jdesktop.swingx.decorator.PatternMatcher;
036    
037    /**
038     * Rudimentary search panel.
039     * 
040     * Updates PatternMatchers from user input.
041     * 
042     * Supports 
043     * 
044     * <ol>
045     * <li> text input to match
046     * <li> match rules like contains/equals/... 
047     * <li> toggle case sensitive match
048     * </ol>
049     * 
050     * TODO: allow custom PatternModel and/or access 
051     * to configuration of bound PatternModel. 
052     * 
053     * TODO: fully support control of multiple PatternMatchers.
054     * 
055     * @author Ramesh Gupta
056     * @author Jeanette Winzenburg
057     * 
058     */
059    public class JXSearchPanel extends AbstractPatternPanel {
060    
061    
062        public static final String MATCH_RULE_ACTION_COMMAND = "selectMatchRule";
063    
064        private JComboBox searchCriteria;
065    
066        private List<PatternMatcher> patternMatchers;
067        
068    
069        public JXSearchPanel() {
070            initComponents();
071            build();
072            initActions();
073            bind();
074            getPatternModel().setIncremental(true);
075        }
076    
077    //----------------- accessing public properties
078    
079        /**
080         * sets the PatternFilter control.
081         * 
082         * PENDING: change to do a addPatternMatcher to enable multiple control.
083         * 
084         */
085        public void setPatternFilter(PatternFilter filter) {
086            getPatternMatchers().add(filter);
087            updateFieldName(filter);
088        }
089    
090        /**
091         * sets the PatternHighlighter control.
092         * 
093         * PENDING: change to do a addPatternMatcher to enable multiple control.
094         * 
095         */
096        public void setPatternHighlighter(PatternHighlighter highlighter) {
097            getPatternMatchers().add(highlighter);
098            updateFieldName(highlighter);
099        }
100    
101    
102    
103        /**
104         * set the label of the search combo.
105         * 
106         * @param name
107         */
108        public void setFieldName(String name) {
109            searchLabel.setText(name);
110        }
111    
112        /**
113         * returns the label of the search combo.
114         * 
115         */
116        public String getFieldName() {
117            return searchLabel.getText();
118        }
119    
120        /**
121         * returns the current compiled Pattern.
122         * 
123         * @return the current compiled <code>Pattern</code>
124         */
125        public Pattern getPattern() {
126            return patternModel.getPattern();
127        }
128    
129        /**
130         * @param matcher
131         */
132        protected void updateFieldName(PatternMatcher matcher) {
133            
134            if (matcher instanceof PatternFilter) {
135                PatternFilter filter = (PatternFilter) matcher;
136                if (filter == null) {
137                    searchLabel.setText("Field");
138                } else {
139                    searchLabel.setText(filter.getColumnName());
140                }
141            } else {
142                if (searchLabel.getText().length() == 0) { // ugly hack
143                    searchLabel.setText("Field");
144                    /** TODO: Remove this hack!!! */
145                }
146    
147            }
148        }
149    
150        // ---------------- action callbacks
151    
152        /**
153         * 
154         */
155        public void match() {
156            for (Iterator<PatternMatcher> iter = getPatternMatchers().iterator(); iter.hasNext();) {
157                iter.next().setPattern(getPattern());
158                
159            }
160        }
161    
162        /**
163         * set's the PatternModel's MatchRule to the selected in combo. 
164         * 
165         * NOTE: this
166         * is public as an implementation side-effect! 
167         * No need to ever call directly.
168         */
169        public void updateMatchRule() {
170            getPatternModel().setMatchRule(
171                    (String) searchCriteria.getSelectedItem());
172        }
173    
174        private List<PatternMatcher> getPatternMatchers() {
175            if (patternMatchers == null) {
176                patternMatchers = new ArrayList<PatternMatcher>();
177            }
178            return patternMatchers;
179        }
180    
181        //---------------- init actions and model
182        
183        @Override
184        protected void initExecutables() {
185            super.initExecutables();
186            getActionMap().put(MATCH_RULE_ACTION_COMMAND,
187                    createBoundAction(MATCH_RULE_ACTION_COMMAND, "updateMatchRule"));
188        }
189    
190    
191        //--------------------- binding support
192        
193    
194    
195        /**
196         * bind the components to the patternModel/actions.
197         */
198        @Override
199        protected void bind() {
200            super.bind();
201            List matchRules = getPatternModel().getMatchRules();
202            // PENDING: map rules to localized strings
203            ComboBoxModel model = new DefaultComboBoxModel(matchRules.toArray());
204            model.setSelectedItem(getPatternModel().getMatchRule());
205            searchCriteria.setModel(model);
206            searchCriteria.setAction(getAction(MATCH_RULE_ACTION_COMMAND));
207            
208        }
209        
210    
211    
212        //------------------------ init ui
213        
214        /**
215         * build container by adding all components.
216         * PRE: all components created.
217         */
218        private void build() {
219            add(searchLabel);
220            add(searchCriteria);
221            add(searchField);
222            add(matchCheck);
223        }
224    
225        /**
226         * create contained components.
227         * 
228         *
229         */
230        @Override
231        protected void initComponents() {
232            super.initComponents();
233            searchCriteria = new JComboBox();
234        }
235    
236    
237    }