2
* $Id: JXFindPanel.java 3357 2009-05-30 04:20:07Z kschaefe $
4
* Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
5
* Santa Clara, California 95054, U.S.A. All rights reserved.
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.
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.
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
22
package org.jdesktop.swingx;
24
import java.awt.Component;
25
import java.util.Locale;
26
import java.util.regex.Pattern;
28
import javax.swing.Box;
29
import javax.swing.BoxLayout;
30
import javax.swing.JCheckBox;
31
import javax.swing.JLabel;
32
import javax.swing.JOptionPane;
34
import org.jdesktop.swingx.search.PatternModel;
35
import org.jdesktop.swingx.search.Searchable;
38
* {@code JXFindPanel} is a basic find panel suitable for use in dialogs. It
39
* offers case-sensitivity, wrapped searching, and reverse searching.
41
* @author unascribed from JDNC
42
* @author Jeanette Winzenburg
44
public class JXFindPanel extends AbstractPatternPanel {
46
public static final String FIND_NEXT_ACTION_COMMAND = "findNext";
47
public static final String FIND_PREVIOUS_ACTION_COMMAND = "findPrevious";
49
protected Searchable searchable;
51
protected JCheckBox wrapCheck;
52
protected JCheckBox backCheck;
53
private boolean initialized;
56
* Default constructor for the find panel. Constructs panel not targeted to
59
public JXFindPanel() {
64
* Construct search panel targeted to specific <code>Searchable</code> component.
66
* @param searchible Component where search widget will try to locate and select
67
* information using methods of the <code>Searchible</code> interface.
69
public JXFindPanel(Searchable searchable) {
70
setName(getUIString(SEARCH_TITLE));
71
setSearchable(searchable);
76
* Sets the Searchable targeted of this find widget.
77
* Triggers a search with null pattern to release the old
80
* @param searchable Component where search widget will try to locate and select
81
* information using methods of the {@link Searchable Searchable} interface.
83
public void setSearchable(Searchable searchable) {
84
if ((this.searchable != null) && this.searchable.equals(searchable)) return;
85
Searchable old = this.searchable;
87
old.search((Pattern) null);
89
this.searchable = searchable;
90
getPatternModel().setFoundIndex(-1);
91
firePropertyChange("searchable", old, this.searchable);
95
* Notifies this component that it now has a parent component.
96
* When this method is invoked, the chain of parent components is
97
* set up with <code>KeyboardAction</code> event listeners.
100
public void addNotify() {
106
* Initializes component and its listeners and models.
108
protected void init() {
109
if (initialized) return;
116
//------------------ support synch the model <--> components
120
* Configure and bind components to/from PatternModel.
123
protected void bind() {
125
getActionContainerFactory().configureButton(wrapCheck,
126
getAction(PatternModel.MATCH_WRAP_ACTION_COMMAND),
128
getActionContainerFactory().configureButton(backCheck,
129
getAction(PatternModel.MATCH_BACKWARDS_ACTION_COMMAND),
135
* called from listening to empty property of PatternModel.
137
* this implementation calls super and additionally synchs the
138
* enabled state of FIND_NEXT_ACTION_COMMAND, FIND_PREVIOUS_ACTION_COMMAND
142
protected void refreshEmptyFromModel() {
143
super.refreshEmptyFromModel();
144
boolean enabled = !getPatternModel().isEmpty();
145
getAction(FIND_NEXT_ACTION_COMMAND).setEnabled(enabled);
146
getAction(FIND_PREVIOUS_ACTION_COMMAND).setEnabled(enabled);
149
//--------------------- action callbacks
151
* Action callback for Find action.
152
* Find next/previous match using current setting of direction flag.
156
public void match() {
161
* Action callback for FindNext action.
162
* Sets direction flag to forward and calls find.
164
public void findNext() {
165
getPatternModel().setBackwards(false);
170
* Action callback for FindPrevious action.
171
* Sets direction flag to previous and calls find.
173
public void findPrevious() {
174
getPatternModel().setBackwards(true);
179
* Common standalone method to perform search. Used by the action callback methods
180
* for Find/FindNext/FindPrevious actions. Finds next/previous match using current
181
* setting of direction flag. Result is being reporred using showFoundMessage and
182
* showNotFoundMessage methods respectively.
188
protected void doFind() {
189
if (searchable == null)
191
int foundIndex = doSearch();
192
boolean notFound = (foundIndex == -1) && !getPatternModel().isEmpty();
194
if (getPatternModel().isWrapping()) {
195
notFound = doSearch() == -1;
199
showNotFoundMessage();
206
* Performs search and returns index of the next match.
208
* @return Index of the next match in document.
210
protected int doSearch() {
211
int foundIndex = searchable.search(getPatternModel().getPattern(),
212
getPatternModel().getFoundIndex(), getPatternModel().isBackwards());
213
getPatternModel().setFoundIndex(foundIndex);
214
return getPatternModel().getFoundIndex();
215
// first try on #236-swingx - foundIndex wrong in backwards search.
216
// re-think: autoIncrement in PatternModel?
217
// return foundIndex;
221
* Report that suitable match is found.
223
protected void showFoundMessage() {
228
* Report that no match is found.
230
protected void showNotFoundMessage() {
231
JOptionPane.showMessageDialog(this, getUIString("notFound"));
235
//-------------- dynamic Locale support
240
protected void updateLocaleState(Locale locale) {
241
super.updateLocaleState(locale);
242
setName(getUIString(SEARCH_TITLE, locale));
245
//-------------------------- initial
249
* creates and registers all "executable" actions.
250
* Meaning: the actions bound to a callback method on this.
253
protected void initExecutables() {
254
getActionMap().put(FIND_NEXT_ACTION_COMMAND,
255
createBoundAction(FIND_NEXT_ACTION_COMMAND, "findNext"));
256
getActionMap().put(FIND_PREVIOUS_ACTION_COMMAND,
257
createBoundAction(FIND_PREVIOUS_ACTION_COMMAND, "findPrevious"));
258
super.initExecutables();
263
//----------------------------- init ui
266
* Create and initialize components.
269
protected void initComponents() {
270
super.initComponents();
271
wrapCheck = new JCheckBox();
272
backCheck = new JCheckBox();
278
* Compose and layout all the subcomponents.
280
protected void build() {
281
Box lBox = new Box(BoxLayout.LINE_AXIS);
282
lBox.add(searchLabel);
283
lBox.add(new JLabel(":"));
284
lBox.add(new JLabel(" "));
285
lBox.setAlignmentY(Component.TOP_ALIGNMENT);
286
Box rBox = new Box(BoxLayout.PAGE_AXIS);
287
rBox.add(searchField);
288
rBox.add(matchCheck);
291
rBox.setAlignmentY(Component.TOP_ALIGNMENT);
293
setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));