001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.tasklist.ui;
043:
044: import java.awt.Component;
045: import java.awt.Graphics;
046: import java.awt.Point;
047: import java.awt.Rectangle;
048: import javax.swing.JComponent;
049: import javax.swing.plaf.basic.BasicTableUI;
050: import javax.swing.table.JTableHeader;
051: import javax.swing.table.TableCellRenderer;
052: import javax.swing.table.TableColumn;
053: import javax.swing.table.TableColumnModel;
054:
055: /**
056: *
057: * @author S. Aubrecht
058: */
059: class TaskListTableUI extends BasicTableUI {
060:
061: /** Creates a new instance of TaskListTableUI */
062: public TaskListTableUI() {
063: }
064:
065: /** Paint a representation of the <code>table</code> instance
066: * that was set in installUI().
067: *
068: * (copy & paste from BasicTableUI)
069: */
070: public void paint(Graphics g, JComponent c) {
071: Rectangle clip = g.getClipBounds();
072:
073: Rectangle bounds = table.getBounds();
074: // account for the fact that the graphics has already been translated
075: // into the table's bounds
076: bounds.x = bounds.y = 0;
077:
078: if (table.getRowCount() <= 0 || table.getColumnCount() <= 0 ||
079: // this check prevents us from painting the entire table
080: // when the clip doesn't intersect our bounds at all
081: !bounds.intersects(clip)) {
082:
083: return;
084: }
085:
086: Point upperLeft = clip.getLocation();
087: Point lowerRight = new Point(clip.x + clip.width - 1, clip.y
088: + clip.height - 1);
089: int rMin = table.rowAtPoint(upperLeft);
090: int rMax = table.rowAtPoint(lowerRight);
091: // This should never happen (as long as our bounds intersect the clip,
092: // which is why we bail above if that is the case).
093: if (rMin == -1) {
094: rMin = 0;
095: }
096: // If the table does not have enough rows to fill the view we'll get -1.
097: // (We could also get -1 if our bounds don't intersect the clip,
098: // which is why we bail above if that is the case).
099: // Replace this with the index of the last row.
100: if (rMax == -1) {
101: rMax = table.getRowCount() - 1;
102: }
103:
104: boolean ltr = table.getComponentOrientation().isLeftToRight();
105: int cMin = table.columnAtPoint(ltr ? upperLeft : lowerRight);
106: int cMax = table.columnAtPoint(ltr ? lowerRight : upperLeft);
107: // This should never happen.
108: if (cMin == -1) {
109: cMin = 0;
110: }
111: // If the table does not have enough columns to fill the view we'll get -1.
112: // Replace this with the index of the last column.
113: if (cMax == -1) {
114: cMax = table.getColumnCount() - 1;
115: }
116:
117: // Paint the grid.
118: paintGrid(g, rMin, rMax, cMin, cMax);
119:
120: // Paint the cells.
121: paintCells(g, rMin, rMax, cMin, cMax);
122: }
123:
124: /*
125: * Paints the grid lines within <I>aRect</I>, using the grid
126: * color set with <I>setGridColor</I>. Paints vertical lines
127: * if <code>getShowVerticalLines()</code> returns true and paints
128: * horizontal lines if <code>getShowHorizontalLines()</code>
129: * returns true.
130: *
131: * (copy & paste from BasicTableUI)
132: */
133: private void paintGrid(Graphics g, int rMin, int rMax, int cMin,
134: int cMax) {
135: g.setColor(table.getGridColor());
136:
137: Rectangle minCell = table.getCellRect(rMin, cMin, true);
138: Rectangle maxCell = table.getCellRect(rMax, cMax, true);
139: Rectangle damagedArea = minCell.union(maxCell);
140:
141: if (table.getShowHorizontalLines()) {
142: int tableWidth = damagedArea.x + damagedArea.width;
143: int y = damagedArea.y;
144: for (int row = rMin; row <= rMax; row++) {
145: y += table.getRowHeight(row);
146: g.drawLine(damagedArea.x, y - 1, tableWidth - 1, y - 1);
147: }
148: }
149: if (table.getShowVerticalLines()) {
150: TableColumnModel cm = table.getColumnModel();
151: int tableHeight = damagedArea.y + damagedArea.height;
152: int x;
153: if (table.getComponentOrientation().isLeftToRight()) {
154: x = damagedArea.x;
155: for (int column = cMin; column <= cMax; column++) {
156: int w = cm.getColumn(column).getWidth();
157: x += w;
158: g.drawLine(x - 1, 0, x - 1, tableHeight - 1);
159: }
160: } else {
161: x = damagedArea.x + damagedArea.width;
162: for (int column = cMin; column < cMax; column++) {
163: int w = cm.getColumn(column).getWidth();
164: x -= w;
165: g.drawLine(x - 1, 0, x - 1, tableHeight - 1);
166: }
167: x -= cm.getColumn(cMax).getWidth();
168: g.drawLine(x, 0, x, tableHeight - 1);
169: }
170: }
171: }
172:
173: /**
174: * (copy & paste from BasicTableUI)
175: */
176: private int viewIndexForColumn(TableColumn aColumn) {
177: TableColumnModel cm = table.getColumnModel();
178: for (int column = 0; column < cm.getColumnCount(); column++) {
179: if (cm.getColumn(column) == aColumn) {
180: return column;
181: }
182: }
183: return -1;
184: }
185:
186: /**
187: * (copy & paste from BasicTableUI)
188: */
189: private void paintCells(Graphics g, int rMin, int rMax, int cMin,
190: int cMax) {
191: JTableHeader header = table.getTableHeader();
192: TableColumn draggedColumn = (header == null) ? null : header
193: .getDraggedColumn();
194:
195: TableColumnModel cm = table.getColumnModel();
196: int columnMargin = cm.getColumnMargin();
197:
198: Rectangle cellRect;
199: TableColumn aColumn;
200: int columnWidth;
201: if (table.getComponentOrientation().isLeftToRight()) {
202: for (int row = rMin; row <= rMax; row++) {
203: cellRect = table.getCellRect(row, cMin, false);
204: if (isFoldingRow(row)) {
205: //paint the cell across the whole table
206: cellRect.x = 0;
207: cellRect.width = table.getColumnModel()
208: .getTotalColumnWidth()
209: - columnMargin;
210: paintCell(g, cellRect, row, 0);
211: } else {
212: for (int column = cMin; column <= cMax; column++) {
213: aColumn = cm.getColumn(column);
214: columnWidth = aColumn.getWidth();
215: cellRect.width = columnWidth - columnMargin;
216: if (aColumn != draggedColumn) {
217: paintCell(g, cellRect, row, column);
218: }
219: cellRect.x += columnWidth;
220: }
221: }
222: }
223: } else {
224: for (int row = rMin; row <= rMax; row++) {
225: cellRect = table.getCellRect(row, cMin, false);
226: if (isFoldingRow(row)) {
227: //paint the cell across the whole table
228: cellRect.x = 0;
229: cellRect.width = table.getColumnModel()
230: .getTotalColumnWidth()
231: - columnMargin;
232: paintCell(g, cellRect, row, 0);
233: } else {
234: aColumn = cm.getColumn(cMin);
235: if (aColumn != draggedColumn) {
236: columnWidth = aColumn.getWidth();
237: cellRect.width = columnWidth - columnMargin;
238: paintCell(g, cellRect, row, cMin);
239: }
240: for (int column = cMin + 1; column <= cMax; column++) {
241: aColumn = cm.getColumn(column);
242: columnWidth = aColumn.getWidth();
243: cellRect.width = columnWidth - columnMargin;
244: cellRect.x -= columnWidth;
245: if (aColumn != draggedColumn) {
246: paintCell(g, cellRect, row, column);
247: }
248: }
249: }
250: }
251: }
252:
253: // Paint the dragged column if we are dragging.
254: if (draggedColumn != null) {
255: paintDraggedArea(g, rMin, rMax, draggedColumn, header
256: .getDraggedDistance());
257: }
258:
259: // Remove any renderers that may be left in the rendererPane.
260: rendererPane.removeAll();
261: }
262:
263: /**
264: * (copy & paste from BasicTableUI)
265: */
266: private void paintDraggedArea(Graphics g, int rMin, int rMax,
267: TableColumn draggedColumn, int distance) {
268: int draggedColumnIndex = viewIndexForColumn(draggedColumn);
269:
270: Rectangle minCell = table.getCellRect(rMin, draggedColumnIndex,
271: true);
272: Rectangle maxCell = table.getCellRect(rMax, draggedColumnIndex,
273: true);
274:
275: Rectangle vacatedColumnRect = minCell.union(maxCell);
276:
277: // Paint a gray well in place of the moving column.
278: g.setColor(table.getParent().getBackground());
279: g.fillRect(vacatedColumnRect.x, vacatedColumnRect.y,
280: vacatedColumnRect.width, vacatedColumnRect.height);
281:
282: // Move to the where the cell has been dragged.
283: vacatedColumnRect.x += distance;
284:
285: // Fill the background.
286: g.setColor(table.getBackground());
287: g.fillRect(vacatedColumnRect.x, vacatedColumnRect.y,
288: vacatedColumnRect.width, vacatedColumnRect.height);
289:
290: // Paint the vertical grid lines if necessary.
291: if (table.getShowVerticalLines()) {
292: g.setColor(table.getGridColor());
293: int x1 = vacatedColumnRect.x;
294: int y1 = vacatedColumnRect.y;
295: int x2 = x1 + vacatedColumnRect.width - 1;
296: int y2 = y1 + vacatedColumnRect.height - 1;
297: // Left
298: g.drawLine(x1 - 1, y1, x1 - 1, y2);
299: // Right
300: g.drawLine(x2, y1, x2, y2);
301: }
302:
303: for (int row = rMin; row <= rMax; row++) {
304: // Render the cell value
305: Rectangle r = table.getCellRect(row, draggedColumnIndex,
306: false);
307: r.x += distance;
308: paintCell(g, r, row, draggedColumnIndex);
309:
310: // Paint the (lower) horizontal grid line if necessary.
311: if (table.getShowHorizontalLines()) {
312: g.setColor(table.getGridColor());
313: Rectangle rcr = table.getCellRect(row,
314: draggedColumnIndex, true);
315: rcr.x += distance;
316: int x1 = rcr.x;
317: int y1 = rcr.y;
318: int x2 = x1 + rcr.width - 1;
319: int y2 = y1 + rcr.height - 1;
320: g.drawLine(x1, y2, x2, y2);
321: }
322: }
323: }
324:
325: /**
326: * (copy & paste from BasicTableUI)
327: */
328: private void paintCell(Graphics g, Rectangle cellRect, int row,
329: int column) {
330: if (table.isEditing() && table.getEditingRow() == row
331: && table.getEditingColumn() == column) {
332: Component component = table.getEditorComponent();
333: component.setBounds(cellRect);
334: component.validate();
335: } else {
336: TableCellRenderer renderer = table.getCellRenderer(row,
337: column);
338: Component component = table.prepareRenderer(renderer, row,
339: column);
340: rendererPane.paintComponent(g, component, table,
341: cellRect.x, cellRect.y, cellRect.width,
342: cellRect.height, true);
343: }
344: }
345:
346: private boolean isFoldingRow(int row) {
347: boolean res = false;
348: if (table.getModel() instanceof FoldingTaskListModel) {
349: res = ((FoldingTaskListModel) table.getModel())
350: .isGroupRow(row);
351: }
352: return res;
353: }
354: }
|