Optimized Printing in Java by anandjohn.pptx

32
Optimized Printing in Java By Anand John Programmer, Department of Computer Applications Christ College, Rajkot

Transcript of Optimized Printing in Java by anandjohn.pptx

Optimized Printing in Java

Optimized Printing in Java

ByAnand JohnProgrammer,Department of Computer ApplicationsChrist College, Rajkot

Terminology used in printing Definition of a pageGutenberg invented the first printing press. At that time, he had to create a terminology to describe the layout of a page.

Figure 1 Layout of a Landscape view

In Figures 1 and 2, the page is divided into several areas. The printer margins make up the page's periphery. They are printer-dependent and define the minimum area that the printer needs to feed the page. Printer margins are not user-definable.

In Java, you do not need to know these measurements; the API (Application Programming Interface) returns the dimensions of the printable area. Just inside the printer margins are the margins that define the contour of the page. Figure 2 Layout of a Portrait view

The left and right margins extend the length of the page minus the top and bottom printer margins.The gutter on the left side of the page provides an additional margin that is used primarily for binding the pages in a book. The printing API in java itself does not support the gutter. The print API in java also fails to support margins. We can design a print framework that will enable us to provide gutter spacing. Finally, the area in the middle of the page is called the printable area. At first glance, the page layout might look similar to the BorderLayout that we are accustomed to in java. However, in the BorderLayout, both top and bottom components extend the width of the display area, whereas in the physical page layout, the top and bottom margins are contained between the left and right margins.

In Java, when working with the Graphics2D class, it is important to understand the difference between device space and user space. In the device space, you work in pixels using the resolution of the device. A square of 100 pixels by 100 pixels drawn on a device that has a resolution of 1,024 pixels by 768 pixels will not be the same size as it is when rendered on a device that has a resolution of 1,600 pixels by 1,400 pixels. Because the second device features more pixels per inch, the square will appear smaller.

User space, on the other hand, allows us to think in terms of measurement units, regardless of the device's resolution.

When you create a Graphics2D object for a given device (screen or printer), a default transform is generated to map the user space to the device space.

In user space, the default is set to 72 coordinates per inch. Instead of thinking in terms of pixels, you think in terms of units. A 1-by-1-inch square is 72 units by 72 units.

A letter-size page (8.5 by 11 inches) is 612 by 792 points. When using the print API, you must set your mind to work with units because all the classes work in the user space.

A method and system for printing documents based on Java commands. A Java program receives page layout requests and converts the requests into a rasterized image which is transferred to a printer. Page layout can be interactively modified. The Java printer also monitors print requests and is configurable using a World Wide Web interface.The rendering process was not optimized at all. Printing a simple page required a great deal of memory and was very slow.

To simplify the concept, let's say that your program has a contract with the printing subsystem to supply a given page at a given time. The printing subsystem may request that your application render a page more than once, or render pages out of sequence. This model provides several advantages. First, by sending strips of the page instead of the whole page to the printer, it allows the application to print complex documents that would require more printer memory than is available.The application does not have to know how to print each strip; it only needs to know how to render a given page. The API will take care of the rest. In this case, the printing subsystem might request that a page be rendered several times depending on the number of strips required to completely print the page. Second, if the paper tray on a particular printer outputs the pages in reverse order, then your application might be asked to print the document in reverse order, so it will appear in the right order in the output tray.

The print system in Java has two distinct models: the Printable and the Pageable.Though Printable can print simple documents, it features several limitations, the major one being that all pages must share the same format. The Pageable model, on the other hand, offers much more flexibility. It can create multipage documents, with each page formatted differently.

The steps required for printing with the Printable model:

Create a PrinterJob object. This object controls the print process by displaying page and print dialogs, and initiating the print action.

Display the proper dialogs, either print or page dialogs.

Create a class that implements the Printable interface's print() method.

Validate the page number to be rendered.

Render your page using the Graphics parameter.

If the page renders, return the PAGE_EXISTS value; if the page does not render, return the NO_SUCH_PAGE value.

