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 com.sun.javafx.print.PrintHelper; 029import javafx.beans.property.ReadOnlyObjectProperty; 030import javafx.beans.property.ReadOnlyObjectWrapper; 031import javafx.collections.ObservableSet; 032import javafx.geometry.Rectangle2D; 033 034import static javafx.print.PageOrientation.*; 035 036import com.sun.javafx.tk.PrintPipeline; 037import com.sun.javafx.print.PrinterImpl; 038 039/** 040 * A Printer instance represents the destination for a print job. 041 * <p> 042 * Printers may be enumerated and selected for use with a print job. 043 * <p> 044 * The configuration of the printer default settings are then used to 045 * populate the initial settings for a job. 046 * <p> 047 * Since the availability of printers may change during the 048 * execution of a program, due to administrative actions, 049 * a long running program which has cached a printer which 050 * has since been taken off-line, may create a job using that 051 * instance, but printing will fail. 052 * 053 * @since JavaFX 8 054 */ 055public final class Printer { 056 057 /** 058 * Retrieve the installed printers. 059 * The set of printers may be dynamic. 060 * Consequently there is no guarantee that the result will be 061 * the same from call to call, but should change only as 062 * a result of the default changing in the environment of the 063 * application. 064 * <p>Note: since printers may be installed, but offline, then 065 * the application may want to query the status of a printer 066 * before using it. 067 * @return may be null if there are no printers. 068 * @throws SecurityException if the application does not 069 * have permission to browse printers. 070 */ 071 public static ObservableSet<Printer> getAllPrinters() { 072 SecurityManager security = System.getSecurityManager(); 073 if (security != null) { 074 security.checkPrintJobAccess(); 075 } 076 return PrintPipeline.getPrintPipeline().getAllPrinters(); 077 } 078 079 private static ReadOnlyObjectWrapper<Printer> defaultPrinter; 080 081 private static ReadOnlyObjectWrapper<Printer> defaultPrinterImpl() { 082 SecurityManager security = System.getSecurityManager(); 083 if (security != null) { 084 security.checkPrintJobAccess(); 085 } 086 if (defaultPrinter == null) { 087 Printer p = PrintPipeline.getPrintPipeline().getDefaultPrinter(); 088 defaultPrinter = 089 new ReadOnlyObjectWrapper<Printer>(null, "defaultPrinter", p); 090 } 091 return defaultPrinter; 092 } 093 094 /** 095 * A read only object property representing the current default printer. 096 * If there are no installed printers, the wrapped value will be null. 097 * @throws SecurityException if the application does not 098 * have permission to browse printers. 099 */ 100 public static ReadOnlyObjectProperty<Printer> defaultPrinterProperty() { 101 return defaultPrinterImpl().getReadOnlyProperty(); 102 } 103 104 /** 105 * Retrieve the default printer. 106 * May return null if no printers are installed. 107 * <p> 108 * The configuration of available printers may be dynamic. 109 * Consequently there is no guarantee that the result will be 110 * the same from call to call, but should change only as 111 * a result of the default changing in the environment of the 112 * application. 113 * @return default printer or null. 114 * @throws SecurityException if the application does not 115 * have permission to browse printers. 116 */ 117 public static Printer getDefaultPrinter() { 118 return defaultPrinterProperty().get(); 119 } 120 121 private PrinterImpl impl; 122 123 Printer(PrinterImpl impl) { 124 this.impl = impl; 125 impl.setPrinter(this); 126 } 127 128 PrinterImpl getPrinterImpl() { 129 return impl; 130 } 131 132 /** 133 * Return the name used by the underlying system to identify 134 * the printer to users and/or applications. 135 * @return printer name. 136 */ 137 public String getName() { 138 return impl.getName(); 139 } 140 141 private PrinterAttributes attributes; 142 /** 143 * Retrieves the delegate object encapsulating the printer 144 * attributes and capabilities. 145 * @return printer attributes. 146 */ 147 public PrinterAttributes getPrinterAttributes() { 148 if (attributes == null) { 149 attributes = new PrinterAttributes(impl); 150 } 151 return attributes; 152 } 153 154 /** 155 * Returns the default settings for this printer as would be 156 * used in setting up a job for this printer. 157 * <p> 158 * When a job is first created and associated with a printer, 159 * (typically the default printer), it acquires these default 160 * settings for that printer. 161 * This method always returns a new instance. 162 */ 163 JobSettings getDefaultJobSettings() { 164 return impl.getDefaultJobSettings(); 165 } 166 167 /** 168 * The MarginType is used to determine the printable area of a PageLayout. 169 * @since JavaFX 8 170 */ 171 public static enum MarginType { 172 /** 173 * This requests a default 0.75 inch margin on all sides. 174 * This is considered to be a common default and is supported 175 * by all known printers. However this may be adjusted if the paper is 176 * too small, to ensure that the margins are not more than 50% of 177 * the smaller dimension. Applications that do expect to deal with 178 * such small media should likely be specifying the required margins 179 * explicitly. 180 * In the unlikely event the hardware margin is larger than 0.75" 181 * it will be adjusted to that same hardware minimum on all sides. 182 */ 183 DEFAULT, 184 /** 185 * Request margins are set to be the smallest on each side that 186 * the hardware allows. This creates the greatest printable area 187 * but the margins may not be aesthetic if they are too small, or 188 * there is significant variation on the different sides of the 189 * paper. 190 * <p> 191 * This is is also useful for an application that wants to know 192 * this so it can construct a new PageLayout that fits within 193 * these margins. 194 */ 195 HARDWARE_MINIMUM, 196 /** 197 * Choose the largest of the four hardware margins, and use that for 198 * all for margins, so that the margins are equal on all sides. 199 */ 200 EQUAL, 201 /** 202 * Similar to <code>EQUAL</code>, but it chooses the larger of 203 * the left/right hardware margins and top/bottom hardware margins 204 * separately, so that the top and bottom margins are equal, and 205 * the left and right margins are equal. 206 */ 207 EQUAL_OPPOSITES, 208 209 }; 210 211 private PageLayout defPageLayout; 212 /** 213 * Return the default page layout for this printer. 214 * @return default page layout. 215 */ 216 public PageLayout getDefaultPageLayout() { 217 if (defPageLayout == null) { 218 PrinterAttributes printerCaps = getPrinterAttributes(); 219 defPageLayout = 220 createPageLayout(printerCaps.getDefaultPaper(), 221 printerCaps.getDefaultPageOrientation(), 222 MarginType.DEFAULT); 223 } 224 return defPageLayout; 225 } 226 227 /** 228 * Obtain a new PageLayout instance for this printer using the specified 229 * parameters. 230 * The paper should be one of the supported papers and 231 * the orientation should be a supported orientation. 232 * If the printer cannot support the layout as specified, it 233 * will adjust the returned layout to a supported configuration 234 * @param paper The paper to use 235 * @param orient The orientation to use 236 * @param mType the margin type to use 237 * @return PageLayout based on the specified parameters. 238 * @throws NullPointerException if any of the parameters are null. 239 */ 240 public PageLayout createPageLayout(Paper paper, PageOrientation orient, 241 MarginType mType) { 242 243 if (paper == null || orient == null || mType == null) { 244 throw new NullPointerException("Parameters cannot be null"); 245 } 246 247 // TBD: Adjust paper to a supported one first. 248 Rectangle2D imgArea = impl.printableArea(paper); 249 double width = paper.getWidth() / 72.0; 250 double height = paper.getHeight() / 72.0; 251 double plm = imgArea.getMinX(); 252 double ptm = imgArea.getMinY(); 253 double prm = width - imgArea.getMaxX(); 254 double pbm = height - imgArea.getMaxY(); 255 256 switch (mType) { 257 case DEFAULT: 258 plm = (plm <= 0.75) ? 0.75 : plm; 259 prm = (prm <= 0.75) ? 0.75 : prm; 260 ptm = (ptm <= 0.75) ? 0.75 : ptm; 261 pbm = (pbm <= 0.75) ? 0.75 : pbm; 262 break; 263 case EQUAL: { 264 double maxH = (double)Math.max(plm, prm); 265 double maxV = (double)Math.max(ptm, pbm); 266 double maxM = (double)Math.max(maxH, maxV); 267 plm = prm = ptm = pbm = maxM; 268 break; 269 } 270 case EQUAL_OPPOSITES: { 271 double maxH = (double)Math.max(plm, prm); 272 double maxV = (double)Math.max(ptm, pbm); 273 plm = prm = maxH; 274 ptm = pbm = maxV; 275 break; 276 } 277 case HARDWARE_MINIMUM: 278 default: // Use hardware margins as is. 279 break; 280 } 281 282 double lm, rm, tm, bm; 283 // Now we gave the margins, they need to be adjusted into 284 // the orientation of the paper. If the orientation is not 285 // supported by the printer, then that needs to adjusted first. 286 287 // TBD: Adjust orient to a supported one first. 288 switch (orient) { 289 case LANDSCAPE: lm = pbm; rm = ptm; tm = plm; bm = prm; 290 break; 291 case REVERSE_LANDSCAPE: lm = ptm; rm = pbm; tm = prm; bm = plm; 292 break; 293 case REVERSE_PORTRAIT: lm = prm; rm = plm; tm = pbm; bm = ptm; 294 break; 295 default: lm = plm; rm = prm; tm = ptm; bm = pbm; 296 } 297 lm *= 72; 298 rm *= 72; 299 tm *= 72; 300 bm *= 72; 301 return new PageLayout(paper, orient, lm, rm, tm, bm); 302 } 303 304 /** 305 * Obtain a new PageLayout for this printer using the specified 306 * parameters. 307 * The paper should be one of the supported papers and 308 * the orientation should be a supported orientation. 309 * <p> 310 * Margin values are specified in 1/72 of an inch points. 311 * Margins will be validated against the printer supported margins, 312 * and adjusted if necessary. This method is generally useful to 313 * a client that wants margins that are different (eg wider) 314 * than the default margins, such as 1" at top and bottom and 315 * 0.5" to the left and right. 316 * <p>A client that needs to know what margin values are legal should first 317 * obtain a PageLayout using the <code>HARDWARE_MINIMUM</code> margins. 318 * <p> 319 * If the printer cannot support the layout as specified, it 320 * will adjust the returned layout to a supported configuration 321 * @param paper The paper to use 322 * @param orient The orientation to use 323 * @param lMargin the left margin to use in pts. 324 * @param rMargin the right margin to use in pts. 325 * @param tMargin the top margin to use in pts. 326 * @param bMargin the bottom margin to use in pts. 327 * @return PageLayout based on the specified parameters. 328 * @throws NullPointerException if paper or orient are null. 329 * @throws IllegalArgumentException if any of the margins values are 330 * less than zero. 331 */ 332 public PageLayout createPageLayout(Paper paper, PageOrientation orient, 333 double lMargin, double rMargin, 334 double tMargin, double bMargin) { 335 336 if (paper == null || orient == null) { 337 throw new NullPointerException("Parameters cannot be null"); 338 } 339 if (lMargin < 0 || rMargin < 0 || tMargin < 0 || bMargin < 0) { 340 throw new IllegalArgumentException("Margins must be >= 0"); 341 } 342 // TBD: Adjust paper to a supported one first. 343 Rectangle2D imgArea = impl.printableArea(paper); 344 double width = paper.getWidth() / 72.0; 345 double height = paper.getHeight() / 72.0; 346 double plm = imgArea.getMinX(); 347 double ptm = imgArea.getMinY(); 348 double prm = width - imgArea.getMaxX(); 349 double pbm = height - imgArea.getMaxY(); 350 351 // Check if the requested margins exceed the paper and 352 // if they do, ignore them. 353 boolean useDefault = false; 354 if (orient == PORTRAIT || orient == REVERSE_PORTRAIT) { 355 if ((lMargin + rMargin > width) || 356 (tMargin + bMargin > height)) { 357 useDefault = true; 358 } 359 } else { 360 if ((lMargin + rMargin > height) || 361 (tMargin + bMargin > width)) { 362 useDefault = true; 363 } 364 } 365 if (useDefault) { 366 return createPageLayout(paper, orient, MarginType.DEFAULT); 367 } 368 369 double lm, rm, tm, bm; 370 // TBD: Adjust orient to a supported one first. 371 switch (orient) { 372 case LANDSCAPE: lm = pbm; rm = ptm; tm = plm; bm = prm; 373 break; 374 case REVERSE_LANDSCAPE: lm = ptm; rm = pbm; tm = prm; bm = plm; 375 break; 376 case REVERSE_PORTRAIT: lm = prm; rm = plm; tm = pbm; bm = ptm; 377 break; 378 default: lm = plm; rm = prm; tm = ptm; bm = pbm; 379 } 380 381 lm = (lMargin <= lm) ? lMargin : lm; 382 rm = (rMargin <= rm) ? rMargin : rm; 383 tm = (tMargin <= tm) ? tMargin : tm; 384 bm = (bMargin <= bm) ? bMargin : bm; 385 386 return new PageLayout(paper, orient, lm, rm, tm, bm); 387 } 388 389 @Override public String toString() { 390 return "Printer " + getName(); 391 } 392 393 static { 394 // This is used by classes in different packages to get access to 395 // private and package private methods. 396 PrintHelper.setPrintAccessor(new PrintHelper.PrintAccessor() { 397 398 @Override 399 public PrintResolution createPrintResolution(int fr, int cfr) { 400 return new PrintResolution(fr, cfr); 401 } 402 403 @Override 404 public Paper createPaper(String paperName, 405 double paperWidth, 406 double paperHeight, 407 Paper.Units units) { 408 return new Paper(paperName, paperWidth, paperHeight, units); 409 } 410 411 @Override 412 public PaperSource createPaperSource(String name) { 413 return new PaperSource(name); 414 } 415 416 @Override 417 public JobSettings createJobSettings(Printer printer) { 418 return new JobSettings(printer); 419 } 420 421 /** 422 * PrintAccess is used so that implementation code outside this package 423 * package can construct printer instances using a non-visible API. 424 * We need this since its not valid for applications to create 425 * Printer instances, and we also need to pass in the delegate 426 * impl object which is not intended to be public. 427 */ 428 @Override 429 public Printer createPrinter(PrinterImpl impl) { 430 return new Printer(impl); 431 } 432 433 @Override 434 public PrinterImpl getPrinterImpl(Printer printer) { 435 return printer.getPrinterImpl(); 436 } 437 }); 438 } 439}