001/* 002 * $Id: TreeSearchable.java 4178 2012-06-20 08:52:11Z kleopatra $ 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 */ 021package org.jdesktop.swingx.search; 022 023import java.util.regex.Matcher; 024import java.util.regex.Pattern; 025 026import org.jdesktop.swingx.JXTree; 027import org.jdesktop.swingx.decorator.AbstractHighlighter; 028import org.jdesktop.swingx.decorator.Highlighter; 029import org.jdesktop.swingx.util.Contract; 030 031/** 032 * A searchable targetting the visible rows of a JXTree. 033 * 034 * 035 */ 036public class TreeSearchable extends AbstractSearchable { 037 038 protected JXTree tree; 039 040 /** 041 * Instantiates a Searchable for the given JTree. 042 * 043 * @param tree the JTree to search, must not be null. 044 */ 045 public TreeSearchable(JXTree tree) { 046 this.tree = Contract.asNotNull(tree, "tree must not be null"); 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. Returns an 074 * appropriate SearchResult if matching or null if no matching 075 * 076 * @param pattern 077 * @param row a valid row index in view coordinates a valid column index in 078 * view coordinates 079 * @return an appropriate <code>SearchResult</code> if matching or null if 080 * no matching 081 */ 082 protected SearchResult findMatchAt(Pattern pattern, int row) { 083 String text = tree.getStringAt(row); 084 if ((text != null) && (text.length() > 0)) { 085 Matcher matcher = pattern.matcher(text); 086 if (matcher.find()) { 087 return createSearchResult(matcher, row, 0); 088 } 089 } 090 return null; 091 } 092 093 @Override 094 protected int getSize() { 095 return tree.getRowCount(); 096 } 097 098 /** 099 * {@inheritDoc} 100 */ 101 @Override 102 public JXTree getTarget() { 103 return tree; 104 } 105 106 /** 107 * {@inheritDoc} 108 */ 109 @Override 110 protected void moveMatchMarker() { 111 if (markByHighlighter()) { 112 moveMatchByHighlighter(); 113 } else { // use selection 114 moveMatchBySelection(); 115 } 116 } 117 118 protected void moveMatchBySelection() { 119 // // the common behaviour (JXList, JXTable) is to not 120 // // move the selection if not found 121 if (!hasMatch()) { 122 return; 123 } 124 tree.setSelectionRow(lastSearchResult.foundRow); 125 tree.scrollRowToVisible(lastSearchResult.foundRow); 126 } 127 128 /** 129 * use and move the match highlighter. PRE: markByHighlighter 130 * 131 */ 132 protected void moveMatchByHighlighter() { 133 AbstractHighlighter searchHL = getConfiguredMatchHighlighter(); 134 // no match 135 if (!hasMatch()) { 136 return; 137 } else { 138 ensureInsertedSearchHighlighters(searchHL); 139 tree.scrollRowToVisible(lastSearchResult.foundRow); 140 } 141 } 142 143 /** 144 * @param searchHighlighter 145 */ 146 @Override 147 protected void removeHighlighter(Highlighter searchHighlighter) { 148 tree.removeHighlighter(searchHighlighter); 149 } 150 151 /** 152 * @return all registered highlighters 153 */ 154 @Override 155 protected Highlighter[] getHighlighters() { 156 return tree.getHighlighters(); 157 } 158 159 /** 160 * @param highlighter 161 */ 162 @Override 163 protected void addHighlighter(Highlighter highlighter) { 164 tree.addHighlighter(highlighter); 165 } 166 167}