001: /*
002: * TablePrintPage.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.print;
013:
014: import java.awt.BasicStroke;
015: import java.awt.Color;
016: import java.awt.Component;
017: import java.awt.Font;
018: import java.awt.FontMetrics;
019: import java.awt.Graphics2D;
020: import java.awt.Rectangle;
021: import java.awt.Stroke;
022: import java.awt.geom.AffineTransform;
023: import javax.swing.Icon;
024:
025: import javax.swing.JTable;
026: import javax.swing.SwingConstants;
027: import javax.swing.SwingUtilities;
028: import javax.swing.table.TableCellRenderer;
029: import javax.swing.table.TableColumnModel;
030: import workbench.gui.renderer.WbRenderer;
031:
032: /**
033: * This class is responsible for keeping a page definition while printing a JTable.
034: * When printing this page, the TablePrintPage assumes that the clipping is set in
035: * a way that it can start printing at 0,0 and can print over the whole Graphics object
036: * This means the caller needs to set the margins according to the page layout.
037: * It is also not checked if the definition actually fits on the graphics context
038: * this calculation needs to be done prior to creating the TablePrintPages
039: *
040: * @see TablePrinter
041: * @author support@sql-workbench.net
042: */
043: public class TablePrintPage {
044:
045: private JTable table;
046: private int startRow;
047: private int endRow;
048: private int startCol;
049: private int endCol;
050: private int[] colWidth;
051: private Font printFont;
052: private int pageNumDown = -1;
053: private int pageNumAcross = -1;
054: private int pageIndex;
055: private int lineSpacing;
056: private int colSpacing;
057: private String[] colHeaders;
058:
059: public TablePrintPage(JTable source, int startRow, int endRow,
060: int startColumn, int endColumn) {
061: this (source, startRow, endRow, startColumn, endColumn, null);
062: }
063:
064: public TablePrintPage(JTable source, int startRow, int endRow,
065: int startColumn, int endColumn, int[] width) {
066: this .table = source;
067: this .startRow = startRow;
068: this .endRow = endRow;
069: this .startCol = startColumn;
070: this .endCol = endColumn;
071: this .colWidth = width;
072: }
073:
074: public void setFont(Font aFont) {
075: this .printFont = aFont;
076: }
077:
078: public Font getFont() {
079: return this .printFont;
080: }
081:
082: public void setPageNumberAcross(int aNum) {
083: this .pageNumAcross = aNum;
084: }
085:
086: public int getPageNumberAcross() {
087: return this .pageNumAcross;
088: }
089:
090: public void setPageNumberDown(int aNum) {
091: this .pageNumDown = aNum;
092: }
093:
094: public int getPageNumberDown() {
095: return this .pageNumDown;
096: }
097:
098: public void setPageIndex(int aNum) {
099: this .pageIndex = aNum;
100: }
101:
102: public int getPageIndex() {
103: return this .pageIndex;
104: }
105:
106: public void setColumnHeaders(String[] headers) {
107: this .colHeaders = headers;
108: }
109:
110: public void setColumnWidths(int[] widths) {
111: this .colWidth = widths;
112: }
113:
114: public String toString() {
115: return "Page V:" + this .pageNumDown + ", H:"
116: + this .pageNumAcross + ", from row " + this .startRow
117: + " to " + this .endRow + ", from column "
118: + this .startCol + " to " + this .endCol;
119: }
120:
121: public void setSpacing(int line, int column) {
122: this .lineSpacing = line;
123: this .colSpacing = column;
124: }
125:
126: private void calculateColWidth() {
127: TableColumnModel model = this .table.getColumnModel();
128: int colCount = model.getColumnCount();
129: this .colWidth = new int[colCount];
130: for (int col = 0; col < colCount; col++) {
131: this .colWidth[col] = model.getColumn(col).getWidth();
132: }
133: }
134:
135: public void print(Graphics2D pg) {
136: Font dataFont = this .printFont;
137: if (dataFont == null)
138: dataFont = this .table.getFont();
139:
140: if (this .colWidth == null) {
141: this .calculateColWidth();
142: }
143:
144: Font headerFont = dataFont.deriveFont(Font.BOLD);
145: FontMetrics fm = pg.getFontMetrics(headerFont);
146: int lineHeight = fm.getHeight();
147:
148: AffineTransform oldTransform = pg.getTransform();
149:
150: pg.setFont(headerFont);
151: pg.setColor(Color.BLACK);
152:
153: int x = 0;
154: int y = 0;
155: pg.translate(0, lineHeight);
156: for (int col = this .startCol; col <= this .endCol; col++) {
157: if (this .colHeaders[col] != null) {
158: pg.drawString(this .colHeaders[col], x, 0);
159: }
160: x += this .colWidth[col] + this .colSpacing;
161: }
162:
163: Stroke s = pg.getStroke();
164: pg.setStroke(new BasicStroke(0.3f));
165: pg.drawLine(0, 1, x, 1);
166: if (s != null)
167: pg.setStroke(s);
168: fm = pg.getFontMetrics(dataFont);
169: lineHeight = fm.getHeight();
170:
171: pg.setTransform(oldTransform);
172: y += (lineHeight + lineSpacing);
173: pg.translate(0, y);
174: pg.setFont(dataFont);
175:
176: Rectangle paintIconR = new Rectangle();
177: Rectangle paintTextR = new Rectangle();
178: Rectangle paintViewR = new Rectangle();
179:
180: for (int row = this .startRow; row <= this .endRow; row++) {
181: int cx = 0;
182: for (int col = this .startCol; col <= this .endCol; col++) {
183: Object value = this .table.getValueAt(row, col);
184: if (value == null)
185: continue;
186: TableCellRenderer rend = table
187: .getCellRenderer(row, col);
188: Component c = rend.getTableCellRendererComponent(table,
189: value, false, false, row, col);
190: if (rend instanceof WbRenderer) {
191: WbRenderer wb = (WbRenderer) rend;
192:
193: // Clip the value returned by the renderer
194: // according to the current column's width
195: String data = wb.getDisplayValue();
196:
197: paintViewR.x = 0;
198: paintViewR.y = 0;
199: paintViewR.width = colWidth[col];
200: paintViewR.height = lineHeight;
201:
202: paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
203: paintTextR.x = paintTextR.y = paintTextR.width = paintTextR.height = 0;
204:
205: String display = SwingUtilities
206: .layoutCompoundLabel(fm, data, (Icon) null,
207: SwingConstants.TOP, wb
208: .getHorizontalAlignment(),
209: SwingConstants.TOP,
210: SwingConstants.RIGHT, paintViewR,
211: paintIconR, paintTextR, 0);
212:
213: pg.drawString(display, cx + paintTextR.x,
214: lineHeight);
215:
216: cx += this .colWidth[col] + colSpacing;
217: } else {
218: c.setSize(this .colWidth[col], lineHeight);
219: c.print(pg);
220: pg.translate(this .colWidth[col] + colSpacing, 0);
221: }
222: }
223: pg.setTransform(oldTransform);
224: y += (lineHeight + lineSpacing);
225: pg.translate(0, y);
226: }
227: }
228: }
|