Learn how to use the Print Service API

Source: Internet
Author: User

Java has developed rapidly in various aspects since its publication, but printing and output have always been the weakest aspect of Java. In fact, Java does not support any printing function. Java1.1 contains a class called printjob in the Java. AWT package, but the printing function provided by this class is very rough and unreliable. When java1.2 came out, it designed a complete and independent printer System (called java2d printing API) Around printerjob, and defined some new classes and interfaces in the Java. AWT. Print package. These make the printjob-based printer (AWT printing) basically obsolete, although printjob has never been attacked and at least in this article is still a class that provides technology.

In j2se1.3, some additional changes occur when printjob functions are extended to setting project and page attributes by using the jobattributes and pageattributes classes in the Java. AWT package. With the release of j2se1.3, the printing function has been improved. However, there are still some problems when using these two completely different printer systems. For example, the two mechanisms use an interface of the Java. AWT. graphics class to display the printed content, which means that all the items to be printed must be represented by an image. In addition, the complete printjob provides a very limited set of engineering-related properties; neither of these mechanisms can be used to select the target printer through the program.

The biggest change in Java printing comes from the Java Printing Service API brought about by the release of j2se. This third-generation Java printing support interface breaks through the limitations of the printservice and docprintjob interfaces using the javax. Print package previously mentioned. Because the new API is a parent set of the previously defined functions of the two old printers, it is a common method and the focus of this article.
Further, the following steps show how to use the new Java Printing Service API:
1. Define the printer and restrict the list of functions that are returned to provide the functions you want to implement. The Print Service implements the printservice interface.

2. Create a print event by calling the createprintjob () method defined in the interface as an instance of docprintjob.

3. Create a class that implements the doc interface to describe the data you want to print. You can also create a printrequestattributeset instance to define the print options you want.

4. Use the printv () method defined by the docprintjob interface to initialize printing, specify the doc you created earlier, specify printrequestattributeset, or set it to a null value.

Now you can check each step and try to complete them.

Note:
In this article, I will use printer and print services alternately, because in most cases, the print service is no less than a real printer. The general print service reflects that theoretically it can be sent to more than just the output of the printer. For example, the print service may not be able to print at all but write data to files on the disk. In other words, all printers can be seen as special printing services, but not all printing services are associated with printers. Just as you usually send your text to a printer, I sometimes use a simpler printer term to replace technically more accurate printing services.

Define Print Service
You can use one of the three static methods defined in the printservicelookup class. The simplest one is lookupdefaultprintservice (). Just like its name, it returns a default printer:

PrintService service = PrintServiceLookup.lookupDefaultPrintService(); 

Although this method is very simple and convenient, using it to select your printer means that your printer has always supported the data output that your program needs to accurately transmit. In fact, what you really want is the type that can process the data you want and support the features you want, such as color or printing on both sides. To return the printers supported by the special features you require from the list, you can use lookupprintservices () or lookupmultidocprintservices () in the remaining two methods ().

The lookupprintservices () method has two parameters: A docflavor instance and an instance that implements the attributeset interface.
You will immediately see that you can use either of the two to restrict the returned printer, but lookupprintservices () allows you to specify the two parameters as null values. If you set both to null, the returned value will be any available printer. In this case, you do not need to view the methods defined in printservice. One of the getname () Methods returns a string representing the name of the printer. You can compile the following code to list the existing printers in your system:

PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
for (int i = 0; i < services.length; i++) {
   System.out.println(services[i].getName());
}

For example, if your system name is printserver and there are alpha, beta, and gamma printers, you can use the above code to get the following output:
// Printserver/Alpha
// Printserver/beta
// Printserver/gamma

Check the parameters that you can pass to the lookupprintservices () method to see how to return printers with special functions.

Docflavor
The first parameter you can specify is a docflavor instance, which describes the type and storage of the data to be printed. In most cases, you do not need to create a new instance. Because Java contains many pre-defined instances, you can use them to pass to lookupprintservices (). However, let's take a look at the docflavor structure and method to explore how the Print Service uses this instance.

The two parameters required to create a docflavor instance are strings. One is the mime (Multipurpose Internet Mail Extensions) type and the other is the class name. The MIME type is used to describe the data type. For example, if you want to print a GIF file, you need to use docflavor of the MIME type of image/GIF. Similarly, if you want to print text information in an HTML file, use MIME-type text/plain or text/html.

Presentation class
The MIME type describes the type of the data to be printed, and the class represents how the Print Service gets the data. Docflavor contains several static internal classes, each of which corresponds to a presentation class and how to load the data to be printed.