Interface Printablepublic interface PrintableThePrintableinterface is implemented by theprintmethods of the current page painter, which is called by the printing system to render a page. When building aPageable, pairs ofPageFormatinstances and instances that implement this interface are used to describe each page. The instance implementingPrintableis called to print the page's graphics.

APrintable(..)may be set on aPrinterJob. When the client subsequently initiates printing by callingPrinterJob.print(..) control is handed to the printing system until all pages have been printed.

It does this by callingPrintable.print(..)until all pages in the document have been printed. In using thePrintableinterface the printing commits to image the contents of a page whenever requested by the printing system.

You can display either the print or the page dialog. This enables you to create unattended print jobs, an ability that becomes useful when you want to set a server to print documents.With the print dialog box, the user can select a printer and modify its configuration. The user can also set the number of copies to print and select the page range. Using this dialog, you transfer control of the print job to the user. The dialog box provides the only place where the user can decide to proceed with the print job or cancel it.if (printJob.printDialog()) { try { printJob.print(); } catch (Exception PrintException) { PrintException.printStackTrace();}}

The printDialog() method, part of the PrinterJob class, shows the print dialog to the user. This method returns a Boolean value. The print method returns an integer value as shown below:public int print(Graphics g, PageFormat pf, int page_index) throws PrinterException { if (page_index > 0) { return NO_SUCH_PAGE;}Graphics2D g2d = (Graphics2D) g; g2d.translate(pf.getImageableX(), pf.getImageableY()); /* Now we perform our rendering */ g.drawString("Print same like this", 400, 400);return PAGE_EXISTS; }

The second dialog is the page dialog. With this dialog, the user can change the page setup. Figure 2 illustrates an example of a page dialog:Using this dialog, the user can choose all the parameters of the PageFormat object, including the paper size, the paper source, the orientation of the page, and the margins.PageFormat documentPageFormat = new PageFormat (); documentPageFormat = printJob.pageDialog (documentPageFormat); book.append (new Document (), documentPageFormat);

Figure 2

To render attractive text, you must first understand the structure of a font. Characters align along a line called the baseline, which is the vertical point of reference for positioning a font. The ascend is the distance between the baseline and the top of the tallest character in a string. The space between the baseline and a string's lowest glyph is the descend. The leading represents the vertical distance between two characters, and the font height is the ascend plus the leading plus the descend. Finally, we call a string's length the advance. All of these parameters are font dependent, meaning that text rendered using an Arial font will not occupy the same physical space as the same text rendered using a Lucida font.Two styles of fonts are available:Serif fonts feature short lines stemming from and at an angle to the upper and lower ends of a letter. Times New Roman is an example of a serif font.Sans serif fonts do not have any decorative elements. The Arial font is a sans serif font.

Java offers eight default fonts: Serif, Sans Serif, Dialog, Dialog Input, Lucida Sans, Lucida Sans Typewriter, Lucida Bright, and Monospace.Java uses logical font names. These names automatically map to an operating system's fonts.The mapping occurs in the JDK directory's jre/lib/font.properties file.If your application needs access to more fonts, set the java.awt.fonts parameters of the Java command as in java D java.awt.fonts=[fonts directory] ... -- to point to a font directory of Type 1 (Postscript) fonts or True Type fonts. The Java Graphics API supplies many classes that alleviate the task of manipulating fonts.TextLayout offers a great deal of functionality in rendering high quality text. This class can render bidirectional text such as Japanese text, where figures align right to left instead of the North American style, which flows left to right.

NameTypeDescriptionFontClassThe Font class represents an instance of a font face. Use this class to create a new font based on the available fonts on the target system.FontMetricsClass (Abstract)This class contains information about a font and the rendering device. FontMetrics features many utilities, one of which obtains a string's width. Note that this class is abstract; to acquire an instance, you must call Graphics.getFontMetrics(). Use FontMetrics to learn a font's basic metric information, such as its descend, ascend, leading, or advance.FontRenderContextClassThis class provides information about a font related to the rendering device and the rules required to render such a font. Rules define the quality of the rendering.

