001: package org.acm.seguin.pmd.swingui;
002:
003: import org.acm.seguin.pmd.swingui.event.ListenerList;
004: import org.acm.seguin.pmd.swingui.event.TextAnalysisResultsEvent;
005: import org.acm.seguin.pmd.swingui.event.TextAnalysisResultsEventListener;
006:
007: import java.awt.Dimension;
008: import java.awt.Font;
009: import java.awt.FontMetrics;
010: import java.awt.Graphics;
011: import java.awt.PrintJob;
012: import java.awt.Toolkit;
013: import java.text.DateFormat;
014: import java.util.ArrayList;
015: import java.util.Date;
016: import java.util.Iterator;
017: import java.util.List;
018: import java.util.StringTokenizer;
019:
020: /**
021: *
022: * @author Donald A. Leckie
023: * @since January 5, 2003
024: * @version $Revision: 1.1 $, $Date: 2003/07/29 20:51:59 $
025: */
026: class PrintAnalysisResults {
027: private PrintJob m_printJob;
028: private Graphics m_graphics;
029: private int m_printAreaX;
030: private int m_printAreaY;
031: private int m_printAreaWidth;
032: private int m_printAreaHeight;
033: private String m_analysisText;
034: private String m_filePath;
035: private String m_printDate;
036: private int m_pageNumber;
037: private int m_printLineTop;
038: private Font m_font;
039: private FontMetrics m_fontMetrics;
040: private Font m_boldFont;
041: private FontMetrics m_boldFontMetrics;
042: private Font m_exampleFont;
043: private FontMetrics m_exampleFontMetrics;
044: private List m_lineTable;
045: private final String EMPTY_STRING = "";
046: private boolean m_printingExample;
047:
048: /**
049: ***********************************************************************
050: */
051: protected PrintAnalysisResults() {
052: }
053:
054: /**
055: ***********************************************************************
056: */
057: protected void print() {
058: TextAnalysisResultsEventListener textListener = null;
059:
060: try {
061: Toolkit toolkit;
062: PMDViewer viewer;
063: String jobTitle;
064:
065: textListener = new GetAnalysisResults();
066: ListenerList.addListener(textListener);
067: toolkit = Toolkit.getDefaultToolkit();
068: viewer = PMDViewer.getViewer();
069: jobTitle = "Print Analysis Results";
070: m_printJob = toolkit.getPrintJob(viewer, jobTitle, null);
071:
072: if (m_printJob != null) {
073: Dimension pageSize;
074: int resolution;
075: int margin;
076:
077: TextAnalysisResultsEvent.notifyRequestText(this );
078: pageSize = m_printJob.getPageDimension();
079: resolution = m_printJob.getPageResolution();
080: margin = resolution / 2; // 1/2 inch margin
081: m_printAreaX = margin;
082: m_printAreaY = margin;
083: m_printAreaWidth = pageSize.width - margin - margin;
084: m_printAreaHeight = pageSize.height - margin - margin;
085: m_boldFont = new Font("Serif", Font.BOLD, 9);
086: m_boldFontMetrics = PMDViewer.getViewer()
087: .getFontMetrics(m_boldFont);
088: m_font = new Font("Serif", Font.PLAIN, 9);
089: m_fontMetrics = PMDViewer.getViewer().getFontMetrics(
090: m_font);
091: m_exampleFont = new Font("Courier", Font.PLAIN, 9);
092: m_exampleFontMetrics = PMDViewer.getViewer()
093: .getFontMetrics(m_exampleFont);
094:
095: Date date;
096: DateFormat dateFormat;
097:
098: date = new Date();
099: dateFormat = DateFormat.getDateTimeInstance();
100: m_printDate = dateFormat.format(date);
101:
102: buildLineTable();
103: printAnalysisResults();
104: m_lineTable.clear();
105: m_printJob = null;
106: }
107: } finally {
108: ListenerList.removeListener(textListener);
109: }
110: }
111:
112: /**
113: **********************************************************************
114: *
115: */
116: private void buildLineTable() {
117: StringTokenizer parser;
118: PrintLineInfo blankLine;
119:
120: parser = new StringTokenizer(m_analysisText, "\n");
121: m_lineTable = new ArrayList(1000);
122: m_filePath = parser.nextToken();
123: blankLine = new PrintLineInfo();
124: blankLine.m_label = EMPTY_STRING;
125: blankLine.m_data = EMPTY_STRING;
126: blankLine.m_labelFont = m_boldFont;
127: blankLine.m_labelFontMetrics = m_boldFontMetrics;
128: blankLine.m_dataFont = m_font;
129: blankLine.m_dataFontMetrics = m_fontMetrics;
130:
131: while (parser.hasMoreTokens()) {
132: String textLine = parser.nextToken();
133: boolean startingExample = false;
134:
135: if (textLine.startsWith("Example:")) {
136: m_printingExample = true;
137: startingExample = true;
138: } else if (textLine.startsWith("Line:")) {
139: m_printingExample = false;
140: m_lineTable.add(blankLine);
141: m_lineTable.add(blankLine);
142: m_lineTable.add(blankLine);
143: }
144:
145: buildPrintLineInfo(textLine, startingExample);
146: }
147: }
148:
149: /**
150: **********************************************************************
151: *
152: */
153: private void buildPrintLineInfo(String textLine,
154: boolean startingExample) {
155: PrintLineInfo printLineInfo;
156: int index;
157:
158: printLineInfo = new PrintLineInfo();
159: printLineInfo.m_label = EMPTY_STRING;
160: printLineInfo.m_data = textLine;
161: index = textLine.indexOf(':');
162:
163: if (index >= 0) {
164: index++;
165: printLineInfo.m_label = textLine.substring(0, index);
166: printLineInfo.m_data = (index < textLine.length()) ? textLine
167: .substring(index)
168: : EMPTY_STRING;
169: }
170:
171: if (m_printingExample) {
172: printLineInfo.m_dataFont = m_exampleFont;
173: printLineInfo.m_dataFontMetrics = m_exampleFontMetrics;
174: printLineInfo.m_label = "Example: ";
175: } else {
176: printLineInfo.m_dataFont = m_font;
177: printLineInfo.m_dataFontMetrics = m_fontMetrics;
178:
179: }
180:
181: printLineInfo.m_labelFont = m_boldFont;
182: printLineInfo.m_labelFontMetrics = m_boldFontMetrics;
183: printLineInfo.m_labelWidth = printLineInfo.m_labelFontMetrics
184: .stringWidth(printLineInfo.m_label);
185: printLineInfo.m_dataWidth = printLineInfo.m_dataFontMetrics
186: .stringWidth(printLineInfo.m_data);
187: printLineInfo.m_labelX = m_printAreaX;
188: printLineInfo.m_dataX = printLineInfo.m_labelX
189: + printLineInfo.m_labelWidth;
190:
191: if (m_printingExample && (startingExample == false)) {
192: printLineInfo.m_label = EMPTY_STRING;
193: }
194:
195: int dataAreaRight = printLineInfo.m_dataX
196: + printLineInfo.m_dataWidth;
197: int printAreaRight = m_printAreaX + m_printAreaWidth;
198:
199: if (dataAreaRight <= printAreaRight) {
200: m_lineTable.add(printLineInfo);
201: } else {
202: buildPrintLineInfoForMultipleLines(printLineInfo);
203: }
204: }
205:
206: /**
207: **********************************************************************
208: *
209: */
210: private void buildPrintLineInfoForMultipleLines(
211: PrintLineInfo basePrintLineInfo) {
212: char[] data = basePrintLineInfo.m_data.toCharArray();
213: int printAreaRight = m_printAreaX + m_printAreaWidth;
214: int dataAreaWidth = printAreaRight - basePrintLineInfo.m_dataX;
215: StringBuffer buffer = new StringBuffer(500);
216: boolean createPrintLineInfo = false;
217:
218: for (int n = 0; n < data.length; n++) {
219: char theChar = data[n];
220: buffer.append(theChar);
221:
222: if ((theChar == ' ') || (theChar == '\n')) {
223: String textLine = buffer.toString();
224:
225: if (m_fontMetrics.stringWidth(buffer.toString()) >= dataAreaWidth) {
226: for (int n1 = buffer.length() - 1; n1 >= 0; n1--) {
227: if (buffer.charAt(n1) == ' ') {
228: textLine = textLine.substring(0, n1);
229: buffer.delete(0, n1 + 1);
230: break;
231: }
232: }
233:
234: createPrintLineInfo = true;
235: } else if (theChar == '\n') {
236: buffer.setLength(0);
237: createPrintLineInfo = true;
238: }
239:
240: if (createPrintLineInfo) {
241: PrintLineInfo printLineInfo;
242:
243: printLineInfo = new PrintLineInfo();
244: printLineInfo.m_label = basePrintLineInfo.m_label;
245: printLineInfo.m_data = textLine;
246: printLineInfo.m_labelX = basePrintLineInfo.m_labelX;
247: printLineInfo.m_labelWidth = basePrintLineInfo.m_labelWidth;
248: printLineInfo.m_dataX = basePrintLineInfo.m_dataX;
249: printLineInfo.m_dataWidth = basePrintLineInfo.m_dataWidth;
250: printLineInfo.m_labelFont = basePrintLineInfo.m_labelFont;
251: printLineInfo.m_labelFontMetrics = basePrintLineInfo.m_labelFontMetrics;
252: printLineInfo.m_dataFont = basePrintLineInfo.m_dataFont;
253: printLineInfo.m_dataFontMetrics = basePrintLineInfo.m_dataFontMetrics;
254: m_lineTable.add(printLineInfo);
255:
256: // Clear the base label so that it isn't repeated.
257: basePrintLineInfo.m_label = EMPTY_STRING;
258:
259: // Setup for next text line
260: createPrintLineInfo = false;
261: }
262: }
263: }
264:
265: if (buffer.length() > 0) {
266: PrintLineInfo printLineInfo;
267:
268: printLineInfo = new PrintLineInfo();
269: printLineInfo.m_label = basePrintLineInfo.m_label;
270: printLineInfo.m_data = buffer.toString();
271: printLineInfo.m_labelX = basePrintLineInfo.m_labelX;
272: printLineInfo.m_labelWidth = basePrintLineInfo.m_labelWidth;
273: printLineInfo.m_dataX = basePrintLineInfo.m_dataX;
274: printLineInfo.m_dataWidth = basePrintLineInfo.m_dataWidth;
275: printLineInfo.m_labelFont = basePrintLineInfo.m_labelFont;
276: printLineInfo.m_labelFontMetrics = basePrintLineInfo.m_labelFontMetrics;
277: printLineInfo.m_dataFont = basePrintLineInfo.m_dataFont;
278: printLineInfo.m_dataFontMetrics = basePrintLineInfo.m_dataFontMetrics;
279: m_lineTable.add(printLineInfo);
280: }
281: }
282:
283: /**
284: **********************************************************************
285: *
286: */
287: private void printAnalysisResults() {
288: int lineHeight;
289: int printAreaBottom;
290: Iterator lineTableIterator;
291:
292: lineTableIterator = m_lineTable.iterator();
293: m_printLineTop = m_printAreaY + m_printAreaHeight;
294: lineHeight = m_fontMetrics.getHeight();
295: printAreaBottom = m_printAreaY + m_printAreaHeight;
296:
297: while (lineTableIterator.hasNext()) {
298: PrintLineInfo printLineInfo = (PrintLineInfo) lineTableIterator
299: .next();
300:
301: if ((m_printLineTop + lineHeight) > printAreaBottom) {
302: endPage();
303: beginPage();
304: printHeader();
305: }
306:
307: printBody(printLineInfo);
308: }
309:
310: m_printJob.end();
311: }
312:
313: /**
314: **********************************************************************
315: *
316: */
317: private void beginPage() {
318: m_graphics = m_printJob.getGraphics();
319: }
320:
321: /**
322: **********************************************************************
323: *
324: * <file path> Page 1 <print date>
325: */
326: private void printHeader() {
327: int baseline;
328:
329: m_printLineTop = m_printAreaY;
330: baseline = m_printLineTop + m_boldFontMetrics.getAscent();
331: m_graphics.setFont(m_boldFont);
332:
333: //
334: // Draw the file path
335: //
336: int fileNameX = m_printAreaX;
337: int fileNameWidth = m_boldFontMetrics.stringWidth(m_filePath);
338: m_graphics.drawString(m_filePath, fileNameX, baseline);
339:
340: //
341: // Draw the page number
342: //
343: int pageTextWidth;
344: int pageTextX;
345: String pageText;
346:
347: m_pageNumber++;
348: pageText = "Page " + m_pageNumber;
349: pageTextWidth = m_boldFontMetrics.stringWidth(pageText);
350: pageTextX = m_printAreaX + (m_printAreaWidth / 2)
351: - (pageTextWidth / 2);
352:
353: if (pageTextX <= (m_printAreaX + fileNameWidth)) {
354: pageTextX = m_printAreaX + fileNameWidth + 10;
355: }
356:
357: m_graphics.drawString(pageText, pageTextX, baseline);
358:
359: //
360: // Draw the print date
361: //
362: int printDateWidth;
363: int printDateX;
364:
365: printDateWidth = m_boldFontMetrics.stringWidth(m_printDate);
366: printDateX = m_printAreaX + m_printAreaWidth - printDateWidth;
367: m_graphics.drawString(m_printDate, printDateX, baseline);
368:
369: //
370: // Draw single horizontal line with space above and below.
371: //
372: int x1;
373: int x2;
374:
375: m_printLineTop += m_boldFontMetrics.getHeight() + 3;
376: x1 = m_printAreaX;
377: x2 = m_printAreaX + m_printAreaWidth;
378: m_graphics.drawLine(x1, m_printLineTop, x2, m_printLineTop);
379: m_printLineTop += 3;
380: }
381:
382: /**
383: **********************************************************************
384: *
385: * @param printLineInfo
386: */
387: private void printBody(PrintLineInfo printLineInfo) {
388: if ((printLineInfo.m_label.length() > 0)
389: || (printLineInfo.m_data.length() > 0)) {
390: int x;
391: int y;
392: int baseline;
393:
394: baseline = m_printLineTop
395: + printLineInfo.m_labelFontMetrics.getAscent();
396:
397: // Print label
398: if (printLineInfo.m_label.length() > 0) {
399: m_graphics.setFont(printLineInfo.m_labelFont);
400: x = printLineInfo.m_labelX;
401: y = baseline;
402: m_graphics.drawString(printLineInfo.m_label, x, y);
403: }
404:
405: // Print data
406: m_graphics.setFont(printLineInfo.m_dataFont);
407: x = printLineInfo.m_dataX;
408: y = baseline;
409: m_graphics.drawString(printLineInfo.m_data, x, y);
410: }
411:
412: m_printLineTop += printLineInfo.m_dataFontMetrics.getHeight();
413: }
414:
415: /**
416: **********************************************************************
417: *
418: */
419: private void endPage() {
420: m_graphics = null;
421: }
422:
423: /**
424: ***********************************************************************
425: ***********************************************************************
426: ***********************************************************************
427: */
428: private class GetAnalysisResults implements
429: TextAnalysisResultsEventListener {
430:
431: /**
432: ****************************************************************************
433: *
434: * @param event
435: */
436: public void requestTextAnalysisResults(
437: TextAnalysisResultsEvent event) {
438: }
439:
440: /**
441: ****************************************************************************
442: *
443: * @param event
444: */
445: public void returnedTextAnalysisResults(
446: TextAnalysisResultsEvent event) {
447: m_analysisText = event.getText();
448: }
449: }
450:
451: /**
452: ***********************************************************************
453: ***********************************************************************
454: ***********************************************************************
455: */
456: private class PrintLineInfo {
457: public String m_label;
458: public String m_data;
459: public int m_labelWidth;
460: public int m_dataWidth;
461: public int m_labelX;
462: public int m_dataX;
463: public Font m_labelFont;
464: public FontMetrics m_labelFontMetrics;
465: public Font m_dataFont;
466: public FontMetrics m_dataFontMetrics;
467: }
468: }
|