Table 1 lists the internal and performance classes mentioned above. Note that next to service_formatted (which will be explained in more detail later), each corresponds to "binary" or "character. In fact, these differences are artificial, because the "character" data type itself is a special binary type. In this case, binary data includes characters that people can understand and formatted characters such as tabs and line breaks. Of course, these differences are very important, reflecting that the class of forward character is not suitable for storing binary data.

For example, you do not use character queues or strings to save a GIF file, and you cannot access it through the reader interface. On the other hand, because character is a special binary data, it is perfect for storing text information in byte arrays or accessing it through inputstream or a URL.

Table

1. docflavor representations

Any static internal class defined above corresponds to a presentation class, but remember that every docflavor instance confirms the type of data to be printed through a presentation class and a mime.
To access such an instance, you need to use the internal classes listed in Table 1. For example, if you want to print a GIF file accessed through a URL on the Internet, you can select javav.net. URL as the performance class, and the corresponding static class in docflavor is the URL class. If you open the internal class document, you will find that it actually defines a series of static internal classes, each corresponding to the MIME type supported by a printer. Table 2 describes the internal classes and mime in docflavor. URL.

Table 2. The docflavor. url inner classes

Because you want to print GIF images through URLs, you can use the code to obtain the instance.

DocFlavor flavor = DocFlavor.URL.GIF; 

