1 9 package bluej.editor.moe; 10 11 import java.awt.Color ; 12 import java.awt.print.*; 13 import java.awt.Graphics ; 14 import java.awt.Font ; 15 import java.awt.FontMetrics ; 16 import java.awt.print.PrinterJob ; 17 import javax.swing.text.*; 18 19 import java.util.*; 20 import java.text.DateFormat ; 21 22 import bluej.utility.Debug; 23 import bluej.utility.Utility; 24 import bluej.Config; 25 26 27 34 public class MoePrinter 35 { 36 37 static final String CONTINUED_LABEL = Config.getString("editor.printer.continued"); 38 private final int HEADER_SPACE = 30; 39 private final int FOOTER_SPACE = 20; 40 private final int PADDING = 5; 41 private final char TAB_CHAR = '\t'; 42 43 private Book pages = new Book(); 45 private static int titleFontSize = Config.getDefaultPropInteger("bluej.fontsize.printTitle", 14); 46 private static int footerFontSize = Config.getDefaultPropInteger("bluej.fontsize.printInfo", 10); 47 private static Font titleFont = new Font ("SansSerif", Font.BOLD, titleFontSize); 48 private static Font smallTitleFont = new Font ("SansSerif", Font.BOLD, 10); 49 private static Font footerFont = new Font ("SansSerif", Font.ITALIC, 9); 50 51 private String className; 52 private int tabSize = Config.getPropInteger("bluej.editor.tabsize", 4); 53 54 57 public MoePrinter() 58 { 59 } 61 62 68 public boolean printDocument(PrinterJob printJob, PlainDocument document, String className, 69 Font font, PageFormat format) 70 { 71 List lines = new ArrayList(); 72 73 this.className = className; 74 Integer tabSizeAsInteger = (Integer )document.getProperty(PlainDocument.tabSizeAttribute); 76 if(tabSizeAsInteger != null) 77 tabSize = tabSizeAsInteger.intValue(); 78 79 try{ 80 document.readLock(); 83 84 Element root = document.getDefaultRootElement(); 86 int count = root.getElementCount(); 88 Segment segment = new Segment(); 89 for (int i = 0; i < count; i++) { 91 Element lineElement = (Element)root.getElement(i); 92 try { 93 document.getText(lineElement.getStartOffset(), 94 lineElement.getEndOffset() - lineElement.getStartOffset(), 95 segment); 96 lines.add(removeNewLines(segment.toString())); 97 } catch(BadLocationException ble) { 98 Debug.reportError("Exception thrown accessing document text: " + ble); 99 } 100 } 101 } 102 finally { 104 document.readUnlock(); 105 } 106 107 return printText(printJob, lines, font, format); 108 } 109 110 111 116 private String removeNewLines(String line) 117 { 118 int length = line.length(); 119 char lastChar = (length > 0 ? line.charAt(line.length()-1) : ' '); 120 121 while((lastChar == '\n') || (lastChar == '\r')) { 122 123 line = line.substring(0, line.length()-1); 124 length = line.length(); 125 lastChar = (length > 0 ? line.charAt(line.length()-1) : ' '); 126 } 127 return line; 128 } 129 130 131 137 private synchronized boolean printText(PrinterJob job, List text, Font font, PageFormat format) 138 { 139 try { 140 pages = paginateText(text, format, font); 141 142 job.setPageable(pages); 145 job.print(); 146 147 return true; 148 } 149 catch (Exception e) { 150 Debug.reportError("Exception thrown during printing: " + e); 152 e.printStackTrace(); 153 return false; 154 } 155 } 156 157 158 162 private Book paginateText(List text, PageFormat pageFormat, Font font) 163 { 164 Book book = new Book(); 165 int currentLine = 0; int pageNum = 1; 168 int height = (int)pageFormat.getImageableHeight() - (HEADER_SPACE + FOOTER_SPACE); 170 171 int linesPerPage = height / (font.getSize() + 2); 173 wrapLines(text, pageFormat, font); 174 175 int numberOfPages = ((int)(text.size() / linesPerPage)) + 1; 177 178 List pageText; 180 ListIterator li = text.listIterator(); 181 while ( pageNum <= numberOfPages) { 182 pageText = new ArrayList(); 183 184 for (int lineCount = 0; li.hasNext() && lineCount < linesPerPage; lineCount++) { 185 pageText.add(li.next()); 186 currentLine++; } 188 189 book.append(new MoePage(pageText, font), pageFormat); 191 pageNum++; } 193 return book; } 195 196 197 203 private void wrapLines(List text, PageFormat format, Font font) 204 { 205 StyleContext context = new StyleContext(); 208 FontMetrics fontMetrics = context.getFontMetrics(font); 209 int maxWidth = (int)format.getImageableWidth() - (PADDING * 2); 210 int fontWidth = fontMetrics.charWidth('m'); 211 int chars = maxWidth / fontWidth; 212 213 for(ListIterator li = text.listIterator(); li.hasNext(); ) { 214 String currentLine = Utility.convertTabsToSpaces((String )li.next(), tabSize); 215 li.set(currentLine); 216 int currentLineLength = currentLine.length(); 217 int width = fontMetrics.stringWidth(currentLine); 218 219 if(width > maxWidth) { 221 int indexOfLine = li.previousIndex(); 222 li.remove(); 224 double iterations = (currentLineLength / chars) + 1; 225 for(int begin = 0, end = 0; iterations > 0; iterations--, begin += chars) { 226 if(begin + chars < currentLineLength) 227 end = begin + chars; 228 else 229 end = currentLineLength; 230 String newSubString = currentLine.substring(begin, end); 231 if(newSubString.length() != 0) 232 li.add(newSubString); 233 } 234 } 235 } 236 } 237 238 239 243 class MoePage implements Printable 244 { 245 private List text; private Font font; 247 248 MoePage(List text, Font font) 249 { 250 this.text = text; this.font = font; } 253 254 258 public int print(Graphics g, PageFormat pageFormat, int pageIndex) throws PrinterException 259 { 260 int position; 262 g.setFont(this.font); g.setColor(Color.black); 265 int xPosition = (int)pageFormat.getImageableX(); 267 int yPosition = (int)pageFormat.getImageableY(); 268 int width = (int)pageFormat.getImageableWidth(); 269 int height = (int)pageFormat.getImageableHeight(); 270 271 printHeader(g, pageIndex, xPosition, yPosition, width, HEADER_SPACE); 273 274 int textYPosition = yPosition + HEADER_SPACE; 276 int textXPosition = xPosition + PADDING; 277 g.drawRect(xPosition, textYPosition, width, height - (HEADER_SPACE + FOOTER_SPACE)); 278 for(ListIterator li = text.listIterator(); li.hasNext(); ) { 280 position = textYPosition + (this.font.getSize() + 2) * (li.nextIndex() + 1); 281 String line = (String )li.next(); 282 if(line.length() == 0) line = " "; g.drawString(line, textXPosition, position); 285 } 286 287 int footerYPosition = yPosition + height - FOOTER_SPACE; 289 printFooter(g, xPosition, footerYPosition, width, FOOTER_SPACE); 290 291 return Printable.PAGE_EXISTS; } 293 294 297 private void printHeader(Graphics g, int pageIndex, int xPos, int yPos, int width, int height) 298 { 299 g.setColor(Color.lightGray); 301 g.fillRect(xPos, yPos, width, height); 302 g.setColor(Color.black); g.drawRect(xPos, yPos, width, height); 304 int titleYPos = yPos + HEADER_SPACE - this.font.getSize() + 2; 305 Font currentFont = null; 306 String title = "Class " + className; 307 308 if(pageIndex == 0) 311 g.setFont(titleFont); 312 else { 313 if(!"".equals(CONTINUED_LABEL) 315 && !"editor.printer.continued".equals(CONTINUED_LABEL)) 316 title = title + " (" + CONTINUED_LABEL + ")"; 317 g.setFont(smallTitleFont); 318 } 319 g.drawString(title, xPos + PADDING, titleYPos); 321 322 g.setFont(smallTitleFont); 324 FontMetrics pfm = g.getFontMetrics(smallTitleFont); 325 String pageInfo = (pageIndex + 1) + "/" + pages.getNumberOfPages(); 327 int pageInfoX = xPos + width - PADDING - pfm.stringWidth(pageInfo); 328 g.drawString(pageInfo, pageInfoX, titleYPos); 329 g.setFont(font); 330 331 } 332 333 336 private void printFooter(Graphics g, int xPos, int yPos, int width, int height) 337 { 338 g.setFont(footerFont); 340 FontMetrics pfm = g.getFontMetrics(footerFont); 341 int footerTextYPos = yPos + FOOTER_SPACE - this.font.getSize() + 2; 342 343 346 Date today = new Date(); 348 DateFormat dateFormat = DateFormat.getDateTimeInstance(); 349 String date = dateFormat.format(today); 350 int pageInfoX = xPos + width - PADDING - pfm.stringWidth(date); 351 g.drawString(date, pageInfoX, footerTextYPos); 352 g.setFont(font); 354 355 } 356 357 } 358 } 359 360 361 362 | Popular Tags |