ExampleFont normalFont = new Font ("serif", Font.PLAIN, 12); Font boldFont = new Font ("serif", Font.BOLD, 12); g2.setFont (normalFont); g2.drawString ("This is a normal font "); g2.setFont (boldFont); g2.drawString ("bold "); g2.setFont (normalFont); g2.drawString ("attribute", 72, 72); If we had to render an entire paragraph! We can simplify this example with an AttributedString object.AttributedString attributedString = new AttributedString ("This is a Bold attribute"); attributedString.addAttribute (TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 11, 14); g2.drawString (attributeString.getIterator (), 72, 72); Output will be: This is a Bold Attribute

Printing imagesPrinting an image is as straightforward as loading it in an Image object and invoking the Graphics2D.drawImage() method.

The process of printing an image is divided into three easy steps.Create a URL that will point to the image you want to print.

Load the image using a MediaTracker class. With this class, you can load GIF, JPEG, and PNG files. If you want to load other image types, use the Advance Imaging API.

Draw the image using the drawImage() method of the Graphics2D class. drawImage() needs six parameters. The first is the Image object to print; the second and third parameters are coordinates for the image's top left position, and the fourth and fifth parameters specify the image's width and height. The last parameter is for the ImageObserver. The Document extends the Component class. All Component classes implement the ImageObserver interface.

Purpose of the print frameworkWe are now able to evaluate its strengths and weaknesses of Java Print API and so we can build a framework on top of it.The print framework or print model will :Be easy to use.Provide the high-level functionality required to efficiently render pages.Loosely couple with the Print API. Because the framework has no direct ties to the Java Print API, it will allow greater support for other output formats, such as PDF or HTML.Provide a structure that clearly defines each component involved in creating documents (document, page, paragraph, and so on).Use an abstract measurement system. Developers will thus be able to work with the measurement system of their choice or even create their own. Provide a print-preview facility. The Java Print API has no support for previewing the output before you print.Support a standard and portable page-setup dialog. The print framework will provide one page-setup dialog that will be uniform across all platforms, but its functionality varies from platform to platform.

Offer export features. Although the framework will support several output formats (PDF, HTML, Postscript).Offer text handling, which is of primary importance. The framework will provide all the functionality needed to effectively render text, including right justification, left justification, full justification, and support for the AttributedString class.Support graphics primitives such as rectangles, circles, and lines.Support GIF and JPEG image types.Support headers and footers. These can be set at the document or the page level, and the first page can feature a different header/footer.Support sticky position, which easily sticks a component to a specific location. Since all print objects are containers, the sticky values would be applied within the boundaries of the parent object.Support dimensions, with which you can set a component's width and/or height to the parent container's width and/or height.Support tables, though their implementation will be limited.

Implement the measurement system classesStart building the framework design by implementing the measurement classes.The PFUnit class forms the heart of the measurement system; only the getPoints() and setPoints() methods are left abstract. Place your code that converts the measurement unit to points in getPoints(), and the code that converts from points to the measurement unit, in the setPoints() method.All the basic math operations have been implemented in PFUnit. The math methods support either a double value or a PFUnit class as their input. When you pass a double value in parameters, the method assumes that the value is in the measurement unit represented by the class. For example, a double value passed to one of the math methods in the PFInchUnit class is assumed to be in inches. PFUnit provides the foundation; by extending PFUnit, you can create custom measurement systems like PFInchUnit and PFCmUnit. In addition, the PFPoint, PFSize, and the PFRectangle represent geometrical coordinates.

The PFPage classThe PFPage class represents a page entity. A document is a collection of pages; a page is a collection of print objects. In the print framework, you must create an instance of PFPage for each page in your document. PFPage uses a Vector object to store print objects and supports several methods of adding and removing print objects.To store page parameters like margins, page size, and page orientation, use a PFPageFormat class, which offers various functionalities. It allows the PFPageSetupDialog to obtain and return the page parameters in one full swoop. If the user selects a different page format, the PFDocument print() method can assign the new parameters using a single line of code. All the PFPrintObject classes render themselves with a Graphics2D object.The getHeader()/getFooter() methods will make the final decision based on the rule: The page header/footer is used if it is not null, else the methods ask PFDocument for a non-null header/footer value.