This Code creates a docflavor instance, which indicates that the class is java.net. url, And the mime is image/GIF.
Table 2 lists docflavor. url classes. What about the other six internal classes? Let's wait and discuss service_formatted. Before that, let's look at the internal classes related to all three types of binary data (byte_array, input_stream, and URL. For example, if you store GIF in a byte array, you can use the following code:

DocFlavor flavor = DocFlavor.BYTE_ARRAY.GIF; 

Just as there are three internal classes associated with the binary type, the other three classes related to the character type are listed in table 3.

Table 3. char_array, reader, and string

Therefore, if you want to print text data stored in strings, use the following code:

DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN;

Similarly, if the text is from an HTML document on a webpage, use the following code:

DocFlavor flavor = DocFlavor.STRING.TEXT_HTML;

Select the correct printer
Remember the assumption about the exact support for the data type you want to print for the printer before we started to discuss docflavor? This seems unnecessary. In fact, you will be surprised by the types of documents supported by your printer. For example, the text type seems to be the easiest to support, so if your program wants to print a common text or HTML text, you can select a print service and send it to the printer. However, most printers do not support text-based representations. If you try to send docflavor that is not supported by the printer, the following exception occurs:

Exception in thread "main" sun.print.PrintJobFlavorException: invalid flavor
   at sun.print.Win32PrintJob.print(Win32PrintJob.java:290)
   at PrintTest.main(PrintTest.java:11)

Now you know how to get a docflavor reference and we also discuss the importance of choosing a printer to support this flavor. Next I will show you how to determine whether your printer supports it. Previously, I said that lookupprintservices () allows you to specify a docflavor as the first parameter. If the parameter you specify is not empty, the method returns an instance that supports this printer. For example, the following code returns a list of printers that can print GIF files through urls:

DocFlavor flavor = DocFlavor.URL.GIF;
PrintService[] services = PrintServiceLookup.lookupPrintServices(flavor, null);

In addition, if your program has obtained an instance of the print service and you want to know whether it supports another specific flavor, you can call the isdocflavorsupported () method. In the following code, you will get a reference to the default printer. If you cannot print GIF, an error message will appear:

PrintService service = PrintServiceLookup.lookupDefaultPrintService();
DocFlavor flavor = DocFlavor.URL.GIF;
if (!service.isDocFlavorSupported(flavor)) {
   System.err.println("The printer does not support the appropriate DocFlavor");
}

Attributeset
As you can see, docflavor describes printing data and can be used to determine whether the Printing Service supports this data. However, your program needs to select a printer based on the supported elements. For example, if you want to print an image and use different colors to describe different information, you want to know whether the provided service supports color printing. If not, you can either disable it or request a black/white image.

Similar to color printing, printing on both sides or using different positioning depends on the attributes of the printer. The javax. Print. Attribute package contains many packages and interfaces you can use to describe these attributes. One of the interfaces is the second attributeset parameter in lookupprintservices () mentioned above. As you would like, it returns the set of attributes. When you call lookupprintservices () to specify a non-null value, the print service that supports these attributes will be returned. In other words, if neither docflavor nor attributeset is null, the method returns the printers supported by both attributes.

Attribute
Attributeset is a set of attributes. An obvious question is how to specify the attribute value? The javax. Print. Attribute package also contains an interface named attribute. You can immediately see that you can call the add method to create an attribute instance for attributeset to obtain this set. The javax. Print. Attribute. Standard package defines a large number of interfaces you will use. Previously, you can view other interfaces in the javax. Print. Attribute package.

Attribute Module
So far, we have described attributes as the function of the print service, but in fact it is very easy to calculate the attributes supported by Java. Java has corresponding modules for each attribute. Only the attributes of these modules are valid. Use different attributes in different JAVA print service locations, rather than all attributes apply anywhere.
To better understand this, let's take a look at
Orientationrequested and colorsupported interfaces. When creating a new printed document, you can specify the orientationrequested attribute and position for printing. Colorsupported is returned when you call the getattributes method of the printservice interface. Orientationrequested is an attribute that you use to pass to the printer, while colorsupported is a printing service that provides you with information about printer capabilities. You can specify colorsupported as a property when creating a print document, because whether the printer supports color printing is beyond your control.

Interfaces and inheritance
When you first check the interfaces and classes in the javax. Print. Attribute package, you may find it difficult to select the interfaces and classes in the list. In addition to attribute and attributeset and hashattributeset inherited from attributeset, The javax. Print. Attribute package contains four sub-interfaces and classes, which are listed in table 4 and figure 1.

Table 4. interfaces and classes defined in javax. Print. Attribute

Figure 1. hierarchical structure of some classes in the javax. Print. Attribute package.

So with attribute, attributeset, and hashattributeset, why do we need to use these different interfaces and inheritance classes? Because these special classes are tailored for those special attributes. For example, I mentioned the attributes that can be used when you create a printed document. For example, colorsupported cannot be used there. When creating such a document, you can use the docattributeset interface (or a more professional, hashdocattributeset inherited class). This inherited class only allows you to add attributes that inherit the docattribute interface. The four different modules are as follows:
& #61623; Doc: when creating a document & #61623; determine how to print the document
& #61623; printjob: print the attributes of a task to describe the task status
& #61623; printrequest: the request sent to the task during initial printing
& #61623; printservice: The printer function is described by the Print Server & #61623; service return.

To learn how to work, create a docattributeset instance and set the docattributeset and orientationrequested attributes for attributeset. Hashdocattributeset defines a good structure. You can easily create an instance as follows:

DocAttributeSet attrs = new HashDocAttributeSet(); 

Now that you have created attributeset, you can call the add method and pass it to the inherited instance of attribute. If you read the documentation of the orientationrequested class, you will find that it contains a series of static orientationrequest instances, each of which corresponds to a document Positioning method. To specify the type you want, all you need to do is to pass the following method to a static instance reference of the add method:

DocAttributeSet attrs = new HashDocAttributeSet();
attrs.add(OrientationRequested.PORTRAIT);

The colorsupported class is a little different, but it is just as simple. It defines two types of static instances: one that supports color printing and the other that does not. You can add a colorsupported attribute to docattributeset. The Code is as follows:

DocAttributeSet attrs = new HashDocAttributeSet();
attrs.add(OrientationRequested.PORTRAIT);
attrs.add(ColorSupported.SUPPORTED);

As mentioned earlier, it is inappropriate to specify whether color printing is supported because this is not what the program can control. In other words, the colorsupported attribute is not suitable for a series of document attributes. Therefore, when the colorsupported attribute is added, a classcastexception is thrown when running the previous code.

Remember that each attributeset sub-interface has a corresponding attribute sub-interface and an inherited sub-class. When an attribute is added, the inherited subclass tries to use attribute as a parameter to the corresponding sub-interface to ensure that only the currently appropriate attribute is successfully added.

In this case, the add method of hashdocattributeset is called together with an instance of orientationrequested for the first time, and is successfully passed to docattribute as an object. As shown in figure 2, orientationrequested inherits the interface. Correspondingly, when the colorsupported instance is passed, it fails because it does not inherit docattribute.


Figure 2. hierarchical structure of some classes in the javax. Print. Attribute package

This example shows that the four interfaces and class groups in Table 4 are used to ensure correct attributes. Note that there is a large amount of interaction between modules and different attributes, so many attributes are associated with more than one module. For example, many attributes inherit from printjobattribute and printrequestattribute because most of them are provided to you through a related print task. You can specify them during initialization. For example, you can add it to printrequestattributeset to specify the Task Name and return it through printjobattributeset during printing. Therefore, the jobname Attribute Class inherits both.
Printrequestattribute and printjobattribute.
Attributeset and hashattributeset

You already know why there are four child classes, but what are the attributeset interfaces and hashattributeset parent classes? Attributeset/hashattributeset is used when you are not sure which attributes are only related to a module to be stored in this set. Remember that the previously mentioned lookupprintservices () method allows you to specify the attributeset parameter to limit the returned Print Service. On the surface, it is better to specify the instance of printserviceattributeset, but many attributes you may use do not inherit printserviceattribute.

Let's assume that you want the lookupprintservices () method to return a printer that supports color printing and landscape printing. These attributes are associated with colorsupported and orientationrequested attributes, but note that these classes do not share modules. The former is a printserviceattribute, while the orientationrequested is associated with the other three modules (Doc, printrequest, and printjob. This means that a single attributeset interface or class does not exist to contain both the colorsupported and sides attributes.

It is too easy to create attributeset and use a hashattributeset instance to contain both orientationrequested and colorsupported. Unlike its subclass, it does not limit you to add special attributes, so you can run the following code successfully:

AttributeSet attrs = new HashAttributeSet();
attrs.add(ColorSupported.SUPPORTED);
attrs.add(OrientationRequested.LANDSCAPE);
PrintService[] services = PrintServiceLookup.lookupPrintServices(null, attrs);

Select a printer on the user interface
In this regard, I think the printer used should be selected by the application program. However, during the operation, a dialog box is displayed for the user to select when the output content is printed. Fortunately, Java simplifies these operations by using static printdialog () methods in the serviceui class (defined in the javax. Print package.
Next to the displayed dialog box, you must specify the following parameter values when calling printdialog:
The optional printservice instance array.
The default printservice.
Printrequestattributeset instance. This is used to pop up the displayed dialog box and return any changes made by the user before the dialog box disappears.
To explain how this works, use the following simple code snippet to display the Print dialog:

PrintService[] services = PrintServiceLookup.lookupPrintServices(null, null);
PrintService svc = PrintServiceLookup.lookupDefaultPrintService();
PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
PrintService selection = ServiceUI.printDialog(
   null, 100, 100, services, svc, null, attrs);

The dialog box shown in Example 3 is generated during running.


Figure 3. The printer Dialog

With the code instructions, the value returned from the printdialog () method is a printservice instance that identifies the printer selected by the user or is identified as null when the user cancels the printer dialog. In addition, printrequestattributeset has been updated to reflect user-made changes, such as the number of copies to be printed.
By using the printdialog () method, you can select the printer to which the output is sent, and provide the user's expectation for professional applications.

Create a print task
This is a simple step in printing, because once you get a reference for printservice, you need to call the createprintjob () method, such:

PrintService service;
.
.
.
DocPrintJob job = service.createPrintJob();

The Code shows that the value returned from createprintjob () is a docprintjob instance, which allows you to control and monitor the status of the print operation. To start printing, you will call the print () method of the docprintjob object. However, before that, you need to define the document to be printed or choose printrequestattributese. You already know how to construct and bring up attributeset. This step is no longer repeated. Next, you will learn about the document to be printed.

Define the document to be printed
The next step is to define the document to be printed and create it using an interface instance of DOC in the javax. Print package. Each Doc instance has two attributes that must be defined and one that can be selected:
& #61623; object indicates the content to be printed
& #61623; A docflavor instance description Data Type
& #61623; optional docattributeset contains attributes during printing

The document of reviewing the doc interface shows that the javax. Print package contains the inheritance of a simpledoc interface. Its constructor contains the preceding three parameters. To learn how to build simpledoc instances, we suppose you want to print two copies of the GIF file containing http://www.apress.com/apresscorporate/supplement/1/421/bcm.gif.
What we need to do is to build a simpledoc instance to describe this document and create a URL to point to the image, reference docflavor, and pass the two to the simpledoc constructor:

URL url = new URL(
   "http://www.apress.com/ApressCorporate/supplement/1/421/bcm.gif");
DocFlavor flavor = DocFlavor.URL.GIF;
SimpleDoc doc = new SimpleDoc(url, flavor, null);

Start printing
The last step of printing is to call the print () method of docprintjob to pass the doc object of the data to be printed, or use the printrequestattributeset instance. For simplicity, assuming that the default printer supports the flavor and attributes you need, use the following code to print the GIF files mentioned in the previous example:

PrintService service = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = service.createPrintJob();
URL url = new URL(
   "http://www.apress.com/ApressCorporate/supplement/1/421/bcm.gif ");
DocFlavor flavor = DocFlavor.URL.GIF;
Doc doc = new SimpleDoc(url, flavor, null);
PrintRequestAttributeSet attrs = new HashPrintRequestAttributeSet();
attrs.add(new Copies(2));
job.print(doc, attrs)

;
Note: In some cases, printing is not executed synchronously, which may return a call to print () before the actual printing is completed.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.