001 /* 002 * $Id: ConditionalHighlighter.java,v 1.11 2006/05/14 15:55:52 dmouse 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 027 /** 028 * ConditionalHighlighter. 029 * 030 * 031 * @author Ramesh Gupta 032 */ 033 public abstract class ConditionalHighlighter extends Highlighter { 034 protected int testColumn = 0; // always in model coordinates 035 protected int highlightColumn = -1; // always in model coordinates 036 037 // TODO JW ?? - changed from 255 to 256 to not be "on" by default... 038 protected int mask = 256; 039 040 public ConditionalHighlighter() { 041 // default constructor 042 } 043 044 /** 045 * <p>Constructs a <code>ConditionalHighlighter</code> instance with the 046 * specified background and foreground colors that will be used to highlight 047 * the renderer component for a cell in the specified highlightColumn of any 048 * row if and only if {@link #needsHighlight needsHighlight} returns true 049 * for the adapter that identifies that cell.</p> 050 * 051 * @param cellBackground background color for highlighted cells, or null, if 052 * background should not be changed 053 * @param cellForeground foreground color for highlighted cells, or null, if 054 * foreground should not be changed 055 * @param testColumn column whose value is to be tested to determine if a 056 * cell <em>should</em> be highlighted 057 * @param highlightColumn column whose index is used to determine if a cell 058 * <em>could</em> be highlighted; may be a valid column index in model 059 * coordinates, or -1 to indicate all columns 060 */ 061 public ConditionalHighlighter(Color cellBackground, Color cellForeground, 062 int testColumn, int highlightColumn) { 063 super(cellBackground, cellForeground); 064 this.testColumn = testColumn; 065 this.highlightColumn = highlightColumn; 066 } 067 068 /** 069 * TODO: JW ?? 070 */ 071 public void setMask(int alpha) { 072 mask = alpha; 073 fireStateChanged(); 074 } 075 076 /** 077 * TODO: JW ?? 078 * @return mask 079 */ 080 public int getMask() { 081 return mask; 082 } 083 084 /** 085 * Performs a conditional highlight. Calls {@link #doHighlight doHighlight} if 086 * and only if {@link #needsHighlight needsHighlight} returns true. 087 * 088 * @param renderer 089 * @param adapter 090 * @return the highlighted component 091 */ 092 @Override 093 public Component highlight(Component renderer, ComponentAdapter adapter) { 094 if (needsHighlight(adapter)) { 095 return doHighlight(renderer, adapter); 096 } 097 else if (getMask() < 256) { 098 return doMask(renderer, adapter); 099 } 100 return renderer; 101 } 102 103 /** 104 * TODO: ?? 105 * 106 * @param renderer 107 * @param adapter 108 * @return renderer 109 */ 110 protected Component doMask(Component renderer, ComponentAdapter adapter) { 111 112 maskBackground(renderer, adapter); 113 maskForeground(renderer, adapter); 114 // and so on... 115 116 return renderer; 117 } 118 119 /** 120 * TODO: ?? 121 */ 122 protected void maskBackground(Component renderer, ComponentAdapter adapter) { 123 Color seed = renderer.getBackground(); 124 Color color = adapter.isSelected() ? computeSelectedBackground(seed) : seed; 125 // fix issue#21-swingx: foreground of renderers can be null 126 if (color != null) { 127 renderer.setBackground( 128 new Color((getMask() << 24) | (color.getRGB() & 0x00FFFFFF), true)); 129 } 130 } 131 132 /** 133 * TODO: ?? 134 * @param renderer 135 * @param adapter 136 */ 137 protected void maskForeground(Component renderer, ComponentAdapter adapter) { 138 Color seed = renderer.getForeground(); 139 Color color = adapter.isSelected() ? computeSelectedForeground(seed) : seed; 140 // fix issue#21-swingx: foreground of renderers can be null 141 if (color != null) { 142 renderer.setForeground( 143 new Color((getMask() << 24) | (color.getRGB() & 0x00FFFFFF), true)); 144 145 } 146 } 147 148 @Override 149 @Deprecated 150 protected Color computeSelectedForeground(Color seed) { 151 return getSelectedForeground() == null ? 152 seed == null ? null : seed.brighter() : getSelectedForeground(); 153 } 154 155 public int getTestColumnIndex() { 156 return testColumn; 157 } 158 159 public void setTestColumnIndex(int columnIndex) { 160 this.testColumn = columnIndex; 161 fireStateChanged(); 162 } 163 164 public int getHighlightColumnIndex() { 165 return highlightColumn; 166 } 167 168 public void setHighlightColumnIndex(int columnIndex) { 169 this.highlightColumn = columnIndex; 170 fireStateChanged(); 171 } 172 173 /** 174 * Checks if the cell identified by the specified adapter is a potential 175 * candidate for highlighting, and returns true if so; otherwise, it returns false. 176 * 177 * @param adapter 178 * @return true if the cell identified by the specified adapter needs 179 * highlight; false otherwise 180 */ 181 protected boolean needsHighlight(ComponentAdapter adapter) { 182 // Before running test(), quickly check if the cell in the current 183 // adapter is a potential candidate for highlighting. If so, run the test. 184 // highlightColumn is always in "model" coordinates, but adapter.column 185 // is in "view" coordinates. So, convert before comparing. 186 if ((highlightColumn < 0) || 187 (highlightColumn == adapter.viewToModel(adapter.column))) { 188 return test(adapter); 189 } 190 return false; // cell is not a candidate for decoration; 191 } 192 193 /** 194 * Tests if the cell identified by the specified adapter should actually be 195 * highlighted, and returns true if so; otherwise, it returns false. 196 * 197 * @param adapter 198 * @return true if the test succeeds; false otherwise 199 */ 200 protected abstract boolean test(ComponentAdapter adapter); 201 202 }