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 }