הדפסה בג'אווה, חלק 1

הקודם 1 2 עמוד 2 עמוד 2 מתוך 2

דגמי טיוח

ישנם שני דגמי הדפסה בג'אווה: Printableעבודות Pageableומשרות.

להדפסה

Printableעבודות הן הפשוטות ביותר מבין שני דגמי ההדפסה. מודל זה משתמש רק באחד PagePainterלכל המסמך. העמודים מוצגים ברצף, החל מדף אפס. כאשר הדף האחרון מודפס, PagePainterעליך להחזיר את NO_SUCH_PAGEהערך. תת-מערכת ההדפסה תבקש תמיד שהיישום יציג את העמודים ברצף. כדוגמה, אם היישום שלך מתבקש להציג את העמודים חמש עד שבע, תת-המערכת להדפיס תבקש את כל העמודים עד העמוד השביעי, אך תדפיס רק את העמודים חמש, שש ושבעה. אם היישום שלך מציג תיבת דו-שיח להדפסה, המספר הכולל של העמודים להדפסה לא יוצג מכיוון שאי אפשר לדעת מראש את מספר העמודים במסמך המשתמש במודל זה.

עמודים

Pageableעבודות מציעות גמישות רבה יותר Printableממשרות, מכיוון שכל עמוד Pageableבעבודה יכול לכלול פריסה שונה. Pageableעבודות משמשות לרוב עם Books, אוסף של דפים שיכולים להיות בפורמטים שונים. אני אסביר את Bookהשיעור עוד רגע.

Pageableעבודה יש את המאפיינים הבאים:

  • לכל עמוד יכול להיות צייר משלו. לדוגמה, יכול להיות שצייר יופעל להדפסת עמוד השער, צייר אחר שידפיס את תוכן העניינים ושלישי שידפיס את המסמך כולו.
  • ניתן להגדיר פורמט עמוד אחר לכל עמוד בספר. בשנת Pageableהעבודה, אתה יכול לערבב עמודים לאורך ולרוחב.
  • תת-מערכת ההדפסה עשויה לבקש מהיישום שלך להדפיס דפים שלא ברצף, ודפים מסוימים עשויים להיות דלגים במידת הצורך. שוב, אינך צריך לדאוג לכך כל עוד תוכל לספק דף כלשהו במסמך שלך על פי דרישה.
  • Pageableהעבודה אינו צריך לדעת כמה דפים קיימים במסמך.

ספרים

חדש גם מכיוון שגרסה 1.2 היא Bookהכיתה. מחלקה זו מאפשרת לך ליצור מסמכים מרובי עמודים. לכל עמוד יכול להיות פורמט משלו וצייר משלו, מה שמעניק לך את הגמישות ליצור מסמכים מתוחכמים. מכיוון Bookשהמחלקה מיישמת את Pageableהממשק, אתה יכול ליישם את Bookהמחלקה שלך כאשר Bookבכיתה הניתנה אין את התכונות הנדרשות לך.

Bookבכיתה מייצגת אוסף של דפים. כאשר הוא נוצר לראשונה, Bookהאובייקט ריק. כדי להוסיף דפים, אתה פשוט משתמש באחת משתי append()השיטות (ראה הסבר שלי על מחלקה זו בסעיף API לפרטים נוספים). הפרמטרים של שיטה זו הם PageFormatהאובייקט המגדיר את המאפיינים הפיזיים של העמוד PagePainterואובייקט המיישם את Printableהממשק. אם אינך יודע את מספר הדפים במסמך שלך, פשוט העביר את UNKNOWN_NUMBER_OF_PAGESהערך append()לשיטה. מערכת המדפסות תמצא באופן אוטומטי את מספר העמודים על ידי קריאה לכל ציירי העמודים בספר עד לקבלת NO_SUCH_PAGEערך.

הגדרת API

תיאוריה ופרקטיקה ייפגשו בחלק זה. בסעיפים הקודמים למדנו על מבנה העמוד, יחידות המדידה והמודלים לעיבוד. בחלק זה נבחן את ממשק ה- API להדפסה של Java.