PFPage classThe PFPage defines a page and acts as a container of PFPrintObject objects. When the print() method invokes, it renders each object in the page. The PFPage class does not store the page parameters directly; it uses a PFPageFormat class for storageUse the PFPageFormat class to set and store the page format data.PFPageFormat computes the page area origin with the getPageAreaOrigin() method, and the page area size using the getPageAreaSize() method. Use getPageFormat() to obtain a java.awt.PageFormat object.Before returning a PageFormat object, getPageFormat() must first evaluate the page orientation and set the page's margins and size accordingly.FPrintObject's rendering process is a bit more complex than PFPage's, because each object must be rendered in relation to its parent object. The parent object can be either the PFPage object onto which the print object was added or another PFPrintObject.

The steps for using the print frameworkCreate a PFDocument objectCreate a PFPage object and add it to the PFDocument classCreate all the print objects that will appear in your page and add them to the PFPage objectInvoke the document's print() method to print itRepeat steps 2 and 3 until all the pages in your document have been created.PFDocument document = new PFDocument (); PFPage page = new PFPage (); PFFrame rectangle = new PFFrame (); document.addPage (page); rectangle.setHeight (new PFInchUnit (5.0)); rectangle.setHorizontalSticky (PFPrintObject.STICKY_LEFT);rectangle.setHorizontalFill (true);rectangle.setFillColor (Color.black); rectangle.setLineColor (Color.red); page.add (rectangle); document.print ();

Printing AWT/Swing componentsBecause visual components rely on layout managers, printing those components can be tricky. You can more easily position and resize an image on a canvas.The component is asked to render itself on the double-buffer image. And finally, the image of the component renders on the page.

Swing Component DemonstrationLink to Printing Jar

JasperReportsOptional Libraries and Tools

There are a number of libraries that are required only if we wish to take advantage of some of JasperReports' features. These optional libraries and their uses are listed next.

Apache ANTJasperReports comes bundled with some custom ANT targets for previewing report designs and for viewing reports serialized in JasperReports' native format. Although not mandatory, it is very helpful to have ANT available to take advantage of these custom targets.We can use JasperReports-specific ANT targets. Therefore, ANT is required when following the examples. ANT can be downloaded from http://ant.apache.org/.

JDT CompilerJDT stands for Java Development Tools. The JDT compiler is the Java compiler included with the Eclipse IDE (Integrated Development Environment). The JDT compiler is needed only when the JasperReports application is running under a Java Runtime Environment (JRE), and not under a full JDK.

JDBC DriverWhen using a JDBC datasource, the appropriate JDBC driver for our specific RDBMS is needed. The following table lists popular relational database systems and the required JAR files to be added to the CLASSPATH (exact file names may vary depending on the version). The names shown in the table reflect the latest stable versions at the time of writing:RDBMSDriver JAR FilesFirebirdfirebirdsql-full.jarHSQLDBhsqldb.jarMySQLmysql-connector-java-3.1.10-bin.jarOracleclasses12dms.jarDB2db2java.zipPostgreSQLpostgresql-8.0-312.jdbc3.jarSQL Servermssqlserver.jarmsbase.jarmsutil.jarSybasej conn3.jar

iText iText is an open-source library for creation and manipulation of PDF files. iText is needed only if you want to export your reports to PDF or RTF format. Version 1.2.2 of the JasperReports project ZIP file includes iText version 1.3.1. The file to be added to your CLASSPATH is itext-1.3.1.jar.iText can be downloaded separately from http://www.lowagie.com/iText/.

JFreeChartJFreeChart is an open-source library for creating professional-looking charts including, but not limited to 2-D and 3-D pie charts, 2-D and 3-D bar charts, and line charts. JFreeChart is needed in our CLASSPATH only if you intend to add charts to your reports. JFreeChart version 1.0 RC1 can be found in the lib directory inside the JasperReports project ZIP file version 1.1. The file to be added to the CLASSPATH is jfreechart-1.0.0-rc1.jar.JFreeChart can be downloaded separately from http://www.jfree.org/jfreechart/.

Thank you