|
JComponentPrinter |
|
1 /* 2 * Copyright (c) 1998-2001, The University of Sheffield. 3 * 4 * This file is part of GATE (see http://gate.ac.uk/), and is free 5 * software, licenced under the GNU Library General Public License, 6 * Version 2, June 1991 (in the distribution as file licence.html, 7 * and also available at http://gate.ac.uk/gate/licence.html). 8 * 9 * Valentin Tablan 07/12/2001 10 * 11 * $Id: JComponentPrinter.java,v 1.3 2001/12/18 18:00:34 valyt Exp $ 12 * 13 */ 14 package gate.print; 15 16 import java.awt.*; 17 import java.awt.print.*; 18 import javax.swing.*; 19 import javax.swing.text.*; 20 21 import gate.event.*; 22 import gate.util.*; 23 import gate.gui.MainFrame; 24 25 26 /** 27 * Will scale the component so it fits on a page horizontally 28 */ 29 public class JComponentPrinter implements Pageable{ 30 31 public JComponentPrinter(JComponent component, PageFormat format){ 32 this.component = component; 33 this.pageFormat = format; 34 //find the scale factor; we will not enlarge as it would look ugly 35 Rectangle componentBounds = component.getBounds(null); 36 scaleFactor = Math.min(format.getImageableWidth() /componentBounds.width, 37 1); 38 39 //calculate the pages count 40 pageCount = (int)((componentBounds.height * scaleFactor + 41 pageFormat.getImageableHeight() - 1) / 42 pageFormat.getImageableHeight()); 43 } 44 45 /** 46 * Returns the number of pages over which the canvas 47 * will be drawn. 48 */ 49 public int getNumberOfPages() { 50 return pageCount; 51 } 52 53 54 /** 55 * Returns the PageFormat of the page specified by 56 * pageIndex. The PageFormat is the same for all pages. 57 * 58 * @param pageIndex the zero based index of the page whose 59 * PageFormat is being requested 60 * @return the PageFormat describing the size and 61 * orientation. 62 * @exception IndexOutOfBoundsException 63 * the Pageable does not contain the requested 64 * page. 65 */ 66 public PageFormat getPageFormat(int pageIndex) 67 throws IndexOutOfBoundsException { 68 if (pageIndex >= pageCount) throw new IndexOutOfBoundsException(); 69 return pageFormat; 70 } 71 72 73 /** 74 * Returns the <code>Printable</code> instance responsible for 75 * rendering the page specified by <code>pageIndex</code>. 76 * 77 * @param pageIndex the zero based index of the page whose 78 * Printable is being requested 79 * @return the Printable that renders the page. 80 * @exception IndexOutOfBoundsException 81 * the Pageable does not contain the requested 82 * page. 83 */ 84 public Printable getPrintable(int pageIndex) 85 throws IndexOutOfBoundsException { 86 if (pageIndex >= pageCount)throw new IndexOutOfBoundsException(); 87 88 double originY = pageIndex * pageFormat.getImageableHeight() / scaleFactor; 89 if(component instanceof JTextComponent){ 90 JTextComponent tComp = (JTextComponent)component; 91 //move the origin up towards the first inter-row space 92 int location = tComp.viewToModel(new Point(0, (int)originY)); 93 try{ 94 Rectangle rect = tComp.modelToView(location); 95 originY = rect.y + rect.height - 1; 96 }catch(BadLocationException ble){ 97 ble.printStackTrace(Err.getPrintWriter()); 98 } 99 } 100 101 return new TranslatedPrintable(originY); 102 } 103 104 105 /** 106 * This inner class's sole responsibility is to translate 107 * the coordinate system before invoking a canvas's 108 * painter. The coordinate system is translated in order 109 * to get the desired portion of a canvas to line up with 110 * the top of a page. 111 */ 112 public class TranslatedPrintable implements Printable { 113 public TranslatedPrintable(double originY){ 114 this.originY = originY; 115 } 116 117 /** 118 * Prints the page at the specified index into the specified 119 * {@link Graphics} context in the specified 120 * format. A PrinterJob calls the 121 * Printableinterface to request that a page be 122 * rendered into the context specified by 123 * graphics. The format of the page to be drawn is 124 * specified by pageFormat. The zero based index 125 * of the requested page is specified by pageIndex. 126 * If the requested page does not exist then this method returns 127 * NO_SUCH_PAGE; otherwise PAGE_EXISTS is returned. 128 * The Graphics class or subclass implements the 129 * {@link PrinterGraphics} interface to provide additional 130 * information. If the Printable object 131 * aborts the print job then it throws a {@link PrinterException}. 132 * @param graphics the context into which the page is drawn 133 * @param pageFormat the size and orientation of the page being drawn 134 * @param pageIndex the zero based index of the page to be drawn 135 * @return PAGE_EXISTS if the page is rendered successfully 136 * or NO_SUCH_PAGE if pageIndex specifies a 137 * non-existent page. 138 * @exception java.awt.print.PrinterException 139 * thrown when the print job is terminated. 140 */ 141 public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) 142 throws PrinterException { 143 144 Rectangle componentBounds = component.getBounds(null); 145 Graphics2D g2 = (Graphics2D) graphics; 146 g2.translate(pageFormat.getImageableX() - componentBounds.x, 147 pageFormat.getImageableY() - originY - componentBounds.y); 148 g2.scale(scaleFactor, scaleFactor); 149 150 if(component instanceof JTextComponent){ 151 JTextComponent tComp = (JTextComponent)component; 152 double nextOriginY = (pageIndex + 1) * pageFormat.getImageableHeight() / 153 scaleFactor; 154 int location = tComp.viewToModel(new Point(0, (int)nextOriginY)); 155 try{ 156 Rectangle rect = tComp.modelToView(location); 157 nextOriginY = rect.y; 158 }catch(BadLocationException ble){ 159 ble.printStackTrace(Err.getPrintWriter()); 160 } 161 Rectangle clip = g2.getClip().getBounds(); 162 clip.setSize((int)clip.getWidth(), (int)(nextOriginY - originY) - 1); 163 g2.setClip(clip); 164 } 165 166 boolean wasBuffered = component.isDoubleBuffered(); 167 component.paint(g2); 168 component.setDoubleBuffered(wasBuffered); 169 170 //fire the events 171 StatusListener sListener = (StatusListener)MainFrame.getListeners(). 172 get("gate.event.StatusListener"); 173 if(sListener != null){ 174 sListener.statusChanged("Printing page " + (pageIndex + 1) + 175 "/" + pageCount); 176 } 177 178 return PAGE_EXISTS; 179 } 180 181 double originY; 182 } 183 184 185 JComponent component; 186 PageFormat pageFormat; 187 int pageCount; 188 double scaleFactor; 189 }
|
JComponentPrinter |
|