כל השיעורים הנדרשים להדפסה נמצאים java.awt.printבחבילה, המורכבת משלושה ממשקים וארבעה כיתות. הטבלאות הבאות מגדירות את המחלקות והממשקים של חבילת ההדפסה.

שֵׁם סוּג תיאור
Paper מעמד מחלקה זו מגדירה את המאפיינים הפיזיים של הדף.
PageFormat מעמד PageFormatמגדיר את גודל העמוד וכיווןו. זה גם מגדיר באיזה Paperשימוש בעת עיבוד דף.
PrinterJob מעמד

כיתה זו מנהלת את עבודת ההדפסה. אחריותה כוללת יצירת עבודת הדפסה, הצגת תיבת דו-שיח להדפסה במידת הצורך והדפסת המסמך.

Book מעמד

Bookמייצג מסמך. Bookאובייקט שפועל כאוסף של דפים. דפים הכלולים בתבנית Bookיכולים להיות בעלי תבניות זהות או שונות ויכולים להשתמש בציירים שונים.

Pageable מִמְשָׁק Pageableיישום מייצג קבוצה של דפים תודפס. Pageableהאובייקט מחזיר את המספר הכולל של דפים בערכה וכן PageFormatו Printableעבור דף מסוים. Bookבכיתה מיישמת ממשק זה.
Printable מִמְשָׁק על צייר עמודים ליישם את Printableהממשק. יש רק שיטה אחת בממשק זה print(),.
PrinterGraphics מִמְשָׁק Graphicsהאובייקט מיישם ממשק זה. PrinterGraphicsמספק את getPrinterJob()השיטה להשיג את עבודת המדפסת שמיצרה את תהליך ההדפסה.

ממשק תומך

Pageableהממשק כלל שלוש שיטות:

שם השיטה תיאור
int getNumberOfPages() מחזיר את מספר העמודים במסמך.
PageFormat getPageFormat(int pageIndex) מחזיר את הדפים PageFormatכמפורט על ידי pageIndex.
Printable getPrintable(int pageIndex) מחזיר את Printableהמופע האחראי לעיבוד הדף שצוין על ידי pageIndex.

ממשק להדפסה

Printableממשק תכונות שיטה אחת ושני ערכים:

שֵׁם סוּג תיאור
int print(Graphics graphics, PageFormat pageFormat, int pageIndex) שיטה

מבקש שהגרפיקה תטפל בתבנית העמוד הנתונה, תציג את העמוד שצוין.

NO_SUCH_PAGE ערך זה קבוע. החזר ערך זה כדי לציין שאין עוד דפים להדפסה.
PAGE_EXISTS ערך print()מחזיר השיטה PAGE_EXISTS. זה מציין שהדף שהועבר כפרמטר אליו print()הועבר וקיים.

כל צייר עמודים חייב ליישם את Printableהממשק. מכיוון שיש רק שיטה אחת ליישום, יצירת ציירי עמודים עשויה להיראות קלה. עם זאת, זכור שהקוד שלך חייב להיות מסוגל לעבד כל דף ברצף או לא ברצף.

ישנם שלושה פרמטרים print(), כולל Graphics, שהוא אותו מחלקה המשמש לציור על המסך. מכיוון Graphicsשהמחלקה מיישמת את PrinterGraphicהממשק, אתה יכול להשיג את PrinterJobהעבודה המייצרת את עבודת ההדפסה הזו. אם פריסת העמוד שלך מורכבת ודורשת כמה תכונות ציור מתקדמות, תוכל Graphicsלהעביר את הפרמטר Graphics2Dלאובייקט. לאחר מכן תהיה לך גישה ל- Java 2D API המלא.

לפני שתתחיל להשתמש Graphicsבאובייקט, שים לב שהקואורדינטות אינן מתורגמות לפינה השמאלית העליונה של האזור להדפסה. עיין באיור 3 כדי למצוא את מיקום מקור ברירת המחדל.

(0, 0) מופיע בפינה השמאלית העליונה של שולי המדפסת. כדי להדפיס מלבן בגודל 1 על 1 אינץ ', 1 אינץ' משוליים העליונים והשמאליים, תשתמש בקוד הבא:

1: public int print (Graphics graphics, PageFormat pageFormat, int pageIndex) { 2: Graphics2D graphics2D = (Graphics2D) graphics; 3: Rectangle2D.Double rectangle = new Rectangle2D.Double (); 4: rectangle.setRect (pageFormat.getImageableX () + 72, 5: pageFormat.getImageableY () + 72, 6: 72, 7: 72); 8: graphics2D.draw (rectangle); 9: return (PAGE_EXISTS); }

מהדוגמה הקודמת אנו רואים שעלינו לתרגם ידנית את מקור המלבן כך שהוא מודפס בחלק העליון של האזור להדפסה כמו באיור 1. כדי לפשט את הקוד, נוכל לתרגם את הקואורדינטות פעם אחת ולהשתמש (0, 0 ) כמקור האזור להדפסה. על ידי שינוי הדוגמה הקודמת, אנו מקבלים:

1: public int print (Graphics graphics, PageFormat pageFormat, int pageIndex) { 2: Graphics2D graphics2D = (Graphics2D) graphics; 3: graphics2D.translate (pageFormat.getImageableX (), pageFormat.getImageableY ()); 4: Rectangle2D.Double rectangle = new Rectangle2D.Double (); 5: rectangle.setRect (72, 72, 72, 72); 6: graphics2D.draw (rectangle); 7: return (PAGE_EXISTS); 8: }

Using the translate() method in line 3, we can translate the coordinates and set our origin (0, 0) at the top of the printable area. From this point on, our code will be simplified.

PrinterGraphics interface

The PrinterGraphics interface consists of one method:

Method name Description
PrinterJob getPrinterJob() Returns the PrinterJob for this rendering request and is implemented by the Graphics class

Paper class

Eight methods make up the Paper class:

Method name Description
double getHeight() This method returns the page's physical height in points (1 inch = 72 points). For example, if you are printing on a letter-size page, the return value will be 792 points, or 11 inches.
double getImageableHeight() This method returns the page's imageable height. The imageable height is the height of the print area that you may draw on. See Figure 1 for a graphical view of the imageable area.
double getImageableWidth() This method returns a page's imageable width (the width of the print area that you may draw on). See Figure 1 for a graphical view of the imageable area.
double getImageableX() This method returns the x origin of the imageable area. Since there is no support for margins, the return value represents the left margin.
double getImageableY() This method returns the y origin of the imageable area. The value returned from this method is equivalent to the top margin.
double getWidth() This method returns the page's physical width in points. If you print on a letter-size paper, the width is 8.5 inches, or 612 points.
void setImageableArea(double x, double y, double width, double height) This method sets the imageable area and specifies the margins on the page. Actually, the API provides no method to set the margins explicitly; you have to calculate them yourself.
void setSize(double width, double height) This method sets the physical page size. To define an 8.5-by-11-inch sheet, you would supply 612 and 792 points. Note that the default size is LETTER.

Before we move on to the next section, remember that the Paper class defines the page's physical characteristics. The PageFormat class represents all the page's characteristics, such as page orientation, size, and the paper type. This class is always passed as a parameter to the Printable interface's print() method. Use Paper to obtain the imageable area location, size, and page orientation along with a transformation matrix.

PageFormat class

The PageFormat consists of 12 methods:

Method name Description
double getHeight() This method returns the page's physical height in points (1 inch = 72 points). If your page measures 8.5 by 11 inches, then the return value will be 792 points, or 11 inches.
double getImageableHeight() This method returns the page's imageable height, which is the height of the print area on which you may draw. See Figure 1 for a graphical view of the imageable area.
double getImageableWidth() This method returns the page's imageable width -- the width of the print area on which you may draw. Figure 1 illustrates a graphical view of the imageable area.
double getImageableX() This method returns the x origin of the imageable area.
double getImageableY() This method returns the imageable area's y origin.
double getWidth() This method returns the page's physical width in points. If you print on letter-sized paper, the width is 8.5 inches, or 612 points.
double getHeight() This method returns the page's physical height in points. For example, letter-sized paper is 11 inches in height, or 792 points.
double[] getMatrix() This method returns a transformation matrix that translates user space into the requested page orientation. The return value is in the format required by the AffineTransform constructor.
int getOrientation() This method returns the orientation of the page as either PORTRAIT or LANDSCAPE.
void setOrientation(int orientation) This method sets the orientation of the page, using the constants PORTRAIT and LANDSCAPE.
Paper getPaper() This method returns the Paper object associated with the page format. Refer to the previous section for a description of the Paper class.
void setPaper(Paper paper) This method sets the Paper object that will be used by the PageFormat class. PageFormat must have access to the physical page characteristics to complete this task.

