/* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * * * * * * * * * * * * * * * * * * * * */ package javafx.print; import java.util.Set; import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanPropertyBase; import javafx.beans.property.IntegerProperty; import javafx.beans.property.ObjectProperty; import javafx.beans.property.Property; import javafx.beans.property.SimpleIntegerProperty; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; /** * The JobSettings class encapsulates most of the configuration of a * print job. Applications do not - and cannot - directly create or * set a JobSettings instance. One is already installed on the print job * when it is created. *
* As documented on PrinterJob, the JobSettings installed on that job will * initially reflect the current default settings for the initially * associated printer for that job. *
* The JobSettings delegate then remains the same for the life of the job, * and will have it's member properties updated to be compatible with * a change in Printer on the job. For example as a * result of a user interaction via a platform's dialog. * An incompatible setting will usually cause the setting to revert to * the default for the new printer. *
* Any implicit or explicit updates to settings resulting from * the user interaction with dialog will be propagated and visible to * the application once the user approves the settings by * dismissing the dialog using its "accept" option. *
* For most printing applications it is likely sufficient to let the user * set the desired options and have these propagated to the job. * For applications which need them, * there are setter and getter methods for the individual options, * which are also available as properties, and change in values of * settings may be monitored and updated via these properties. *
* Not all values of settings are available on all printers. For example
* a printer may not support two-sided printing.
* See the {@link javafx.print.Printer Printer} class for how to
* to determine supported settings.
*
* @since JavaFX 8.0
*
*
*/
public final class JobSettings {
private PrinterJob job;
private Printer printer;
private PrinterAttributes printerCaps;
/*
* There's no need for client code to create a JobSettings
* as there is already one set on a PrinterJob and it must
* be updated, not replaced. So we do not expose the constructor.
*
*/
JobSettings(Printer printer) {
this.printer = printer;
printerCaps = printer.getPrinterAttributes();
}
void setPrinterJob(PrinterJob job) {
this.job = job;
}
private boolean isJobNew() {
// If we haven't yet set the job its equivalent to a new job.
return job == null || job.isJobNew();
}
/*
* We need to be able to distinguish settings which are
* the printer defaults, versus explicitly set ones. so
* the settings object remembers for each setting if it
* was an explicit setting or a default.
* Settings such as JobName which are supportable across printers
* don't need this treatment.
*/
private boolean defaultCopies = true;
private boolean hasOldCopies = false;
private int oldCopies;
private boolean defaultSides = true;
private boolean hasOldSides = false;
private PrintSides oldSides;
private boolean defaultCollation = true;
private boolean hasOldCollation = false;
private Collation oldCollation;
private boolean defaultPrintColor = true;
private boolean hasOldPrintColor = false;
private PrintColor oldPrintColor;
private boolean defaultPrintQuality = true;
private boolean hasOldPrintQuality = false;
private PrintQuality oldPrintQuality;
private boolean defaultPrintResolution = true;
private boolean hasOldPrintResolution = false;
private PrintResolution oldPrintResolution;
private boolean defaultPaperSource = true;
private boolean hasOldPaperSource = false;
private PaperSource oldPaperSource;
private boolean defaultPageLayout = true;
private boolean hasOldPageLayout = false;
private PageLayout oldPageLayout;
/**
* If any settings are incompatible with the specified printer,
* they are updated to be compatible.
* This method could be useful as a public one.
*/
void updateForPrinter(Printer printer) {
this.printer = printer;
this.printerCaps = printer.getPrinterAttributes();
////////////////////////////////////////////////
/*
* The algorithm for how we update is tricky in order to get
* the desired behaviour, which needs to be explained first.
* - If neither user nor code ever set a value for a property,
* we always update to the default for the new printer.
* - If user or code has ever explicitly set a value for a
* property then when we navigate to a different printer we
* remember that last set value.
* - If the new printer can support that value, it is used
* - If it can't, then we use the default value for that printer,
* or in a few cases some 'close' value. Such as substituting
* LANDSCAPE for REVERSE_LANDSCAPE.
* - We still remember the value and if we move to another printer
* that supports it, it gets resurrected.
*/
//////////// COPIES ////////////
if (defaultCopies) {
if (getCopies() != printerCaps.getDefaultCopies()) {
setCopies(printerCaps.getDefaultCopies());
defaultCopies = true; // restore that this is default.
}
} else {
int copies = getCopies();
if (hasOldCopies && oldCopies > copies) {
copies = oldCopies;
}
int maxCopies = printerCaps.getMaxCopies();
if (!hasOldCopies && getCopies() > maxCopies) {
hasOldCopies = true;
oldCopies = getCopies();
}
if (copies > maxCopies) copies = maxCopies;
setCopies(copies);
}
////////////////////////////////////////////////
PrintSides currSides = getPrintSides();
PrintSides defSides = printerCaps.getDefaultPrintSides();
Set
* An illegal or unsupported (by the printer) set of page ranges
* will be ignored.
*
* Ranges which exceed beyond the number of pages imaged by the job
* during printing do not cause any error.
*/
public final ObjectProperty pageRangesProperty() {
if (pageRanges == null) {
pageRanges = new SimpleObjectProperty(JobSettings.this,
"pageRanges", null) {
@Override
public void set(Object o) {
try {
set((PageRange[])o);
} catch (ClassCastException e) {
return;
}
}
public void set(PageRange[] value) {
if (!isJobNew()) {
return;
}
if (value == null || value.length == 0 ||
value[0] == null) {
value = null;
} else { // validate
int len = value.length;
PageRange[] arr = new PageRange[len];
int curr = 0;
for (int i=0; i
* @param color new setting for print color.
*/
public void setPrintColor(PrintColor color) {
if (color == getPrintColor()) {
return;
}
printColorProperty().set(color);
}
/////////////////////// END COLOUR /////////////////////
/////////////////////// START QUALITY /////////////////////
private ObjectProperty
* Note that quality and resolution overlapping concepts.
* Therefore a printer may support setting one, or the other but
* not both. Applications setting these programmatically should
* query both properties and select appropriately from the supported
* values. If a printer supports non-standard values, code likely
* cannot distinguish the printer's interpretation of these values
* and is safest to stick to selecting from the standard value that
* matches the requirement.
* @param quality new setting for print quality.
*/
public void setPrintQuality(PrintQuality quality) {
if (quality == getPrintQuality()) {
return;
}
printQualityProperty().set(quality);
}
/////////////////////// END QUALITY /////////////////////
/////////////////////// START RESOLUTION /////////////////////
private ObjectProperty
* Note that quality and resolution overlapping concepts.
* Therefore a printer may support setting one, or the other but
* not both. Applications setting these programmatically should
* query both properties and select appropriately from the supported
* values. If a printer supports non-standard values, code likely
* cannot distinguish the printer's interpretation of these values
* and is safest to stick to selecting from the standard value that
* matches the requirement.
* @param resolution new setting for print resolution.
*/
public void setPrintResolution(PrintResolution resolution) {
if (resolution == null || resolution == getPrintResolution()) {
return;
}
printResolutionProperty().set(resolution);
}
/////////////////////// END RESOLUTION /////////////////////
//////////////// START PAPERSOURCE /////////////////
private ObjectPropertyStringProperty
representing the name of a job.
*/
public final StringProperty jobNameProperty() {
if (jobName == null) {
jobName = new SimpleStringProperty(JobSettings.this, "jobName",
DEFAULT_JOBNAME) {
@Override
public void set(String value) {
if (!isJobNew()) {
return;
}
if (value == null) {
value = DEFAULT_JOBNAME;
}
super.set(value);
}
@Override
public void bind(ObservableValue extends String>
rawObservable) {
throw new
RuntimeException("Jobname property cannot be bound");
}
@Override
public void bindBidirectional(PropertyIntegerProperty
representing the number of
* copies of the job to print.
*/
public final IntegerProperty copiesProperty() {
if (copies == null) {
copies =
new SimpleIntegerProperty(JobSettings.this, "copies",
printerCaps.getDefaultCopies()) {
@Override
public void set(int value) {
if (!isJobNew()) {
return;
}
if (value <= 0) {
if (defaultCopies) {
return;
} else {
super.set(printerCaps.getDefaultCopies());
defaultCopies = true;
return;
}
}
super.set(value);
defaultCopies = false;
}
@Override
public void bind(ObservableValue extends Number>
rawObservable) {
throw new
RuntimeException("Copies property cannot be bound");
}
@Override
public void bindBidirectional(PropertyObjectProperty
whose value represents the job pages
* to print as an array of PageRange.
* A null values mean print all pages.
* Otherwise it must be a non-overlapping array of PageRange
* instances ordered in increasing page number.
* Page numbers start from 1 (one).
* An empty array is considered equivalent to a null array.
* ((PageRange[])null)
always means all pages however
* since this is the default it is less likely to be used.
* See {@link pageRangesProperty} for more details.
* @param pages null or a varargs array as specified above
*/
public void setPageRanges(PageRange... pages) {
pageRangesProperty().set((PageRange[])pages);
}
/////////////////////// END PAGE RANGES /////////////////////
/////////////////////// START SIDES /////////////////////
private ObjectPropertyPrintSides
.
*/
public final ObjectPropertyPrintSides
property which controls
* duplex printing.
* A null value is ignored.
* @param sides new setting for number of sides.
*/
public void setPrintSides(PrintSides sides) {
if (sides == getPrintSides()) {
return;
}
printSidesProperty().set(sides);
}
/////////////////////// END SIDES /////////////////////
/////////////////////// START COLLATION /////////////////////
private ObjectPropertyCollation
.
*/
public final ObjectPropertyfalse) is the typical default value.
*/
public Collation getCollation() {
return collationProperty().get();
}
/**
* Set the
Collation
property.
* A null value is ignored.
* @param collation new setting for collation
*/
public void setCollation(Collation collation) {
if (collation == getCollation()) {
return;
}
collationProperty().set(collation);
}
/////////////////////// END COLLATION /////////////////////
/////////////////////// START COLOUR /////////////////////
private ObjectPropertyPrintColor
.
*/
public final ObjectPropertyPrintColor
property.
* A null value is ignored.
* PrintQuality
.
*/
public final ObjectPropertyPrintQuality
property.
* A null value is ignored.
* PrintResolution
.
*/
public final ObjectPropertyPrintResolution
property.
* A null value is ignored.
* PaperSource
.
*/
public final ObjectPropertyPageLayout
.
*/
public final ObjectProperty