Spec-Zone .ru
спецификации, руководства, описания, API
|
001/* 002 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. Oracle designates this 008 * particular file as subject to the "Classpath" exception as provided 009 * by Oracle in the LICENSE file that accompanied this code. 010 * 011 * This code is distributed in the hope that it will be useful, but WITHOUT 012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 014 * version 2 for more details (a copy is included in the LICENSE file that 015 * accompanied this code). 016 * 017 * You should have received a copy of the GNU General Public License version 018 * 2 along with this work; if not, write to the Free Software Foundation, 019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 020 * 021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 022 * or visit www.oracle.com if you need additional information or have any 023 * questions. 024 */ 025 026package javafx.print; 027 028import java.util.Set; 029 030import javafx.beans.property.BooleanProperty; 031import javafx.beans.property.BooleanPropertyBase; 032import javafx.beans.property.IntegerProperty; 033import javafx.beans.property.ObjectProperty; 034import javafx.beans.property.Property; 035import javafx.beans.property.SimpleIntegerProperty; 036import javafx.beans.property.SimpleObjectProperty; 037import javafx.beans.property.SimpleStringProperty; 038import javafx.beans.property.StringProperty; 039import javafx.beans.value.ObservableValue; 040 041/** 042 * The JobSettings class encapsulates most of the configuration of a 043 * print job. Applications do not - and cannot - directly create or 044 * set a JobSettings instance. One is already installed on the print job 045 * when it is created. 046 * <p> 047 * As documented on PrinterJob, the JobSettings installed on that job will 048 * initially reflect the current default settings for the initially 049 * associated printer for that job. 050 * <p> 051 * The JobSettings delegate then remains the same for the life of the job, 052 * and will have it's member properties updated to be compatible with 053 * a change in Printer on the job. For example as a 054 * result of a user interaction via a platform's dialog. 055 * An incompatible setting will usually cause the setting to revert to 056 * the default for the new printer. 057 * <p> 058 * Any implicit or explicit updates to settings resulting from 059 * the user interaction with dialog will be propagated and visible to 060 * the application once the user approves the settings by 061 * dismissing the dialog using its "accept" option. 062 * <p> 063 * For most printing applications it is likely sufficient to let the user 064 * set the desired options and have these propagated to the job. 065 * For applications which need them, 066 * there are setter and getter methods for the individual options, 067 * which are also available as properties, and change in values of 068 * settings may be monitored and updated via these properties. 069 * <p> 070 * Not all values of settings are available on all printers. For example 071 * a printer may not support two-sided printing. 072 * See the {@link javafx.print.Printer Printer} class for how to 073 * to determine supported settings. 074 * 075 * @since JavaFX 8 076 * 077 * 078 */ 079public final class JobSettings { 080 081 private PrinterJob job; 082 private Printer printer; 083 private PrinterAttributes printerCaps; 084 085 /* 086 * There's no need for client code to create a JobSettings 087 * as there is already one set on a PrinterJob and it must 088 * be updated, not replaced. So we do not expose the constructor. 089 * 090 */ 091 JobSettings(Printer printer) { 092 this.printer = printer; 093 printerCaps = printer.getPrinterAttributes(); 094 } 095 096 void setPrinterJob(PrinterJob job) { 097 this.job = job; 098 } 099 100 private boolean isJobNew() { 101 // If we haven't yet set the job its equivalent to a new job. 102 return job == null || job.isJobNew(); 103 } 104 105 106 /* 107 * We need to be able to distinguish settings which are 108 * the printer defaults, versus explicitly set ones. so 109 * the settings object remembers for each setting if it 110 * was an explicit setting or a default. 111 * Settings such as JobName which are supportable across printers 112 * don't need this treatment. 113 */ 114 115 private boolean defaultCopies = true; 116 private boolean hasOldCopies = false; 117 private int oldCopies; 118 119 private boolean defaultSides = true; 120 private boolean hasOldSides = false; 121 private PrintSides oldSides; 122 123 private boolean defaultCollation = true; 124 private boolean hasOldCollation = false; 125 private Collation oldCollation; 126 127 private boolean defaultPrintColor = true; 128 private boolean hasOldPrintColor = false; 129 private PrintColor oldPrintColor; 130 131 private boolean defaultPrintQuality = true; 132 private boolean hasOldPrintQuality = false; 133 private PrintQuality oldPrintQuality; 134 135 private boolean defaultPrintResolution = true; 136 private boolean hasOldPrintResolution = false; 137 private PrintResolution oldPrintResolution; 138 139 private boolean defaultPaperSource = true; 140 private boolean hasOldPaperSource = false; 141 private PaperSource oldPaperSource; 142 143 private boolean defaultPageLayout = true; 144 private boolean hasOldPageLayout = false; 145 private PageLayout oldPageLayout; 146 147 /** 148 * If any settings are incompatible with the specified printer, 149 * they are updated to be compatible. 150 * This method could be useful as a public one. 151 */ 152 void updateForPrinter(Printer printer) { 153 154 this.printer = printer; 155 this.printerCaps = printer.getPrinterAttributes(); 156 157 //////////////////////////////////////////////// 158 159 /* 160 * The algorithm for how we update is tricky in order to get 161 * the desired behaviour, which needs to be explained first. 162 * - If neither user nor code ever set a value for a property, 163 * we always update to the default for the new printer. 164 * - If user or code has ever explicitly set a value for a 165 * property then when we navigate to a different printer we 166 * remember that last set value. 167 * - If the new printer can support that value, it is used 168 * - If it can't, then we use the default value for that printer, 169 * or in a few cases some 'close' value. Such as substituting 170 * LANDSCAPE for REVERSE_LANDSCAPE. 171 * - We still remember the value and if we move to another printer 172 * that supports it, it gets resurrected. 173 */ 174 175 //////////// COPIES //////////// 176 177 if (defaultCopies) { 178 if (getCopies() != printerCaps.getDefaultCopies()) { 179 setCopies(printerCaps.getDefaultCopies()); 180 defaultCopies = true; // restore that this is default. 181 } 182 } else { 183 int copies = getCopies(); 184 if (hasOldCopies && oldCopies > copies) { 185 copies = oldCopies; 186 } 187 int maxCopies = printerCaps.getMaxCopies(); 188 if (!hasOldCopies && getCopies() > maxCopies) { 189 hasOldCopies = true; 190 oldCopies = getCopies(); 191 } 192 if (copies > maxCopies) copies = maxCopies; 193 setCopies(copies); 194 } 195 196 197 //////////////////////////////////////////////// 198 199 PrintSides currSides = getPrintSides(); 200 PrintSides defSides = printerCaps.getDefaultPrintSides(); 201 Set<PrintSides> suppSides = printerCaps.getSupportedPrintSides(); 202 203 if (defaultSides) { 204 if (currSides != defSides) { 205 setPrintSides(defSides); 206 defaultSides = true; // restore that this is default. 207 } 208 } else { 209 // The "current" sides may not be the one we really wanted, 210 // but one that was forced by virtue of the current printer not 211 // supporting the one specified for a previous printer. 212 // Check to see if the old supported value can now 213 // be restored on this new printer. 214 if (hasOldSides) { 215 if (suppSides.contains(oldSides)) { 216 setPrintSides(oldSides); 217 hasOldSides = false; // is current again. 218 } else { 219 setPrintSides(defSides); 220 } 221 } else if (!suppSides.contains(currSides)) { 222 hasOldSides = true; 223 oldSides = currSides; 224 setPrintSides(defSides); 225 } 226 } 227 228 //////////////////////////////////////////////// 229 230 Collation currColl = getCollation(); 231 Collation defColl = printerCaps.getDefaultCollation(); 232 Set<Collation> suppColl = printerCaps.getSupportedCollations(); 233 234 if (defaultCollation) { 235 if (currColl != defColl) { 236 setCollation(defColl); 237 defaultCollation = true; // restore that this is default. 238 } 239 } else { 240 if (hasOldCollation) { 241 if (suppColl.contains(oldCollation)) { 242 setCollation(oldCollation); 243 hasOldCollation = false; // is current again. 244 } else { 245 setCollation(defColl); 246 } 247 } else if (!suppColl.contains(currColl)) { 248 hasOldCollation = true; 249 oldCollation = currColl; 250 setCollation(defColl); 251 } 252 } 253 254 255 //////////////////////////////////////////////// 256 257 PrintColor currColor = getPrintColor(); 258 PrintColor defColor = printerCaps.getDefaultPrintColor(); 259 Set<PrintColor> suppColors = printerCaps.getSupportedPrintColors(); 260 261 if (defaultPrintColor) { 262 if (currColor != defColor) { 263 setPrintColor(defColor); 264 defaultPrintColor = true; // restore that this is default. 265 } 266 } else { 267 if (hasOldPrintColor) { 268 if (suppColors.contains(oldPrintColor)) { 269 setPrintColor(oldPrintColor); 270 hasOldPrintColor = false; // is current again. 271 } else { 272 setPrintColor(defColor); 273 } 274 } else if (!suppColors.contains(currColor)) { 275 hasOldPrintColor = true; 276 oldPrintColor = currColor; 277 setPrintColor(defColor); 278 } 279 } 280 281 //////////////////////////////////////////////// 282 283 PrintQuality currQuality = getPrintQuality(); 284 PrintQuality defQuality = printerCaps.getDefaultPrintQuality(); 285 Set<PrintQuality> suppQuality = printerCaps.getSupportedPrintQuality(); 286 287 if (defaultPrintQuality) { 288 if (currQuality != defQuality) { 289 setPrintQuality(defQuality); 290 defaultPrintQuality = true; // restore that this is default. 291 } 292 } else { 293 if (hasOldPrintQuality) { 294 if (suppQuality.contains(oldPrintQuality)) { 295 setPrintQuality(oldPrintQuality); 296 hasOldPrintQuality = false; // is current again. 297 } else { 298 setPrintQuality(defQuality); 299 } 300 } else if (!suppQuality.contains(currQuality)) { 301 hasOldPrintQuality = true; 302 oldPrintQuality = currQuality; 303 setPrintQuality(defQuality); 304 } 305 } 306 307 //////////////////////////////////////////////// 308 309 PrintResolution currRes = getPrintResolution(); 310 PrintResolution defResolution = printerCaps.getDefaultPrintResolution(); 311 Set<PrintResolution> suppRes = 312 printerCaps.getSupportedPrintResolutions(); 313 314 if (defaultPrintResolution) { 315 if (currRes != defResolution) { 316 setPrintResolution(defResolution); 317 defaultPrintResolution = true; // restore that this is default. 318 } 319 } else { 320 if (hasOldPrintResolution) { 321 if (suppRes.contains(oldPrintResolution)) { 322 setPrintResolution(oldPrintResolution); 323 hasOldPrintResolution = false; // is current again. 324 } else { 325 setPrintResolution(defResolution); 326 } 327 } else if (!suppRes.contains(currRes)) { 328 hasOldPrintResolution = true; 329 oldPrintResolution = currRes; 330 setPrintResolution(defResolution); 331 } 332 } 333 334 //////////////////////////////////////////////// 335 336 337 PaperSource currSource = getPaperSource(); 338 PaperSource defSource = printerCaps.getDefaultPaperSource(); 339 Set<PaperSource> suppSources = printerCaps.getSupportedPaperSources(); 340 341 if (defaultPaperSource) { 342 if (currSource != defSource) { 343 setPaperSource(defSource); 344 defaultPaperSource = true; // restore that this is default. 345 } 346 } else { 347 if (hasOldPaperSource) { 348 if (suppSources.contains(oldPaperSource)) { 349 setPaperSource(oldPaperSource); 350 hasOldPaperSource = false; // is current again. 351 } else { 352 setPaperSource(defSource); 353 } 354 } else if (!suppSources.contains(currSource)) { 355 hasOldPaperSource = true; 356 oldPaperSource = currSource; 357 setPaperSource(defSource); 358 } 359 } 360 361 /////////////////////////////////////////////////// 362 363 // Paper size is an important component of PageLayout 364 // and the selected paper input tray may affect the paper sizes 365 // that are supported. For example non-standard sizes may 366 // require a manual or secondary input tray to be used. 367 // The implementation below is not accounting for that and 368 // it likely should, which means that when updating to a new 369 // printer we need to consider tray and layout together, not 370 // consecutively. 371 372 PageLayout currPageLayout = getPageLayout(); 373 PageLayout defPageLayout = printer.getDefaultPageLayout(); 374 375 if (defaultPageLayout) { 376 // It might appear cleaner to always set the default page layout 377 // instance for this printer, but it if they are equal, then 378 // either set(..) will skip it anyway, or it won't and a 379 // listener will see a somewhat spurious change in the property. 380 if (!currPageLayout.equals(defPageLayout)) { 381 setPageLayout(defPageLayout); 382 defaultPageLayout = true; // restore that this is default. 383 } 384 } else { 385 if (hasOldPageLayout) { 386 PageLayout valPageLayout = 387 job.validatePageLayout(oldPageLayout); 388 if (valPageLayout.equals(oldPageLayout)) { 389 setPageLayout(oldPageLayout); 390 hasOldPageLayout = false; // is current again. 391 } else { 392 setPageLayout(defPageLayout); 393 } 394 } else { 395 PageLayout valPageLayout = 396 job.validatePageLayout(currPageLayout); 397 if (!valPageLayout.equals(currPageLayout)) { 398 hasOldPageLayout = true; 399 oldPageLayout = currPageLayout; 400 // Should I use the validated layout instead ? 401 setPageLayout(defPageLayout); 402 } 403 } 404 } 405 } 406 407 /////////////////////// START JOBNAME ///////////////////// 408 409 private static final String DEFAULT_JOBNAME = "JavaFX Print Job"; 410 private SimpleStringProperty jobName; 411 412 /** 413 * <code>StringProperty</code> representing the name of a job. 414 */ 415 public final StringProperty jobNameProperty() { 416 if (jobName == null) { 417 jobName = new SimpleStringProperty(JobSettings.this, "jobName", 418 DEFAULT_JOBNAME) { 419 420 @Override 421 public void set(String value) { 422 if (!isJobNew()) { 423 return; 424 } 425 if (value == null) { 426 value = DEFAULT_JOBNAME; 427 } 428 super.set(value); 429 } 430 431 @Override 432 public void bind(ObservableValue<? extends String> 433 rawObservable) { 434 throw new 435 RuntimeException("Jobname property cannot be bound"); 436 } 437 438 @Override 439 public void bindBidirectional(Property<String> other) { 440 throw new 441 RuntimeException("Jobname property cannot be bound"); 442 } 443 }; 444 } 445 return jobName; 446 } 447 448 /** 449 * @return a string representing the name of a job. 450 */ 451 public String getJobName() { 452 return jobNameProperty().get(); 453 } 454 455 456 /** 457 * @param name string representing the name of a job. 458 */ 459 public void setJobName(String name) { 460 jobNameProperty().set(name); 461 } 462 /////////////////////// END JOBNAME ///////////////////// 463 464 //////////////////////// START COPIES //////////////////////// 465 466 private IntegerProperty copies; 467 468 /** 469 * <code>IntegerProperty</code> representing the number of 470 * copies of the job to print. 471 */ 472 public final IntegerProperty copiesProperty() { 473 if (copies == null) { 474 copies = 475 new SimpleIntegerProperty(JobSettings.this, "copies", 476 printerCaps.getDefaultCopies()) { 477 478 @Override 479 public void set(int value) { 480 if (!isJobNew()) { 481 return; 482 } 483 if (value <= 0) { 484 if (defaultCopies) { 485 return; 486 } else { 487 super.set(printerCaps.getDefaultCopies()); 488 defaultCopies = true; 489 return; 490 } 491 } 492 super.set(value); 493 defaultCopies = false; 494 } 495 496 @Override 497 public void bind(ObservableValue<? extends Number> 498 rawObservable) { 499 throw new 500 RuntimeException("Copies property cannot be bound"); 501 } 502 503 @Override 504 public void bindBidirectional(Property<Number> other) { 505 throw new 506 RuntimeException("Copies property cannot be bound"); 507 } 508 }; 509 } 510 return copies; 511 } 512 513 /** 514 * @return number of copies to print. 515 */ 516 public int getCopies() { 517 return copiesProperty().get(); 518 } 519 520 /** 521 * @param nCopies number of copies to print. 522 */ 523 public final void setCopies(int nCopies) { 524 copiesProperty().set(nCopies); 525 } 526 527 //////////////////////// END COPIES //////////////////////// 528 529 530 /////////////////////// START PAGE RANGES ///////////////////// 531 private ObjectProperty<PageRange[]> pageRanges = null; 532 533 /** 534 * An <code>ObjectProperty</code> whose value represents the job pages 535 * to print as an array of PageRange. 536 * A null values mean print all pages. 537 * Otherwise it must be a non-overlapping array of PageRange 538 * instances ordered in increasing page number. 539 * Page numbers start from 1 (one). 540 * An empty array is considered equivalent to a null array. 541 * <p> 542 * An illegal or unsupported (by the printer) set of page ranges 543 * will be ignored. 544 * <p> 545 * Ranges which exceed beyond the number of pages imaged by the job 546 * during printing do not cause any error. 547 */ 548 public final ObjectProperty pageRangesProperty() { 549 if (pageRanges == null) { 550 pageRanges = new SimpleObjectProperty(JobSettings.this, 551 "pageRanges", null) { 552 553 @Override 554 public void set(Object o) { 555 try { 556 set((PageRange[])o); 557 } catch (ClassCastException e) { 558 return; 559 } 560 } 561 562 public void set(PageRange[] value) { 563 if (!isJobNew()) { 564 return; 565 } 566 if (value == null || value.length == 0 || 567 value[0] == null) { 568 value = null; 569 } else { // validate 570 int len = value.length; 571 PageRange[] arr = new PageRange[len]; 572 int curr = 0; 573 for (int i=0; i<len; i++) { 574 PageRange r = value[i]; 575 if (r == null || curr >= r.getStartPage()) { 576 return; // bad range 577 } 578 curr = r.getEndPage(); 579 arr[i] = r; 580 } 581 value = arr; 582 } 583 // passed validation so its either null, 584 // or an array of ranges in increasing order. 585 super.set(value); 586 } 587 588 @Override 589 public void bind(ObservableValue rawObservable) { 590 throw new RuntimeException 591 ("PageRanges property cannot be bound"); 592 } 593 594 @Override 595 public void bindBidirectional(Property other) { 596 throw new RuntimeException 597 ("PageRanges property cannot be bound"); 598 } 599 }; 600 } 601 return pageRanges; 602 } 603 604 /** 605 * The range of pages to print. null always means all pages. 606 * See {@link pageRangesProperty} for more details. 607 * @return null or an array as specified above 608 */ 609 public PageRange[] getPageRanges() { 610 return (PageRange[])(pageRangesProperty().get()); 611 } 612 613 /** 614 * The range of pages to print as an array of PageRange. 615 * The use of varargs means the common case of a single range 616 * can be auto-boxed. 617 * <code>((PageRange[])null)</code> always means all pages however 618 * since this is the default it is less likely to be used. 619 * See {@link pageRangesProperty} for more details. 620 * @param pages null or a varargs array as specified above 621 */ 622 public void setPageRanges(PageRange... pages) { 623 pageRangesProperty().set((PageRange[])pages); 624 } 625 626 /////////////////////// END PAGE RANGES ///////////////////// 627 628 629 /////////////////////// START SIDES ///////////////////// 630 631 private ObjectProperty<PrintSides> sides = null; 632 633 /** 634 * Property representing an instance of <code>PrintSides</code>. 635 */ 636 public final ObjectProperty<PrintSides> printSidesProperty() { 637 if (sides == null) { 638 sides = new SimpleObjectProperty<PrintSides> 639 (JobSettings.this, "printSides", 640 printerCaps.getDefaultPrintSides()) { 641 642 @Override 643 public void set(PrintSides value) { 644 if (!isJobNew()) { 645 return; 646 } 647 if (value == null) { 648 if (defaultSides) { 649 return; 650 } else { 651 super.set(printerCaps.getDefaultPrintSides()); 652 defaultSides = true; 653 } 654 } 655 if (printerCaps.getSupportedPrintSides().contains(value)) { 656 super.set(value); 657 defaultSides = false; 658 } 659 } 660 661 @Override 662 public void bind(ObservableValue<? extends PrintSides> 663 rawObservable) { 664 throw new RuntimeException 665 ("PrintSides property cannot be bound"); 666 } 667 668 @Override 669 public void bindBidirectional(Property<PrintSides> other) { 670 throw new RuntimeException 671 ("PrintSides property cannot be bound"); 672 } 673 }; 674 } 675 return sides; 676 } 677 678 /** 679 * If a printer supports it, then a job may be printed on 680 * both sides of the media (paper), ie duplex printing. 681 * This method returns the selected setting. 682 * @return the duplex (side) setting. 683 */ 684 public PrintSides getPrintSides() { 685 return printSidesProperty().get(); 686 } 687 688 /** 689 * Set the <code>PrintSides</code> property which controls 690 * duplex printing. 691 * A null value is ignored. 692 * @param sides new setting for number of sides. 693 */ 694 public void setPrintSides(PrintSides sides) { 695 if (sides == getPrintSides()) { 696 return; 697 } 698 printSidesProperty().set(sides); 699 } 700 /////////////////////// END SIDES ///////////////////// 701 702 703 /////////////////////// START COLLATION ///////////////////// 704 705 private ObjectProperty<Collation> collation = null; 706 707 /** 708 * Property representing an instance of <code>Collation</code>. 709 */ 710 public final ObjectProperty<Collation> collationProperty() { 711 if (collation == null) { 712 Collation coll = printerCaps.getDefaultCollation(); 713 collation = new SimpleObjectProperty<Collation> 714 (JobSettings.this, "collation", coll) { 715 716 @Override 717 public void set(Collation value) { 718 if (!isJobNew()) { 719 return; 720 } 721 if (value == null) { 722 if (defaultCollation) { 723 return; 724 } else { 725 super.set(printerCaps.getDefaultCollation()); 726 defaultCollation = true; 727 return; 728 } 729 } 730 if (printerCaps.getSupportedCollations().contains(value)) { 731 super.set(value); 732 defaultCollation = false; 733 } 734 } 735 736 @Override 737 public void bind(ObservableValue<? extends Collation> 738 rawObservable) { 739 throw new RuntimeException 740 ("Collation property cannot be bound"); 741 } 742 743 @Override 744 public void bindBidirectional(Property<Collation> other) { 745 throw new RuntimeException 746 ("Collation property cannot be bound"); 747 } 748 }; 749 } 750 return collation; 751 } 752 753 /** 754 * Collation determines how sheets are sorted when 755 * multiple copies of a document are printed. 756 * As such it is only relevant if 2 or more copies of 757 * a document with 2 more sheets are printed. 758 * A sheet is the physical media, so documents with 2 pages 759 * that are printed N-up, or double-sided may still have only 760 * one sheet. 761 * A collated print job produces documents with sheets 762 * of a document sorted in sequence. 763 * An uncollated job collects together the multiple copies 764 * of the same sheet. 765 * Uncollated (<code>false</false>) is the typical default value. 766 */ 767 public Collation getCollation() { 768 return collationProperty().get(); 769 } 770 771 /** 772 * Set the <code>Collation</code> property. 773 * A null value is ignored. 774 * @param collation new setting for collation 775 */ 776 public void setCollation(Collation collation) { 777 if (collation == getCollation()) { 778 return; 779 } 780 collationProperty().set(collation); 781 } 782 783 /////////////////////// END COLLATION ///////////////////// 784 785 /////////////////////// START COLOUR ///////////////////// 786 787 private ObjectProperty<PrintColor> color = null; 788 789 /** 790 * Property representing an instance of <code>PrintColor</code>. 791 */ 792 public final ObjectProperty<PrintColor> printColorProperty() { 793 if (color == null) { 794 color = new SimpleObjectProperty<PrintColor> 795 (JobSettings.this, "printColor", 796 printerCaps.getDefaultPrintColor()) { 797 798 @Override 799 public void set(PrintColor value) { 800 if (!isJobNew()) { 801 return; 802 } 803 if (value == null) { 804 if (defaultPrintColor) { 805 return; 806 } else { 807 super.set(printerCaps.getDefaultPrintColor()); 808 defaultPrintColor = true; 809 } 810 } 811 if (printerCaps. 812 getSupportedPrintColors().contains(value)) { 813 super.set(value); 814 defaultPrintColor = false; 815 } 816 } 817 818 @Override 819 public void bind(ObservableValue<? extends PrintColor> 820 rawObservable) { 821 throw new RuntimeException 822 ("PrintColor property cannot be bound"); 823 } 824 825 @Override 826 public void bindBidirectional(Property<PrintColor> other) { 827 throw new RuntimeException 828 ("PrintColor property cannot be bound"); 829 } 830 }; 831 } 832 return color; 833 } 834 835 public PrintColor getPrintColor() { 836 return printColorProperty().get(); 837 } 838 839 /** 840 * Set the <code>PrintColor</code> property. 841 * A null value is ignored. 842 * <p> 843 * @param color new setting for print color. 844 */ 845 public void setPrintColor(PrintColor color) { 846 if (color == getPrintColor()) { 847 return; 848 } 849 printColorProperty().set(color); 850 } 851 852 /////////////////////// END COLOUR ///////////////////// 853 854 /////////////////////// START QUALITY ///////////////////// 855 856 private ObjectProperty<PrintQuality> quality = null; 857 858 /** 859 * Property representing an instance of <code>PrintQuality</code>. 860 */ 861 public final ObjectProperty<PrintQuality> printQualityProperty() { 862 if (quality == null) { 863 quality = new SimpleObjectProperty<PrintQuality> 864 (JobSettings.this, "printQuality", 865 printerCaps.getDefaultPrintQuality()) { 866 867 @Override 868 public void set(PrintQuality value) { 869 if (!isJobNew()) { 870 return; 871 } 872 if (value == null) { 873 if (defaultPrintQuality) { 874 return; 875 } else { 876 super.set(printerCaps.getDefaultPrintQuality()); 877 defaultPrintQuality = true; 878 } 879 } 880 if (printerCaps. 881 getSupportedPrintQuality().contains(value)) { 882 super.set(value); 883 defaultPrintQuality = false; 884 } 885 } 886 887 @Override 888 public void bind(ObservableValue<? extends PrintQuality> 889 rawObservable) { 890 throw new RuntimeException 891 ("PrintQuality property cannot be bound"); 892 } 893 894 @Override 895 public void bindBidirectional(Property<PrintQuality> other) { 896 throw new RuntimeException 897 ("PrintQuality property cannot be bound"); 898 } 899 }; 900 } 901 return quality; 902 } 903 904 public PrintQuality getPrintQuality() { 905 return printQualityProperty().get(); 906 } 907 908 /** 909 * Set the <code>PrintQuality</code> property. 910 * A null value is ignored. 911 * <p> 912 * Note that quality and resolution overlapping concepts. 913 * Therefore a printer may support setting one, or the other but 914 * not both. Applications setting these programmatically should 915 * query both properties and select appropriately from the supported 916 * values. If a printer supports non-standard values, code likely 917 * cannot distinguish the printer's interpretation of these values 918 * and is safest to stick to selecting from the standard value that 919 * matches the requirement. 920 * @param quality new setting for print quality. 921 */ 922 public void setPrintQuality(PrintQuality quality) { 923 if (quality == getPrintQuality()) { 924 return; 925 } 926 printQualityProperty().set(quality); 927 } 928 929 /////////////////////// END QUALITY ///////////////////// 930 931 /////////////////////// START RESOLUTION ///////////////////// 932 933 934 private ObjectProperty<PrintResolution> resolution = null; 935 936 /** 937 * Property representing an instance of <code>PrintResolution</code>. 938 */ 939 public final ObjectProperty<PrintResolution> printResolutionProperty() { 940 if (resolution == null) { 941 resolution = new SimpleObjectProperty<PrintResolution> 942 (JobSettings.this, "printResolution", 943 printerCaps.getDefaultPrintResolution()) { 944 945 @Override 946 public void set(PrintResolution value) { 947 if (!isJobNew()) { 948 return; 949 } 950 if (value == null) { 951 if (defaultPrintResolution) { 952 return; 953 } else { 954 super.set(printerCaps.getDefaultPrintResolution()); 955 defaultPrintResolution = true; 956 } 957 } 958 if (printerCaps.getSupportedPrintResolutions(). 959 contains(value)) 960 { 961 super.set(value); 962 defaultPrintResolution = false; 963 } 964 } 965 966 @Override 967 public void bind(ObservableValue<? extends PrintResolution> 968 rawObservable) { 969 throw new RuntimeException 970 ("PrintResolution property cannot be bound"); 971 } 972 973 @Override 974 public void bindBidirectional(Property<PrintResolution> other) 975 { 976 throw new RuntimeException 977 ("PrintResolution property cannot be bound"); 978 } 979 }; 980 } 981 return resolution; 982 } 983 984 /** 985 * 986 */ 987 public PrintResolution getPrintResolution() { 988 return printResolutionProperty().get(); 989 } 990 991 /** 992 * Set the <code>PrintResolution</code> property. 993 * A null value is ignored. 994 * <p> 995 * Note that quality and resolution overlapping concepts. 996 * Therefore a printer may support setting one, or the other but 997 * not both. Applications setting these programmatically should 998 * query both properties and select appropriately from the supported 999 * values. If a printer supports non-standard values, code likely 1000 * cannot distinguish the printer's interpretation of these values 1001 * and is safest to stick to selecting from the standard value that 1002 * matches the requirement. 1003 * @param resolution new setting for print resolution. 1004 */ 1005 public void setPrintResolution(PrintResolution resolution) { 1006 if (resolution == null || resolution == getPrintResolution()) { 1007 return; 1008 } 1009 printResolutionProperty().set(resolution); 1010 } 1011 1012 /////////////////////// END RESOLUTION ///////////////////// 1013 1014 //////////////// START PAPERSOURCE ///////////////// 1015 1016 private ObjectProperty<PaperSource> paperSource = null; 1017 1018 1019 /** 1020 * Property representing an instance of <code>PaperSource</code>. 1021 */ 1022 public final ObjectProperty<PaperSource> paperSourceProperty() { 1023 if (paperSource == null) { 1024 paperSource = new SimpleObjectProperty<PaperSource> 1025 (JobSettings.this, "paperSource", 1026 printerCaps.getDefaultPaperSource()) { 1027 1028 @Override 1029 public void set(PaperSource value) { 1030 if (!isJobNew()) { 1031 return; 1032 } 1033 if (value == null) { 1034 if (defaultPaperSource) { 1035 return; 1036 } else { 1037 super.set(printerCaps.getDefaultPaperSource()); 1038 defaultPaperSource = true; 1039 } 1040 } 1041 if (printerCaps. 1042 getSupportedPaperSources().contains(value)) { 1043 super.set(value); 1044 defaultPaperSource = false; 1045 } 1046 } 1047 1048 @Override 1049 public void bind(ObservableValue<? extends PaperSource> 1050 rawObservable) { 1051 throw new RuntimeException 1052 ("PaperSource property cannot be bound"); 1053 } 1054 1055 @Override 1056 public void bindBidirectional(Property<PaperSource> other) { 1057 throw new RuntimeException 1058 ("PaperSource property cannot be bound"); 1059 } 1060 }; 1061 } 1062 return paperSource; 1063 } 1064 1065 1066 public PaperSource getPaperSource() { 1067 return paperSourceProperty().get(); 1068 } 1069 1070 public void setPaperSource(PaperSource value) { 1071 paperSourceProperty().set(value); 1072 } 1073 1074 //////////////// END PAPERSOURCE ///////////////// 1075 1076 //////////////// START PAGELAYOUT ///////////////// 1077 1078 /* 1079 * Default page needs to originate from the printer, be the 1080 * default for the initial settings on the job. 1081 1082 * having "page" be a property might make sense and perhaps 1083 * for the elts of a paper like orientation. 1084 * But what is the point in listening in on the paper of a Page 1085 * or orientation if a whole new Page is added instead .. 1086 */ 1087 1088 private ObjectProperty<PageLayout> layout = null; 1089 1090 /** 1091 * Property representing an instance of <code>PageLayout</code>. 1092 */ 1093 public final ObjectProperty<PageLayout> pageLayoutProperty() { 1094 if (layout == null) { 1095 layout = new SimpleObjectProperty<PageLayout> 1096 (JobSettings.this, "pageLayout", 1097 printer.getDefaultPageLayout()) { 1098 1099 @Override 1100 public void set(PageLayout value) { 1101 if (!isJobNew()) { 1102 return; 1103 } 1104 if (value == null) { 1105 return; 1106 } 1107 defaultPageLayout = false; 1108 super.set(value); 1109 } 1110 1111 @Override 1112 public void bind(ObservableValue<? extends PageLayout> 1113 rawObservable) { 1114 throw new RuntimeException 1115 ("PageLayout property cannot be bound"); 1116 } 1117 1118 @Override 1119 public void bindBidirectional(Property<PageLayout> other) { 1120 throw new RuntimeException 1121 ("PageLayout property cannot be bound"); 1122 } 1123 }; 1124 } 1125 return layout; 1126 } 1127 1128 /** 1129 * Get the current page layout for this job. 1130 * @return page layout to use for the job. 1131 */ 1132 public PageLayout getPageLayout() { 1133 return pageLayoutProperty().get(); 1134 } 1135 1136 /** 1137 * Set the PageLayout to use. 1138 * @param pageLayout The page layout to use. 1139 */ 1140 public void setPageLayout(PageLayout pageLayout) { 1141 pageLayoutProperty().set(pageLayout); 1142 } 1143 1144 //////////////// END PAGELAYOUT ///////////////// 1145 1146 public String toString() { 1147 String nl = System.lineSeparator(); 1148 return 1149 " Collation = " + getCollation() + nl + 1150 " Copies = " + getCopies() + nl + 1151 " Sides = " + getPrintSides() + nl + 1152 " JobName = " + getJobName() + nl + 1153 " Page ranges = " + getPageRanges() + nl + 1154 " Print color = " + getPrintColor() + nl + 1155 " Print quality = " + getPrintQuality() + nl + 1156 " Print resolution = " + getPrintResolution() + nl + 1157 " Paper source = " + getPaperSource() + nl + 1158 " Page layout = " + getPageLayout(); 1159 } 1160}