001    /*
002     * $Id: AlternateRowHighlighter.java,v 1.5 2005/11/22 12:21:39 kleopatra Exp $
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    
022    package org.jdesktop.swingx.decorator;
023    
024    import java.awt.Color;
025    import java.awt.Component;
026    import java.util.HashMap;
027    
028    import javax.swing.UIManager;
029    
030    /**
031     * AlternateRowHighlighter prepares a cell renderer to use different background
032     * colors for alternating rows in a data view. The size (in terms of row count) of
033     * an alternating group is configurable (defaults to 1);
034     *
035     * @author Ramesh Gupta
036     */
037    public class AlternateRowHighlighter extends Highlighter {
038        private final static Color  defaultOddRowColor = Color.white;
039        private final static Color  defaultEvenRowColor = new Color(0xF0, 0xF0, 0xE0);
040    
041        public final static Highlighter beige =
042            new AlternateRowHighlighter(Color.white, new Color(245, 245, 220), null, true);
043    
044        public final static Highlighter linePrinter =
045            new AlternateRowHighlighter(Color.white, new Color(0xCC, 0xCC, 0xFF), null, true);
046    
047        public final static Highlighter classicLinePrinter =
048            new AlternateRowHighlighter(Color.white, new Color(0xCC, 0xFF, 0xCC), null, true);
049    
050        public final static Highlighter floralWhite =
051            new AlternateRowHighlighter(Color.white, new Color(255, 250, 240), null, true);
052    
053        public final static Highlighter quickSilver =
054            new AlternateRowHighlighter(Color.white, defaultEvenRowColor, null, true);
055        
056        public final static AlternateRowHighlighter genericGrey = 
057            new AlternateRowHighlighter(Color.white, new Color(229, 229, 229), null, true);
058    
059        private Color oddRowBackground = defaultOddRowColor;
060        private Color evenRowBackground = defaultEvenRowColor;
061        private int linesPerGroup = 1; 
062    
063        /**
064         * Constructs a default <code>AlternateRowHighlighter</code> that prepares a
065         * cell renderer to paint a white background for odd rows and a silver
066         * <code>(0xF0, 0xF0, 0xE0)</code> background for even rows.
067         */
068        public AlternateRowHighlighter() {
069        }
070    
071        /**
072         * Constructs an <code>AlternateRowHighlighter</code> that prepares a
073         * cell renderer to paint the specified background colors for odd and even
074         * and even rows. A foreground color may also be specified. If null is
075         * specified for the foreground color, the foreground color for the renderer
076         * is unchanged. Otherwise, it is set to the specified foreground color for
077         * both odd and even rows.
078         *
079         * @param oddRowBackground
080         * @param evenRowBackground
081         * @param foreground
082         */
083        public AlternateRowHighlighter(Color oddRowBackground,
084                                       Color evenRowBackground, Color foreground) {
085            this(oddRowBackground, evenRowBackground, foreground, false);
086        }
087    
088        public AlternateRowHighlighter(Color oddRowBackground,
089                Color evenRowBackground, Color foreground, boolean immutable) {
090            super(oddRowBackground, foreground, immutable); // same background for odd and even
091            this.oddRowBackground = oddRowBackground;
092            this.evenRowBackground = evenRowBackground;
093        }
094    
095        /**
096         * Returns the background color for odd rows, or null if the background color
097         * of the cell renderer should be left unchanged for odd rows.
098         *
099         * @return the background color for odd rows, or null if the background color
100         * of the cell renderer should be left unchanged for odd rows
101         */
102        public Color getOddRowBackground() {
103            return oddRowBackground;
104        }
105    
106        /**
107         * Sets the background color for odd rows to the specified color. If null is
108         * specified, the background color for odd rows is left unchanged in the
109         * renderer
110    
111         *
112         * @param color the background color for odd rows, or null if the background
113         * color of the cell renderer should be left unchanged for odd rows
114         */
115        public void setOddRowBackground(Color color) {
116            if (isImmutable()) return;
117            oddRowBackground = color;
118            fireStateChanged();
119        }
120    
121        /**
122         * Returns the background color for even rows, or null if the background color
123         * of the cell renderer should be left unchanged for even rows.
124         *
125         * @return the background color for even rows, or null if the background color
126         * of the cell renderer should be left unchanged for even rows
127         */
128        public Color getEvenRowBackground() {
129            return evenRowBackground;
130        }
131    
132        /**
133         * Sets the background color for even rows to the specified color. If null is
134         * specified, the background color for even rows is left unchanged in the
135         * renderer.
136         *
137         * @param color the background color for even rows, or null if the background
138         * color of the cell renderer should be left unchanged for even rows
139         */
140        public void setEvenRowBackground(Color color) {
141            if (isImmutable()) return;
142            evenRowBackground = color;
143            fireStateChanged();
144        }
145    
146    
147        @Override
148        protected Color computeUnselectedBackground(Component renderer, ComponentAdapter adapter) {
149            return isOddRow(adapter) ?
150                    oddRowBackground : evenRowBackground;
151        }
152    
153        /**
154         * @param adapter
155         * @return true if the adapter's row should be colored with the oddRowBackground,
156         *          false is not
157         */
158        protected boolean isOddRow(ComponentAdapter adapter) {
159            return ((adapter.row / getLinesPerGroup()) % 2) == 0;
160        }
161    
162    
163        public int getLinesPerGroup() {
164            return linesPerGroup;
165        }
166        
167        public void setLinesPerGroup(int linesPerGroup) {
168            if (isImmutable()) return;
169            this.linesPerGroup = Math.max(1, linesPerGroup);
170            fireStateChanged();
171        }
172        
173        public static class UIAlternateRowHighlighter extends AlternateRowHighlighter 
174           implements UIHighlighter {
175    
176            private HashMap<Color, Color> colorMap;
177            public UIAlternateRowHighlighter() {
178                super(Color.WHITE, null, null);
179                initColorMap();
180                updateUI();
181            }
182            
183     
184            public void updateUI() {
185                
186                Color selection = UIManager.getColor("Table.selectionBackground");
187                Color highlight = getMappedColor(selection);
188                
189                setEvenRowBackground(highlight);
190            }
191    
192            private Color getMappedColor(Color selection) {
193                Color color = colorMap.get(selection);
194                if (color == null) {
195                    color = AlternateRowHighlighter.genericGrey.getEvenRowBackground();
196                }
197                return color;
198            }
199            /** 
200             * this is a hack until we can think about something better!
201             * we map all known selection colors to highlighter colors.
202             *
203             */
204            private void initColorMap() {
205                colorMap = new HashMap<Color, Color>();
206                // Ocean
207                colorMap.put(new Color(184, 207, 229), new Color(230, 238, 246));
208                // xp blue
209                colorMap.put(new Color(49, 106, 197), new Color(224, 233, 246));
210                // xp silver
211                colorMap.put(new Color(178, 180, 191), new Color(235, 235, 236));
212                // xp olive
213                colorMap.put(new Color(147, 160, 112), new Color(228, 231, 219));
214                // win classic
215                colorMap.put(new Color(10, 36, 106), new Color(218, 222, 233));
216                // win 2k?
217                colorMap.put(new Color(0, 0, 128), new Color(218, 222, 233));
218                // default metal
219                colorMap.put(new Color(205, 205, 255), new Color(235, 235, 255));
220                // mac OS X
221                colorMap.put(new Color(56, 117, 215), new Color(237, 243, 254));
222                
223            }
224            
225        }
226    
227    }