/* * $Id$ * * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ package org.jdesktop.swingx.decorator; import java.awt.Component; import java.util.ArrayList; import java.util.List; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.jdesktop.swingx.plaf.UIDependent; import org.jdesktop.swingx.util.Contract; /** * A class which manages the lists of <code>Highlighter</code>s. * * @see Highlighter * * @author Ramesh Gupta * @author Jeanette Winzenburg * */ public class CompoundHighlighter extends AbstractHighlighter implements UIDependent { public static final Highlighter[] EMPTY_HIGHLIGHTERS = new Highlighter[0]; protected List<Highlighter> highlighters; /** the listener for changes in contained Highlighters. */ private ChangeListener highlighterChangeListener; /** * Instantiates a CompoundHighlighter containing the given * <code>Highlighter</code>s. * * @param inList zero or more not-null Highlighters to manage by this * CompoundHighlighter. * @throws NullPointerException if array is null or array contains null values. */ public CompoundHighlighter(Highlighter... inList) { this(null, inList); } /** * Instantiates a CompoundHighlighter with the given predicate containing the given * <code>Highlighter</code>s. * * @param predicate the highlightPredicate to use * @param inList zero or more not-null Highlighters to manage by this * CompoundHighlighter. * @throws NullPointerException if array is null or array contains null values. */ public CompoundHighlighter(HighlightPredicate predicate, Highlighter... inList) { super(predicate); highlighters = new ArrayList<Highlighter>(); setHighlighters(inList); } /** * Sets the given * <code>Highlighter</code>s. * * @param inList zero or more not-null Highlighters to manage by this * CompoundHighlighter. * @throws NullPointerException if array is null or array contains null values. */ public void setHighlighters(Highlighter... inList) { Contract.asNotNull(inList, "Highlighter must not be null"); if (highlighters.isEmpty() && (inList.length == 0)) return; removeAllHighlightersSilently(); for (Highlighter highlighter : inList) { addHighlighterSilently(highlighter, false); } fireStateChanged(); } /** * Removes all contained highlighters without firing an event. * Deregisters the listener from all. */ private void removeAllHighlightersSilently() { for (Highlighter highlighter : highlighters) { highlighter.removeChangeListener(getHighlighterChangeListener()); } highlighters.clear(); } /** * Appends a highlighter to the pipeline. * * @param highlighter highlighter to add * @throws NullPointerException if highlighter is null. */ public void addHighlighter(Highlighter highlighter) { addHighlighter(highlighter, false); } /** * Adds a highlighter to the pipeline. * * PENDING: Duplicate inserts? * * @param highlighter highlighter to add * @param prepend prepend the highlighter if true; false will append * @throws NullPointerException if highlighter is null. */ public void addHighlighter(Highlighter highlighter, boolean prepend) { addHighlighterSilently(highlighter, prepend); fireStateChanged(); } private void addHighlighterSilently(Highlighter highlighter, boolean prepend) { Contract.asNotNull(highlighter, "Highlighter must not be null"); if (prepend) { highlighters.add(0, highlighter); } else { highlighters.add(highlighters.size(), highlighter); } updateUI(highlighter); highlighter.addChangeListener(getHighlighterChangeListener()); } /** * Removes a highlighter from the pipeline. * * * @param hl highlighter to remove */ public void removeHighlighter(Highlighter hl) { boolean success = highlighters.remove(hl); if (success) { // PENDING: duplicates? hl.removeChangeListener(getHighlighterChangeListener()); fireStateChanged(); } // should log if this didn't succeed. Maybe } /** * Returns an array of contained Highlighters. * * @return the contained Highlighters, might be empty but never null. */ public Highlighter[] getHighlighters() { if (highlighters.isEmpty()) return EMPTY_HIGHLIGHTERS; return highlighters.toArray(new Highlighter[highlighters.size()]); } //--------------------- implement UIDependent /** * {@inheritDoc} <p> * * Implemented to call updateUI on contained Highlighters. */ @Override public void updateUI() { for (Highlighter highlighter : highlighters) { updateUI(highlighter); } } /** * Returns the <code>ChangeListner</code> to contained * <code>Highlighter</code>s. The listener is lazily created. * * @return the listener for contained highlighters, guaranteed * to be not null. */ protected ChangeListener getHighlighterChangeListener() { if (highlighterChangeListener == null) { highlighterChangeListener = createHighlighterChangeListener(); } return highlighterChangeListener; } /** * Creates and returns the ChangeListener registered to * contained <code>Highlighter</code>s. Here: fires a * stateChanged on each notification. * * @return the listener for contained Highlighters. * */ protected ChangeListener createHighlighterChangeListener() { return highlighterChangeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { fireStateChanged(); } }; } /** * Updates the ui-dependent state of the given Highlighter. * * @param hl the highlighter to update. */ private void updateUI(Highlighter hl) { if (hl instanceof UIDependent) { ((UIDependent) hl).updateUI(); } } //------------------- implement Highlighter /** * {@inheritDoc} */ @Override protected Component doHighlight(Component stamp, ComponentAdapter adapter) { for (Highlighter highlighter : highlighters) { stamp = highlighter.highlight(stamp, adapter); } return stamp; } }