Provides classes and interfaces that describe the types of Java™ Print Service attributes and how they can be collected into attribute sets.
The print data and the processing instructions are separate entities. This means that:
In the Java Print Service API, an attribute category is represented by a Java
class implementing the Attribute interface.
Attribute values are instances of such a class or one of its subclasses. For
example, to specify the number of copies, an application constructs an
instance of the Copies class with the
number of desired copies and uses the Copies
instance as part of the
print request. In this case, the Copies
class represents the
attribute category, and the Copies
instance represents the attribute
value.
Once the printer starts processing the print job, additional information about the job becomes available, which might include: the job state (such as completed or queued) and the number of pages printed so far. These pieces of information are also attributes. Attributes can also describe the printer itself, such as: the printer name, the printer location, and the number of jobs queued.
The Java Print Service API defines these different kinds of attributes with
five subinterfaces of Attribute
:
DocAttribute
or to an entire print job as a
PrintRequestAttribute
. Certain low-level attributes are never used on
their own but are always aggregated into higher-level attributes. These
low-level attribute classes only implement interface
Attribute, not any of the tagging subinterfaces.
The Java Print Service API defines a group of standard attribute classes
modeled upon the attributes in the Internet Printing Protocol (IPP) version
1.1. The standard attribute classes are in the subpackage
javax.print.attribute.standard
to keep the actual attribute classes
conceptually separate from the generic apparatus defined in package
javax.print.attribute
.
The AttributeSet
interface is similar to the
Map interface: it provides a map of
key to values, in which each key is unique and can contain no more than one
value. However, the AttributeSet
interface is designed to
specifically support the needs of the Java Print Service API. An
AttributeSet
requires that:
AttributeSet
corresponds to a category, and the
value of the key can only be one of the attribute values that belong to the
category represented by the key. Thus, unlike a Map
, an
AttributeSet
restricts the possible values of a key: an attribute
category cannot be set to an attribute value that does not belong to that
category.
Attribute
interface can be
added to the set.
javax.print.attribute
package includes
HashAttributeSet as a concrete
implementation of the attribute set interface. HashAttributeSet
provides an attribute set based on a hash map. You can use this
implementation or provide your own implementation of interface
AttributeSet
.
The Java Print Service API provides four specializations of an attribute set that are restricted to contain just one of the four kinds of attributes, as discussed in the Attribute Roles section:
Notice that only four kinds of attribute sets are listed here, but there are five kinds of attributes. Interface SupportedValuesAttribute denotes an attribute that gives the supported values for another attribute. Supported-values attributes are never aggregated into attribute sets, so there is no attribute set subinterface defined for them.
In some contexts, an attribute set is read-only, which means that the client
is only allowed to examine an attribute set's contents but not change them.
In other contexts, the attribute set is read-write, which means that the
client is allowed both to examine and to change an attribute set's contents.
For a read-only attribute set, calling a mutating operation throws an
UnmodifiableSetException
.
Package javax.print.attribute
includes one concrete implementation of
each of the attribute set subinterfaces:
Copies
, class Sides, and class
PrinterResolution. Each
attribute class wraps one or more primitive data items containing the
attribute's value. Attribute set operations perform frequent comparisons
between attribute category objects when adding attributes, finding existing
attributes in the same category, and looking up an attribute given its
category. Because an attribute category is represented by a class, fast
attribute-value comparisons can be performed with the Class.equals
method.
Even though the Java Print Service API includes a large number of different attribute categories, there are only a few different types of attribute values. Most attributes can be represented by a small number of data types, such as: integer values, integer ranges, text, or an enumeration of integer values. The type of the attribute value that a category accepts is called the attribute's abstract syntax. To provide consistency and reduce code duplication, the Java Print Service API defines abstract syntax classes to represent each abstract syntax, and these classes are used as the parent of standard attributes whenever possible. The abstract syntax classes are:
Each attribute class implements the Attribute
interface, either
directly or indirectly, to mark it as a printing attribute. An attribute
class that can appear in restricted attribute sets in certain contexts also
implements one or more subinterfaces of Attribute
. Most attribute
classes also extend the appropriate abstract syntax class to get the
implementation. Consider the Sides
attribute class:
public class Sides extends EnumSyntax implements DocAttribute, PrintRequestAttribute, PrintJobAttribute { public final Object getCategory() { return Sides.class;
... }}
Since every attribute class implements Attribute
, every attribute
class must provide an implementation for the
getCategory
method,
which returns the attribute category. In the case of Sides
, the
getCategory
method returns Sides.class
. The
getCategory
method is final to ensure that any vendor-defined
subclasses of a standard attribute class appear in the same category. Every
attribute object is immutable once constructed so that attribute object
references can be passed around freely. To get a different attribute value,
construct a different attribute object.
EnumSyntax
specifies all
the possible attribute values at compile time as singleton instances of the
attribute class. This means that new enumerated values cannot be constructed
at run time. To define new vendor-specific values for a standard enumerated
attribute, the vendor must define a new attribute class specifying the new
singleton instances. To ensure that the new attribute values fall in the same
category as the standard attribute values, the new attribute class must be a
subclass of the standard attribute class.
To define a new attribute category, a vendor defines a new attribute class.
This attribute class, like the standard attribute classes, implements
Attribute
or one of its subinterfaces and extends an abstract syntax
class. The vendor can either use an existing abstract syntax class or define
a new one. The new vendor-defined attribute can be used wherever an
Attribute
is used, such as in an AttributeSet
.
PrintRequestAttributeSet
because print-request attributes are the types of attributes that client
usually specifies. This example demonstrates creating an attribute set of
print-request attributes and locating a printer that can print the document
according to the specified attributes:
FileInputStream psStream; try { psstream = new FileInputStream("file.ps");
catch (FileNotFoundException ffne) { } if (psstream == null) { return; } //Set the document type. See the DocFlavor documentation for //more information. DocFlavor psInFormat = DocFlavor.INPUT_STREAM.POSTSCRIPT; Doc myDoc = new SimpleDoc(pstream, psInFormat, null); PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); aset.add(new Copies(5)); aset.add(MediaSize.A4); aset.add(Sides.DUPLEX); PrintService[] services = PrintServiceLookup.lookupPrintServices(psInFormat, aset); if (services.length > 0) { DocPrintJob job = services[0].createPrintJob(); try { job.print(myDoc, aset); } catch (PrintException pe) {} } }
Please note: In the javax.print
APIs, a null
reference
parameter to methods is incorrect unless explicitly documented on the method
as having a meaningful interpretation. Usage to the contrary is incorrect
coding and may result in a run time exception either immediately or at some
later time. IllegalArgumentException
and NullPointerException
are examples of typical and acceptable run time exceptions for such cases.