This concludes the description of the page classes. The next class that we will study is the PrinterJob.

PrinterJob class

The PrinterJob class controls the printing process. It can both instantiate and control a print job. Below you will find a definition of the class:

Method name Description
abstract void cancel() This method cancels the current print job. You can validate the cancellation with the isCancel() method.
abstract boolean isCancelled() This method returns true if the job is cancelled.
PageFormat defaultPage() This method returns the default page format for the PrinterJob.
abstract PageFormat defaultPage(PageFormat page) This method clones the PageFormat passed in parameters and modifies the clone to create the default PageFormat.
abstract int getCopies() This method returns the number of copies that the print job will print.
abstract void setCopies(int copies) This method sets the number of copies that the job will print. Note that if you show a print dialog box, users can alter the number of copies (see the pageDialog method).
abstract String getJobName() This method returns the job name.
static PrinterJob getPrinterJob() This method creates and returns a new PrinterJob.
abstract String getUserName() This method returns the user name associated with the print job.
abstract PageFormat pageDialog(PageFormat page) This method displays a dialog that allows the user to modify the PageFormat. The PageFormat, passed in parameters, sets the fields of the dialog. If the user cancels the dialog, then the original PageFormat will be returned. But if the user accepts the parameters, then a new PageFormat will be created and returned. Since it will not show the same parameters on all operating systems, you must be careful when using the pageDialog.
abstract void setPageable(Pageable document) This method queries the document to obtain the total number of pages. The Pageable will also return the PageFormat and the Printable object for each page. See the definition of the Pageable interface for more information.
abstract void setPrintable(Printable painter) This method sets the Painter object that will render the pages to be printed. A Painter object is an object that implements the Printable class and its print() method.
abstract void setPrintable(Printable painter, PageFormat format) This method completes the same tasks as abstract void setPrintable(Printable painter), except that you supply the PageFormat that the Painter will use. As indicated in the definition of the Printable interface, the print() method passes a PageFormat object as the first parameter.
abstract void print() This method prints the document. It actually calls the print() method of the Painter previously assigned to this print job.
abstract void setJobName(String jobName) This method sets the name of the print job.
abstract boolean printDialog() This method displays a print dialog box that allows the user to change the print parameters. Note that this interaction's result will not be returned to your program. Instead, it will be passed to the peer operating system.
abstract PageFormat validatePage(PageFormat page) This method will validate the PageFormat passed in parameters. If the printer cannot use the PageFormat that you supplied, then a new one that conforms to the printer will be returned.

Book class

Seven methods make up the Book class:

>

Method name Description
void append(Printable painter, PageFormat page) This method appends a page to the Book. The painter and the PageFormat for that page are passed in parameters.
void append(Printable painter, PageFormat page, int numPages) This method completes the same tasks as void append(Printable painter, PageFormat page), except that you specify the number of pages.
int getNumberOfPages() This method returns the number of pages currently in the Book.
PageFormat getPageFormat(int pageIndex) This method returns the PageFormat object for a given page.
Printable getPrintable(int pageIndex) This method returns the painter for a given page.
void setPage(int pageIndex, Printable painter, PageFormat page) This method sets the painter and the PageFormat for a given page already in the book.

The printing recipe

The recipe for printing is very simple. First, create a PrinterJob object:

PrinterJob printJob = PrinterJob.getPrinterJob ();

Next, using the setPrintable() method of the PrinterJob, assign the Painter object to the PrinterJob. Note that a Painter object is one that implements the Printable interface.

printJob.setPrintable (Painter);

