001 /*
002 * $Id: TreeSearchable.java 3166 2009-01-02 13:27:18Z rah003 $
003 *
004 * Copyright 2008 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 package org.jdesktop.swingx.search;
022
023 import java.util.regex.Matcher;
024 import java.util.regex.Pattern;
025
026 import org.jdesktop.swingx.JXTree;
027 import org.jdesktop.swingx.decorator.AbstractHighlighter;
028 import org.jdesktop.swingx.decorator.Highlighter;
029
030 /**
031 * A searchable targetting the visible rows of a JXTree.
032 *
033 * PENDING: value to string conversion should behave as nextMatch (?) which
034 * uses the convertValueToString().
035 *
036 */
037 public class TreeSearchable extends AbstractSearchable {
038
039 protected JXTree tree;
040
041
042 /**
043 * @param tree
044 */
045 public TreeSearchable(JXTree tree) {
046 this.tree = tree;
047 }
048
049 @Override
050 protected void findMatchAndUpdateState(Pattern pattern, int startRow,
051 boolean backwards) {
052 SearchResult searchResult = null;
053 if (backwards) {
054 for (int index = startRow; index >= 0 && searchResult == null; index--) {
055 searchResult = findMatchAt(pattern, index);
056 }
057 } else {
058 for (int index = startRow; index < getSize()
059 && searchResult == null; index++) {
060 searchResult = findMatchAt(pattern, index);
061 }
062 }
063 updateState(searchResult);
064
065 }
066
067 @Override
068 protected SearchResult findExtendedMatch(Pattern pattern, int row) {
069 return findMatchAt(pattern, row);
070 }
071
072 /**
073 * Matches the cell content at row/col against the given Pattern.
074 * Returns an appropriate SearchResult if matching or null if no
075 * matching
076 *
077 * @param pattern
078 * @param row
079 * a valid row index in view coordinates
080 * a valid column index in view coordinates
081 * @return an appropriate <code>SearchResult</code> if matching or
082 * null if no matching
083 */
084 protected SearchResult findMatchAt(Pattern pattern, int row) {
085 String text = tree.getStringAt(row);
086 if ((text != null) && (text.length() > 0 )) {
087 Matcher matcher = pattern.matcher(text);
088 if (matcher.find()) {
089 return createSearchResult(matcher, row, 0);
090 }
091 }
092 return null;
093 }
094
095 @Override
096 protected int getSize() {
097 return tree.getRowCount();
098 }
099
100 /**
101 * {@inheritDoc}
102 */
103 @Override
104 public JXTree getTarget() {
105 return tree;
106 }
107
108
109 /**
110 * {@inheritDoc}
111 */
112 @Override
113 protected void moveMatchMarker() {
114 if (markByHighlighter()) {
115 moveMatchByHighlighter();
116 } else { // use selection
117 moveMatchBySelection();
118 }
119 }
120
121 protected void moveMatchBySelection() {
122 // // the common behaviour (JXList, JXTable) is to not
123 // // move the selection if not found
124 if (!hasMatch()) {
125 return;
126 }
127 tree.setSelectionRow(lastSearchResult.foundRow);
128 tree.scrollRowToVisible(lastSearchResult.foundRow);
129 }
130
131
132 /**
133 * use and move the match highlighter.
134 * PRE: markByHighlighter
135 *
136 */
137 protected void moveMatchByHighlighter() {
138 AbstractHighlighter searchHL = getConfiguredMatchHighlighter();
139 // no match
140 if (!hasMatch()) {
141 return;
142 } else {
143 ensureInsertedSearchHighlighters(searchHL);
144 tree.scrollRowToVisible(lastSearchResult.foundRow);
145 }
146 }
147
148
149
150 /**
151 * @param searchHighlighter
152 */
153 @Override
154 protected void removeHighlighter(Highlighter searchHighlighter) {
155 tree.removeHighlighter(searchHighlighter);
156 }
157
158 /**
159 * @return all registered highlighters
160 */
161 @Override
162 protected Highlighter[] getHighlighters() {
163 return tree.getHighlighters();
164 }
165
166 /**
167 * @param highlighter
168 */
169 @Override
170 protected void addHighlighter(Highlighter highlighter) {
171 tree.addHighlighter(highlighter);
172 }
173
174 }