001: /*
002: * ToolTipRenderer.java
003: *
004: * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005: *
006: * Copyright 2002-2008, Thomas Kellerer
007: * No part of this code maybe reused without the permission of the author
008: *
009: * To contact the author please send an email to: support@sql-workbench.net
010: *
011: */
012: package workbench.gui.renderer;
013:
014: import java.awt.Color;
015: import java.awt.Component;
016: import java.awt.Dimension;
017: import java.awt.FontMetrics;
018: import java.awt.Graphics;
019: import java.awt.Insets;
020: import java.awt.Rectangle;
021:
022: import javax.swing.Icon;
023: import javax.swing.JComponent;
024: import javax.swing.JTable;
025: import javax.swing.SwingConstants;
026: import javax.swing.SwingUtilities;
027: import javax.swing.table.TableCellRenderer;
028: import workbench.gui.WbSwingUtilities;
029: import workbench.gui.components.WbTable;
030: import workbench.resource.Settings;
031: import workbench.storage.filter.ColumnExpression;
032: import workbench.util.StringUtil;
033:
034: /**
035: * A renderer that automatically displays the value as a tooltip.
036: * It also handles the highlighting of null values during display
037: * and non-null columns in editing mode.
038: * It can also highlight values based on a ColumnExpression that is
039: * provided by WbTable.
040: *
041: * @author support@sql-workbench.net
042: */
043: public class ToolTipRenderer extends JComponent implements
044: TableCellRenderer, WbRenderer, RequiredFieldHighlighter {
045: protected String displayValue = StringUtil.EMPTY_STRING;
046: protected String tooltip = null;
047:
048: protected Color selectedForeground;
049: protected Color selectedBackground;
050: protected Color unselectedForeground;
051: protected Color unselectedBackground;
052: protected Color highlightBackground;
053: protected Color filterHighlightColor = Settings.getInstance()
054: .getExpressionHighlightColor();
055:
056: private Color alternateBackground = Settings.getInstance()
057: .getAlternateRowColor();
058: private boolean useAlternatingColors = Settings.getInstance()
059: .getUseAlternateRowColor();
060: private Color nullColor = Settings.getInstance().getNullColor();
061:
062: protected int maxTooltipSize = Settings.getInstance()
063: .getIntProperty("workbench.gui.renderer.maxtooltipsize",
064: 1000);
065: protected int editingRow = -1;
066: private boolean isEditing = false;
067: private boolean[] highlightCols;
068: private int currentColumn = -1;
069:
070: private Rectangle paintIconR = new Rectangle();
071: private Rectangle paintTextR = new Rectangle();
072: private Rectangle paintViewR = new Rectangle();
073:
074: private boolean isPrinting = false;
075:
076: private Insets focusedInsets;
077:
078: protected boolean isSelected;
079: protected boolean hasFocus;
080:
081: //protected boolean filterMatches;
082: protected ColumnExpression filter;
083:
084: private int valign = SwingConstants.TOP;
085: private int halign = SwingConstants.LEFT;
086:
087: private boolean isAlternatingRow = false;
088:
089: public ToolTipRenderer() {
090: int thick = WbSwingUtilities.FOCUSED_CELL_BORDER.getThickness();
091: focusedInsets = new Insets(thick, thick, thick, thick);
092: }
093:
094: public void setUseAlternatingColors(boolean flag) {
095: this .useAlternatingColors = flag;
096: }
097:
098: public void setEditingRow(int row) {
099: this .editingRow = row;
100: }
101:
102: public void setHighlightColumns(boolean[] cols) {
103: this .highlightCols = cols;
104: }
105:
106: public void setVerticalAlignment(int align) {
107: this .valign = align;
108: }
109:
110: public void setHorizontalAlignment(int align) {
111: this .halign = align;
112: }
113:
114: public int getHorizontalAlignment() {
115: return this .halign;
116: }
117:
118: public void setHighlightBackground(Color c) {
119: this .highlightBackground = c;
120: }
121:
122: protected void initDisplay(JTable table, Object value,
123: boolean selected, boolean focus, int row, int col) {
124: this .hasFocus = focus;
125: this .isEditing = (row == this .editingRow)
126: && (this .highlightBackground != null);
127: this .currentColumn = col;
128: this .isSelected = selected;
129: this .isAlternatingRow = this .useAlternatingColors
130: && ((row % 2) == 1);
131:
132: if (selectedForeground == null) {
133: selectedForeground = table.getSelectionForeground();
134: selectedBackground = table.getSelectionBackground();
135: }
136:
137: if (unselectedForeground == null) {
138: unselectedForeground = table.getForeground();
139: unselectedBackground = table.getBackground();
140: }
141:
142: if (table instanceof WbTable) {
143: filter = ((WbTable) table).getHighlightExpression();
144: }
145: }
146:
147: public Component getTableCellRendererComponent(JTable table,
148: Object value, boolean selected, boolean focus, int row,
149: int col) {
150: initDisplay(table, value, selected, focus, row, col);
151: this .setFont(table.getFont());
152:
153: if (value != null) {
154: this .prepareDisplay(value);
155: } else {
156: this .displayValue = null;
157: setTooltip(null);
158: }
159:
160: return this ;
161: }
162:
163: public Dimension getPreferredSize() {
164: Dimension d = super .getPreferredSize();
165: FontMetrics fm = getFontMetrics(getFont());
166:
167: d.setSize(d.getWidth(), fm.getHeight());
168: return d;
169: }
170:
171: protected Color getForegroundColor() {
172: if (isSelected) {
173: return selectedForeground;
174: }
175: return unselectedForeground;
176: }
177:
178: private boolean isHighlightColumn(int col) {
179: if (this .highlightCols == null)
180: return false;
181: if (col < 0 || col > this .highlightCols.length)
182: return false;
183: return this .highlightCols[col];
184: }
185:
186: protected Color getBackgroundColor() {
187: if (isPrinting) {
188: return unselectedBackground;
189: }
190:
191: if (isEditing) {
192: if (isHighlightColumn(currentColumn)) {
193: return this .highlightBackground;
194: } else {
195: return unselectedBackground;
196: }
197: }
198:
199: if (isSelected) {
200: return selectedBackground;
201: }
202:
203: if (checkHighlightExpression()) {
204: return filterHighlightColor;
205: }
206:
207: if (displayValue == null && nullColor != null) {
208: return nullColor;
209: } else {
210: if (isAlternatingRow) {
211: return alternateBackground;
212: } else {
213: return unselectedBackground;
214: }
215: }
216: }
217:
218: public void paint(Graphics g) {
219: int w = this .getWidth();
220: int h = this .getHeight();
221:
222: FontMetrics fm = getFontMetrics(getFont());
223:
224: Insets insets;
225:
226: if (hasFocus) {
227: insets = focusedInsets;
228: } else {
229: insets = WbSwingUtilities.EMPTY_INSETS;
230: }
231:
232: paintViewR.x = insets.left;
233: paintViewR.y = insets.top;
234: paintViewR.width = w - (insets.left + insets.right);
235: paintViewR.height = h - (insets.top + insets.bottom);
236:
237: paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
238: paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
239:
240: String clippedText = StringUtil.EMPTY_STRING;
241: if (displayValue != null) {
242: clippedText = SwingUtilities.layoutCompoundLabel(this , fm,
243: this .displayValue, (Icon) null, this .valign,
244: this .halign, SwingConstants.TOP,
245: SwingConstants.RIGHT, paintViewR, paintIconR,
246: paintTextR, 0);
247: }
248:
249: int textX = paintTextR.x;
250: if (textX < 0)
251: textX = 0;
252: int textY = paintTextR.y + fm.getAscent();
253: if (textY < 0)
254: textY = 0;
255:
256: g.setColor(getBackgroundColor());
257: g.fillRect(0, 0, w, h);
258: g.setColor(getForegroundColor());
259: g.drawString(clippedText, textX, textY);
260:
261: if (hasFocus) {
262: WbSwingUtilities.FOCUSED_CELL_BORDER.paintBorder(this , g,
263: 0, 0, w, h);
264: }
265: }
266:
267: public void print(Graphics g) {
268: this .isPrinting = true;
269: super .print(g);
270: this .isPrinting = false;
271: }
272:
273: protected void firePropertyChange(String propertyName,
274: Object oldValue, Object newValue) {
275: }
276:
277: public boolean isOpaque() {
278: return true;
279: }
280:
281: public void prepareDisplay(Object value) {
282: if (value == null) {
283: displayValue = null;
284: } else {
285: displayValue = value.toString();
286: }
287:
288: setTooltip(displayValue);
289: }
290:
291: protected boolean checkHighlightExpression() {
292: if (this .filter == null) {
293: return false;
294: }
295: return filter.evaluate(displayValue);
296: }
297:
298: public String getToolTipText() {
299: return this .tooltip;
300: }
301:
302: protected void setTooltip(String tip) {
303: if (tip != null && tip.length() > 0)
304: tooltip = StringUtil.getMaxSubstring(tip, maxTooltipSize);
305: else
306: tooltip = null;
307: }
308:
309: public String getDisplayValue() {
310: return displayValue;
311: }
312:
313: }
|