001/*
002 * $Id: HighlighterFactory.java 4082 2011-11-15 18:39:43Z kschaefe $
003 *
004 * Copyright 2006 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.decorator;
022
023import java.awt.Color;
024import java.awt.Component;
025
026import javax.swing.UIManager;
027
028import org.jdesktop.swingx.decorator.HighlightPredicate.NotHighlightPredicate;
029import org.jdesktop.swingx.decorator.HighlightPredicate.RowGroupHighlightPredicate;
030import org.jdesktop.swingx.plaf.LookAndFeelAddons;
031import org.jdesktop.swingx.plaf.UIColorHighlighterAddon;
032import org.jdesktop.swingx.plaf.UIDependent;
033import org.jdesktop.swingx.util.PaintUtils;
034
035/**
036 * A Factory which creates common Highlighters. <p>
037 * 
038 * PENDING JW: really need the alternate striping? That's how the
039 * old AlternateRowHighlighter did it, but feels a bit wrong to 
040 * have one stripe hardcoded to WHITE. Would prefer to remove.
041 * 
042 * @author Jeanette Winzenburg
043 */
044public final class HighlighterFactory {
045    private static Highlighter COMPUTED_FOREGROUND_HIGHLIGHTER = new AbstractHighlighter() {
046        @Override
047        protected Component doHighlight(Component component, ComponentAdapter adapter) {
048            component.setForeground(PaintUtils.computeForeground(component.getBackground()));
049            
050            return component;
051        }
052    };
053
054    /**
055     * Creates a highlighter that sets the foreground color to WHITE or BLACK by computing the best
056     * match based on the current background color. It is recommended that no background changing
057     * highlighters be added after this highlighter, lest the computation be incorrect.
058     * 
059     * @return a highlighter that computes the appropriate foreground color
060     */
061    public static Highlighter createComputedForegroundHighlighter() {
062        return COMPUTED_FOREGROUND_HIGHLIGHTER;
063    }
064        
065    /**
066     * Creates and returns a Highlighter which highlights every second row
067     * background with a color depending on the LookAndFeel. The rows between
068     * are not highlighted, that is typically, they will show the container's
069     * background.
070     * 
071     * @return a Highlighter striping every second row background.
072     */
073    public static Highlighter createSimpleStriping() {
074        ColorHighlighter hl = new UIColorHighlighter(HighlightPredicate.ODD);
075        return hl;
076    }
077    
078    /**
079     * Creates and returns a Highlighter which highlights every second row group
080     * background with a color depending on LF. The row groups between are not
081     * highlighted, that is typically, they will show the container's
082     * background.
083     * 
084     * @param rowsPerGroup the number of rows in a group
085     * @return a Highlighter striping every second row group background.
086     */
087    public static Highlighter createSimpleStriping(int rowsPerGroup) {
088        return new UIColorHighlighter(new RowGroupHighlightPredicate(
089                rowsPerGroup));
090    }
091
092    /**
093     * Creates and returns a Highlighter which highlights every second row
094     * background with the given color. The rows between are not highlighted
095     * that is typically, they will show the container's background.
096     * 
097     * @param stripeBackground the background color for the striping.
098     * @return a Highlighter striping every second row background. 
099     */
100    public static Highlighter createSimpleStriping(Color stripeBackground) {
101        ColorHighlighter hl = new ColorHighlighter(HighlightPredicate.ODD, stripeBackground, null);
102        return hl;
103    }
104    
105    /**
106     * Creates and returns a Highlighter which highlights every second row group
107     * background with the given color. The row groups between are not
108     * highlighted, that is they typically will show the container's background.
109     * 
110     * @param stripeBackground the background color for the striping.
111     * @param rowsPerGroup the number of rows in a group
112     * @return a Highlighter striping every second row group background.
113     */
114    public static Highlighter createSimpleStriping(Color stripeBackground,
115            int rowsPerGroup) {
116        HighlightPredicate predicate = new RowGroupHighlightPredicate(
117                rowsPerGroup);
118        ColorHighlighter hl = new ColorHighlighter(predicate, stripeBackground,
119                null);
120        return hl;
121    }
122
123    /**
124     * Creates and returns a Highlighter which highlights 
125     * with alternate background. The first is Color.WHITE, the second
126     * with the color depending on LF. 
127     * 
128     * @return a Highlighter striping every second row background. 
129     */
130    public static Highlighter createAlternateStriping() {
131        ColorHighlighter first = new ColorHighlighter(HighlightPredicate.EVEN, Color.WHITE, null);
132        ColorHighlighter hl = new UIColorHighlighter(HighlightPredicate.ODD);
133        return new CompoundHighlighter(first, hl);
134    }
135
136    /**
137     * Creates and returns a Highlighter which highlights 
138     * with alternate background. the first Color.WHITE, the second
139     * with the color depending on LF. 
140     * 
141     * @param rowsPerGroup the number of rows in a group
142     * @return a Highlighter striping every second row group background.
143     */
144    public static Highlighter createAlternateStriping(int rowsPerGroup) {
145        HighlightPredicate predicate = new RowGroupHighlightPredicate(rowsPerGroup);
146        ColorHighlighter first = new ColorHighlighter(new NotHighlightPredicate(predicate), Color.WHITE, null);
147        ColorHighlighter hl = new UIColorHighlighter(predicate);
148        return new CompoundHighlighter(first, hl);
149    }
150    
151    /**
152     * Creates and returns a Highlighter which highlights with
153     * alternating background, starting with the base.
154     * 
155     * @param baseBackground the background color for the even rows.
156     * @param alternateBackground background color for odd rows.
157     * @return a Highlighter striping alternating background. 
158     */
159    public static Highlighter createAlternateStriping(Color baseBackground, Color alternateBackground) {
160        ColorHighlighter base = new ColorHighlighter(HighlightPredicate.EVEN, baseBackground, null);
161        ColorHighlighter alternate = new ColorHighlighter(HighlightPredicate.ODD, alternateBackground, null);
162        return new CompoundHighlighter(base, alternate);
163    }
164
165    /**
166     * Creates and returns a Highlighter which highlights with
167     * alternating background, starting with the base.
168     * 
169     * @param baseBackground the background color for the even rows.
170     * @param alternateBackground background color for odd rows.
171     * @param linesPerStripe the number of rows in a group
172     * @return a Highlighter striping every second row group background. 
173     */
174    public static Highlighter createAlternateStriping(Color baseBackground, Color alternateBackground, int linesPerStripe) {
175        HighlightPredicate predicate = new RowGroupHighlightPredicate(linesPerStripe);
176        ColorHighlighter base = new ColorHighlighter(new NotHighlightPredicate(predicate), baseBackground, null);
177        ColorHighlighter alternate = new ColorHighlighter(predicate, alternateBackground, null);
178        
179        return new CompoundHighlighter(base, alternate);
180    }
181 
182//--------------------------- UI dependent
183    
184    /**
185     * A ColorHighlighter with UI-dependent background.
186     * 
187     * PENDING JW: internally install a AND predicate to check for LFs
188     *   which provide striping on the UI-Delegate level?
189     * 
190     */
191    public static class UIColorHighlighter extends ColorHighlighter 
192        implements UIDependent {
193
194        static {
195            LookAndFeelAddons.contribute(new UIColorHighlighterAddon());
196        }
197
198     
199     /**
200      * Instantiates a ColorHighlighter with LF provided unselected
201      * background and default predicate. All other colors are null.
202      *
203      */
204     public UIColorHighlighter() {
205         this(null);
206     }
207     
208
209     /**
210      * Instantiates a ColorHighlighter with LF provided unselected
211      * background and the given predicate. All other colors are null.
212     * @param odd the predicate to use
213     */
214    public UIColorHighlighter(HighlightPredicate odd) {
215        super(odd, null, null);
216        updateUI();
217    }
218
219
220    /**
221     * @inheritDoc
222     */
223    @Override
224    public void updateUI() {
225         setBackground(getUIColor());
226     }
227
228    /**
229     * Looks up and returns the LF specific color to use for striping
230     * background highlighting. 
231     * 
232     * Lookup strategy: 
233     * <ol>
234     * <li> in UIManager for key = "UIColorHighlighter.stripingBackground", if null
235     * <li> use hard-coded HighlighterFactory.GENERIC_GREY
236     * </ol>
237     * 
238     * PENDING: fallback or not? 
239     *  
240     * @return the LF specific color for background striping.
241     */
242     private Color getUIColor() {
243         Color color = null;
244         // JW: can't do - Nimbus stripes even rows (somewhere deep down the ui?)
245         //, SwingX stripes odd rows
246         // --> combined == no striping 
247//         color = UIManager.getColor("Table.alternateRowColor");
248         if (color == null) {
249             color = UIManager.getColor("UIColorHighlighter.stripingBackground");
250         }
251         if (color == null) {
252             color = HighlighterFactory.GENERIC_GRAY;
253         }
254         return color;
255     }
256//     /** 
257//      * this is a hack until we can think about something better!
258//      * we map all known selection colors to highlighter colors.
259//      *
260//      */
261//     private void initColorMap() {
262//         colorMap = new HashMap<Color, Color>();
263//         // Ocean
264//         colorMap.put(new Color(184, 207, 229), new Color(230, 238, 246));
265//         // xp blue
266//         colorMap.put(new Color(49, 106, 197), new Color(224, 233, 246));
267//         // xp silver
268//         colorMap.put(new Color(178, 180, 191), new Color(235, 235, 236));
269//         // xp olive
270//         colorMap.put(new Color(147, 160, 112), new Color(228, 231, 219));
271//         // win classic
272//         colorMap.put(new Color(10, 36, 106), new Color(218, 222, 233));
273//         // win 2k?
274//         colorMap.put(new Color(0, 0, 128), new Color(218, 222, 233));
275//         // default metal
276//         colorMap.put(new Color(205, 205, 255), new Color(235, 235, 255));
277//         // mac OS X
278//         colorMap.put(new Color(56, 117, 215), new Color(237, 243, 254));
279//         
280//     }
281     
282 }
283
284    /** predefined colors - from old alternateRow. */
285    public final static Color BEIGE = new Color(245, 245, 220);
286    public final static Color LINE_PRINTER = new Color(0xCC, 0xCC, 0xFF);
287    public final static Color CLASSIC_LINE_PRINTER = new Color(0xCC, 0xFF, 0xCC);
288    public final static Color FLORAL_WHITE = new Color(255, 250, 240);
289    public final static Color QUICKSILVER = new Color(0xF0, 0xF0, 0xE0);
290    public final static Color GENERIC_GRAY = new Color(229, 229, 229);
291    public final static Color LEDGER = new Color(0xF5, 0xFF, 0xF5);
292    public final static Color NOTEPAD = new Color(0xFF, 0xFF, 0xCC);
293
294}