001: /*
002: * The contents of this file are subject to the Mozilla Public License
003: * Version 1.1 (the "License"); you may not use this file except in
004: * compliance with the License. You may obtain a copy of the License at
005: * http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
009: * License for the specific language governing rights and limitations
010: * under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
015: * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
016: *
017: * Contributor(s):
018: * Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
019: *
020: * If you didn't download this code from the following link, you should check
021: * if you aren't using an obsolete version: http://www.isqlviewer.com
022: */
023: package org.isqlviewer.ui.laf;
024:
025: import java.awt.Color;
026: import java.awt.Component;
027: import java.awt.Graphics;
028:
029: import javax.swing.Icon;
030: import javax.swing.JTable;
031: import javax.swing.SwingConstants;
032: import javax.swing.UIManager;
033: import javax.swing.event.ChangeEvent;
034: import javax.swing.event.ListSelectionEvent;
035: import javax.swing.event.TableColumnModelEvent;
036: import javax.swing.event.TableColumnModelListener;
037: import javax.swing.table.DefaultTableCellRenderer;
038: import javax.swing.table.JTableHeader;
039:
040: import org.isqlviewer.swing.table.Sortable;
041:
042: /**
043: * @author Markus A. Kobold <mkobold at sprintpcs dot com>
044: */
045: public class SortableHeaderRenderer extends DefaultTableCellRenderer
046: implements TableColumnModelListener {
047:
048: private static final long serialVersionUID = 1302200480018755232L;
049:
050: public static int SORT_ICON_WIDTH = 4;
051:
052: private int sortedColumn = -1;
053: private String sortedColumnName = null;
054: private boolean sortAsc = false;
055: private int renderColumn = -1;
056:
057: public SortableHeaderRenderer(JTable table) {
058:
059: table.getColumnModel().addColumnModelListener(this );
060: setBorder(UIManager.getBorder("TableHeader.cellBorder"));
061: setHorizontalTextPosition(LEFT);
062: setHorizontalAlignment(CENTER);
063: }
064:
065: @Override
066: public Component getTableCellRendererComponent(JTable table,
067: Object value, boolean isSelected, boolean hasFocus,
068: int row, int column) {
069:
070: if (table != null) {
071: JTableHeader header = table.getTableHeader();
072: if (header != null) {
073: setForeground(header.getForeground());
074: setBackground(header.getBackground());
075: }
076:
077: if (sortedColumnName != null && renderColumn == column) {
078: String tColumn = table.getColumnName(column);
079: if (tColumn != null) {
080: if (tColumn.compareTo(sortedColumnName) == 0)
081: if (sortAsc) {
082: setIcon(new BasicArrowIcon(
083: SwingConstants.SOUTH,
084: SORT_ICON_WIDTH));
085: } else {
086: setIcon(new BasicArrowIcon(
087: SwingConstants.NORTH,
088: SORT_ICON_WIDTH));
089: }
090: } else {
091: setIcon(null);
092: }
093: } else {
094: setIcon(null);
095: }
096:
097: Icon ico = getIcon();
098: if (ico != null) {
099: setSize(getPreferredSize().width + ico.getIconWidth(),
100: getHeight());
101: } else {
102: setSize(getPreferredSize());
103: }
104: setText((value == null) ? "" : value.toString());
105: }
106: return this ;
107: }
108:
109: /**
110: * Tells listeners that the selection model of the TableColumnModel changed.
111: */
112: public void columnSelectionChanged(ListSelectionEvent e) {
113:
114: }
115:
116: /** Tells listeners that a column was moved due to a margin change. */
117: public void columnMarginChanged(ChangeEvent e) {
118:
119: }
120:
121: /** Tells listeners that a column was repositioned. */
122: public void columnMoved(TableColumnModelEvent e) {
123:
124: if (renderColumn == -1)
125: return;
126:
127: int from = e.getFromIndex();
128: int to = e.getToIndex();
129:
130: if (to == from) // actually hasn't finished moving...
131: return;
132:
133: if (to == renderColumn) // another column is moved to this current sorted column
134: renderColumn = from;
135: else if (from == renderColumn)
136: renderColumn = to;
137: }
138:
139: /** Tells listeners that a column was removed from the model. */
140: public void columnRemoved(TableColumnModelEvent e) {
141:
142: }
143:
144: /** Tells listeners that a column was added to the model. */
145: public void columnAdded(TableColumnModelEvent e) {
146:
147: }
148:
149: public boolean isAscending() {
150:
151: return sortAsc;
152: }
153:
154: public int getSortedColumn() {
155:
156: return sortedColumn;
157: }
158:
159: public int getRenderedSortedColumn() {
160:
161: return renderColumn;
162: }
163:
164: public synchronized void setSortedColumn(int column, JTable jTable,
165: boolean asc) {
166:
167: synchronized (this ) {
168: if (column < 0 || !(jTable.getModel() instanceof Sortable)) {
169: sortedColumn = -1;
170: sortedColumnName = null;
171: sortAsc = false;
172: renderColumn = -1;
173: } else {
174: Sortable mdl = (Sortable) jTable.getModel();
175: sortAsc = asc;
176: renderColumn = column;
177: sortedColumnName = jTable.getColumnName(column);
178: sortedColumn = mdl
179: .getIndexOfColumnName(sortedColumnName);
180: }
181: }
182:
183: }
184:
185: public static class BasicArrowIcon implements Icon, SwingConstants {
186:
187: private int direction = NORTH;
188: private int size = 0;
189:
190: public BasicArrowIcon() {
191:
192: this (EAST);
193: }
194:
195: public BasicArrowIcon(int dir) {
196:
197: this (dir, 16);
198: }
199:
200: public BasicArrowIcon(int dir, int size) {
201:
202: this .size = size;
203: direction = dir;
204: }
205:
206: public int getIconHeight() {
207:
208: return size;
209: }
210:
211: public int getIconWidth() {
212:
213: return size;
214: }
215:
216: public void paintIcon(Component c, Graphics g, int x, int y) {
217:
218: Color oldColor = g.getColor();
219: int mid, i, j;
220: boolean isEnabled = c.isEnabled();
221:
222: j = 0;
223: size = Math.max(size, 2);
224: mid = size / 2;
225:
226: g.translate(x, y);
227: if (isEnabled)
228: g.setColor(UIManager.getColor("controlDkShadow"));
229: else
230: g.setColor(UIManager.getColor("controlShadow"));
231:
232: switch (direction) {
233: case NORTH:
234: for (i = 0; i < size; i++) {
235: g.drawLine(mid - i, i, mid + i, i);
236: }
237: if (!isEnabled) {
238: g
239: .setColor(UIManager
240: .getColor("controlLtHighlight"));
241: g.drawLine(mid - i + 2, i, mid + i, i);
242: }
243: break;
244: case SOUTH:
245: if (!isEnabled) {
246: g.translate(1, 1);
247: g
248: .setColor(UIManager
249: .getColor("controlLtHighlight"));
250:
251: for (i = size - 1; i >= 0; i--) {
252: g.drawLine(mid - i, j, mid + i, j);
253: j++;
254: }
255: g.translate(-1, -1);
256: g.setColor(UIManager.getColor("controlShadow"));
257: }
258: j = 0;
259: for (i = size - 1; i >= 0; i--) {
260: g.drawLine(mid - i, j, mid + i, j);
261: j++;
262: }
263: break;
264: case WEST:
265: for (i = 0; i < size; i++) {
266: g.drawLine(i, mid - i, i, mid + i);
267: }
268: if (!isEnabled) {
269: g
270: .setColor(UIManager
271: .getColor("controlLtHighlight"));
272: g.drawLine(i, mid - i + 2, i, mid + i);
273: }
274: break;
275: case EAST:
276: if (!isEnabled) {
277: g.translate(1, 1);
278: g
279: .setColor(UIManager
280: .getColor("controlLtHighlight"));
281: for (i = size - 1; i >= 0; i--) {
282: g.drawLine(j, mid - i, j, mid + i);
283: j++;
284: }
285: g.translate(-1, -1);
286: g.setColor(UIManager.getColor("controlShadow"));
287: }
288: j = 0;
289: for (i = size - 1; i >= 0; i--) {
290: g.drawLine(j, mid - i, j, mid + i);
291: j++;
292: }
293: break;
294: }
295: g.translate(-x, -y);
296: g.setColor(oldColor);
297: }
298:
299: }
300: }
|