001/* 002 * $Id: CompoundHighlighter.java 3927 2011-02-22 16:34:11Z kleopatra $ 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 022package org.jdesktop.swingx.decorator; 023 024import java.awt.Component; 025import java.util.ArrayList; 026import java.util.List; 027 028import javax.swing.event.ChangeEvent; 029import javax.swing.event.ChangeListener; 030 031import org.jdesktop.swingx.plaf.UIDependent; 032import org.jdesktop.swingx.util.Contract; 033 034/** 035 * A class which manages the lists of <code>Highlighter</code>s. 036 * 037 * @see Highlighter 038 * 039 * @author Ramesh Gupta 040 * @author Jeanette Winzenburg 041 * 042 */ 043public class CompoundHighlighter extends AbstractHighlighter 044 implements UIDependent { 045 public static final Highlighter[] EMPTY_HIGHLIGHTERS = new Highlighter[0]; 046 047 protected List<Highlighter> highlighters; 048 049 /** the listener for changes in contained Highlighters. */ 050 private ChangeListener highlighterChangeListener; 051 052 053 /** 054 * Instantiates a CompoundHighlighter containing the given 055 * <code>Highlighter</code>s. 056 * 057 * @param inList zero or more not-null Highlighters to manage by this 058 * CompoundHighlighter. 059 * @throws NullPointerException if array is null or array contains null values. 060 */ 061 public CompoundHighlighter(Highlighter... inList) { 062 this(null, inList); 063 } 064 065 /** 066 * Instantiates a CompoundHighlighter with the given predicate containing the given 067 * <code>Highlighter</code>s. 068 * 069 * @param predicate the highlightPredicate to use 070 * @param inList zero or more not-null Highlighters to manage by this 071 * CompoundHighlighter. 072 * @throws NullPointerException if array is null or array contains null values. 073 */ 074 public CompoundHighlighter(HighlightPredicate predicate, Highlighter... inList) { 075 super(predicate); 076 highlighters = new ArrayList<Highlighter>(); 077 setHighlighters(inList); 078 } 079 080 /** 081 * Sets the given 082 * <code>Highlighter</code>s. 083 * 084 * @param inList zero or more not-null Highlighters to manage by this 085 * CompoundHighlighter. 086 * @throws NullPointerException if array is null or array contains null values. 087 */ 088 public void setHighlighters(Highlighter... inList) { 089 Contract.asNotNull(inList, "Highlighter must not be null"); 090 if (highlighters.isEmpty() && (inList.length == 0)) return; 091 removeAllHighlightersSilently(); 092 for (Highlighter highlighter : inList) { 093 addHighlighterSilently(highlighter, false); 094 } 095 fireStateChanged(); 096 } 097 098 /** 099 * Removes all contained highlighters without firing an event. 100 * Deregisters the listener from all. 101 */ 102 private void removeAllHighlightersSilently() { 103 for (Highlighter highlighter : highlighters) { 104 highlighter.removeChangeListener(getHighlighterChangeListener()); 105 } 106 highlighters.clear(); 107 } 108 109 /** 110 * Appends a highlighter to the pipeline. 111 * 112 * @param highlighter highlighter to add 113 * @throws NullPointerException if highlighter is null. 114 */ 115 public void addHighlighter(Highlighter highlighter) { 116 addHighlighter(highlighter, false); 117 } 118 119 /** 120 * Adds a highlighter to the pipeline. 121 * 122 * PENDING: Duplicate inserts? 123 * 124 * @param highlighter highlighter to add 125 * @param prepend prepend the highlighter if true; false will append 126 * @throws NullPointerException if highlighter is null. 127 */ 128 public void addHighlighter(Highlighter highlighter, boolean prepend) { 129 addHighlighterSilently(highlighter, prepend); 130 fireStateChanged(); 131 } 132 133 private void addHighlighterSilently(Highlighter highlighter, boolean prepend) { 134 Contract.asNotNull(highlighter, "Highlighter must not be null"); 135 if (prepend) { 136 highlighters.add(0, highlighter); 137 } else { 138 highlighters.add(highlighters.size(), highlighter); 139 } 140 updateUI(highlighter); 141 highlighter.addChangeListener(getHighlighterChangeListener()); 142 } 143 144 /** 145 * Removes a highlighter from the pipeline. 146 * 147 * 148 * @param hl highlighter to remove 149 */ 150 public void removeHighlighter(Highlighter hl) { 151 boolean success = highlighters.remove(hl); 152 if (success) { 153 // PENDING: duplicates? 154 hl.removeChangeListener(getHighlighterChangeListener()); 155 fireStateChanged(); 156 } 157 // should log if this didn't succeed. Maybe 158 } 159 160 /** 161 * Returns an array of contained Highlighters. 162 * 163 * @return the contained Highlighters, might be empty but never null. 164 */ 165 public Highlighter[] getHighlighters() { 166 if (highlighters.isEmpty()) return EMPTY_HIGHLIGHTERS; 167 return highlighters.toArray(new Highlighter[highlighters.size()]); 168 } 169 170//--------------------- implement UIDependent 171 172 /** 173 * {@inheritDoc} <p> 174 * 175 * Implemented to call updateUI on contained Highlighters. 176 */ 177 @Override 178 public void updateUI() { 179 for (Highlighter highlighter : highlighters) { 180 updateUI(highlighter); 181 } 182 } 183 184 /** 185 * Returns the <code>ChangeListner</code> to contained 186 * <code>Highlighter</code>s. The listener is lazily created. 187 * 188 * @return the listener for contained highlighters, guaranteed 189 * to be not null. 190 */ 191 protected ChangeListener getHighlighterChangeListener() { 192 if (highlighterChangeListener == null) { 193 highlighterChangeListener = createHighlighterChangeListener(); 194 } 195 return highlighterChangeListener; 196 } 197 198 /** 199 * Creates and returns the ChangeListener registered to 200 * contained <code>Highlighter</code>s. Here: fires a 201 * stateChanged on each notification. 202 * 203 * @return the listener for contained Highlighters. 204 * 205 */ 206 protected ChangeListener createHighlighterChangeListener() { 207 return highlighterChangeListener = new ChangeListener() { 208 209 @Override 210 public void stateChanged(ChangeEvent e) { 211 fireStateChanged(); 212 } 213 214 }; 215 } 216 217 /** 218 * Updates the ui-dependent state of the given Highlighter. 219 * 220 * @param hl the highlighter to update. 221 */ 222 private void updateUI(Highlighter hl) { 223 if (hl instanceof UIDependent) { 224 ((UIDependent) hl).updateUI(); 225 } 226 } 227 228 229//------------------- implement Highlighter 230 231 /** 232 * {@inheritDoc} 233 */ 234 @Override 235 protected Component doHighlight(Component stamp, ComponentAdapter adapter) { 236 for (Highlighter highlighter : highlighters) { 237 stamp = highlighter.highlight(stamp, adapter); 238 } 239 return stamp; 240 } 241 242 243 244}