Or you could set the PageFormat along with the Painter :

printJob.setPrintable (Painter, pageFormat);

Finally, the Painter object must implement the print() method:

public int print (Graphics g, PageFormat pageFormat, int page)

Here the first parameter is the graphics handle that you will use to render the page, the pageFormat is the format that will be used for the current page, and the last parameter is the page number that must be rendered.

That's all there is to it -- for simple printing, that is.

Introduction to the framework

The print framework that we will build in this series will be completely independent of the Java printing API. It will allow for greater flexibility in producing different outputs. Its structure will allow you to create documents, pages, and print objects. You will be able to add print objects to a page while adding pages to a document. By using this structure, you will be able to easily implement export features to PDF or HTML files, or print directly to the printer using the print API. But the main goal of the framework is to simplify the creation of printed documents. When you print using the print API, you only end up with a graphic canvas to draw on. It fails to address the concepts of paragraphs, images, drawings, graphics, tables, or running headers and footers. Because you must compute the (x, y) origin, the width and height of the printable area, setting margins is a chore. Our print framework will address all of these weaknesses.

Conclusion

We covered a lot of ground in this first part. We looked at measurement units, the structure of page, the two rendering models (Pageable and Printable), and Books, and we concluded with a detailed explanation of the printing API. Next month, we'll focus primarily on code, as we will be putting everything into practice. We will also look at the issues that arise when printing on multiple platforms. Looking ahead to Part 3, I will explain in detail the design and implementation of the framework.

ז'אן פייר דובה הוא יועץ Java עצמאי. הוא הקים את Infocom בשנת 1988. מאז, Infocom פיתחה יישומים מותאמים אישית בתחומים הכוללים ייצור, ניהול מסמכים וניהול קווי חשמל בקנה מידה גדול. לז'אן פייר ניסיון רב בתכנות בתחום C, Visual Basic ו- Java; זו האחרונה היא כעת השפה העיקרית עבור כל הפרויקטים החדשים. הוא מקדיש את הסדרה לאמו, שנפטרה בזמן שכתב מאמר זה.

למידע נוסף על נושא זה

  • "הדפסה בג'אווה", ז'אן פייר דובה ( JavaWorld )
  • חלק 1: הכירו את מודל ההדפסה של Java (20 באוקטובר 2000)
  • חלק 2: הדפיסו את העמוד הראשון והציגו מסמכים מורכבים (1 בדצמבר 2000)
  • חלק 3: ז'אן פייר דובה מציג את מסגרת ההדפסה שעובדת על גבי ממשק ה- API של Java Print (5 בינואר 2001)
  • Part 4: Code the print framework
  • (February 2, 2001)
  • Part 5: Discover the print framework's support classes
  • (March 2, 2001)
  • You will find tons of books covering Java AWT, but none will cover this subject to the extent of this book. If you're writing GUIs, you must have this book next to your computer: Graphic Java 2, Mastering The JFCAWT, Volume 1, David M. Geary (Prentice Hall, 1998)

    //www.amazon.com/exec/obidos/ASIN/0130796662/javaworld

  • This book was helpful when Java 1.1 came out, and was the first to talk about printing in Java: Migrating from Java 1.0 to Java 1.1, Daniel I. Joshi and Pavel A. Vorobiev (Ventana Communications Group, 1997)

    //www.amazon.com/exec/obidos/ASIN/1566046866/javaworld

  • ככל הנראה הספר הטוב ביותר ב- Java 2D, ספר זה מכסה את כל ההיבטים של ה- API 2D ומספק גם Graphicsמסגרת להרכבים דו-ממדיים מתקדמים: Java 2D API Graphics, Vincent J. Hardy (Prentice Hall, 1999)

    //www.amazon.com/exec/obidos/ASIN/0130142662/javaworld

  • מבוא מצוין ל- Java 2D API "תחילת העבודה עם Java 2D," ביל דיי ( JavaWorld, יולי, 1998)

    //www.javaworld.com/javaworld/jw-07-1998/jw-07-media.html

סיפור זה, "הדפסה בג'אווה, חלק 1" פורסם במקור בהוצאת JavaWorld.