Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/print/ServiceUI.java
38829 views
/*1* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.print;2627import java.awt.GraphicsConfiguration;28import java.awt.GraphicsDevice;29import java.awt.GraphicsEnvironment;30import java.awt.HeadlessException;31import java.awt.Dialog;32import java.awt.Frame;33import java.awt.Point;34import java.awt.Rectangle;35import java.awt.Window;36import java.awt.KeyboardFocusManager;37import javax.print.attribute.Attribute;38import javax.print.attribute.AttributeSet;39import javax.print.attribute.PrintRequestAttributeSet;40import javax.print.attribute.standard.Destination;41import javax.print.attribute.standard.Fidelity;4243import sun.print.ServiceDialog;44import sun.print.SunAlternateMedia;4546/** This class is a collection of UI convenience methods which provide a47* graphical user dialog for browsing print services looked up through the Java48* Print Service API.49* <p>50* The dialogs follow a standard pattern of acting as a continue/cancel option51*for a user as well as allowing the user to select the print service to use52*and specify choices such as paper size and number of copies.53* <p>54* <p>55* The dialogs are designed to work with pluggable print services though the56* public APIs of those print services.57* <p>58* If a print service provides any vendor extensions these may be made59* accessible to the user through a vendor supplied tab panel Component.60* Such a vendor extension is encouraged to use Swing! and to support its61* accessibility APIs.62* The vendor extensions should return the settings as part of the63* AttributeSet.64* Applications which want to preserve the user settings should use those65* settings to specify the print job.66* Note that this class is not referenced by any other part of the Java67* Print Service and may not be included in profiles which cannot depend68* on the presence of the AWT packages.69*/7071public class ServiceUI {727374/**75* Presents a dialog to the user for selecting a print service (printer).76* It is displayed at the location specified by the application and77* is modal.78* If the specification is invalid or would make the dialog not visible it79* will be displayed at a location determined by the implementation.80* The dialog blocks its calling thread and is application modal.81* <p>82* The dialog may include a tab panel with custom UI lazily obtained from83* the PrintService's ServiceUIFactory when the PrintService is browsed.84* The dialog will attempt to locate a MAIN_UIROLE first as a JComponent,85* then as a Panel. If there is no ServiceUIFactory or no matching role86* the custom tab will be empty or not visible.87* <p>88* The dialog returns the print service selected by the user if the user89* OK's the dialog and null if the user cancels the dialog.90* <p>91* An application must pass in an array of print services to browse.92* The array must be non-null and non-empty.93* Typically an application will pass in only PrintServices capable94* of printing a particular document flavor.95* <p>96* An application may pass in a PrintService to be initially displayed.97* A non-null parameter must be included in the array of browsable98* services.99* If this parameter is null a service is chosen by the implementation.100* <p>101* An application may optionally pass in the flavor to be printed.102* If this is non-null choices presented to the user can be better103* validated against those supported by the services.104* An application must pass in a PrintRequestAttributeSet for returning105* user choices.106* On calling the PrintRequestAttributeSet may be empty, or may contain107* application-specified values.108* <p>109* These are used to set the initial settings for the initially110* displayed print service. Values which are not supported by the print111* service are ignored. As the user browses print services, attributes112* and values are copied to the new display. If a user browses a113* print service which does not support a particular attribute-value, the114* default for that service is used as the new value to be copied.115* <p>116* If the user cancels the dialog, the returned attributes will not reflect117* any changes made by the user.118*119* A typical basic usage of this method may be :120* <pre>{@code121* PrintService[] services = PrintServiceLookup.lookupPrintServices(122* DocFlavor.INPUT_STREAM.JPEG, null);123* PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();124* if (services.length > 0) {125* PrintService service = ServiceUI.printDialog(null, 50, 50,126* services, services[0],127* null,128* attributes);129* if (service != null) {130* ... print ...131* }132* }133* }</pre>134* <p>135136* @param gc used to select screen. null means primary or default screen.137* @param x location of dialog including border in screen coordinates138* @param y location of dialog including border in screen coordinates139* @param services to be browsable, must be non-null.140* @param defaultService - initial PrintService to display.141* @param flavor - the flavor to be printed, or null.142* @param attributes on input is the initial application supplied143* preferences. This cannot be null but may be empty.144* On output the attributes reflect changes made by the user.145* @return print service selected by the user, or null if the user146* cancelled the dialog.147* @throws HeadlessException if GraphicsEnvironment.isHeadless()148* returns true.149* @throws IllegalArgumentException if services is null or empty,150* or attributes is null, or the initial PrintService is not in the151* list of browsable services.152*/153public static PrintService printDialog(GraphicsConfiguration gc,154int x, int y,155PrintService[] services,156PrintService defaultService,157DocFlavor flavor,158PrintRequestAttributeSet attributes)159throws HeadlessException160{161int defaultIndex = -1;162163if (GraphicsEnvironment.isHeadless()) {164throw new HeadlessException();165} else if ((services == null) || (services.length == 0)) {166throw new IllegalArgumentException("services must be non-null " +167"and non-empty");168} else if (attributes == null) {169throw new IllegalArgumentException("attributes must be non-null");170}171172if (defaultService != null) {173for (int i = 0; i < services.length; i++) {174if (services[i].equals(defaultService)) {175defaultIndex = i;176break;177}178}179180if (defaultIndex < 0) {181throw new IllegalArgumentException("services must contain " +182"defaultService");183}184} else {185defaultIndex = 0;186}187188// For now we set owner to null. In the future, it may be passed189// as an argument.190Window owner = null;191192Rectangle gcBounds = (gc == null) ? GraphicsEnvironment.193getLocalGraphicsEnvironment().getDefaultScreenDevice().194getDefaultConfiguration().getBounds() : gc.getBounds();195196ServiceDialog dialog;197if (owner instanceof Frame) {198dialog = new ServiceDialog(gc,199x + gcBounds.x,200y + gcBounds.y,201services, defaultIndex,202flavor, attributes,203(Frame)owner);204} else {205dialog = new ServiceDialog(gc,206x + gcBounds.x,207y + gcBounds.y,208services, defaultIndex,209flavor, attributes,210(Dialog)owner);211}212Rectangle dlgBounds = dialog.getBounds();213214// get union of all GC bounds215GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();216GraphicsDevice[] gs = ge.getScreenDevices();217for (int j=0; j<gs.length; j++) {218gcBounds =219gcBounds.union(gs[j].getDefaultConfiguration().getBounds());220}221222// if portion of dialog is not within the gc boundary223if (!gcBounds.contains(dlgBounds)) {224// put in the center relative to parent frame/dialog225dialog.setLocationRelativeTo(owner);226}227dialog.show();228229if (dialog.getStatus() == ServiceDialog.APPROVE) {230PrintRequestAttributeSet newas = dialog.getAttributes();231Class dstCategory = Destination.class;232Class amCategory = SunAlternateMedia.class;233Class fdCategory = Fidelity.class;234235if (attributes.containsKey(dstCategory) &&236!newas.containsKey(dstCategory))237{238attributes.remove(dstCategory);239}240241if (attributes.containsKey(amCategory) &&242!newas.containsKey(amCategory))243{244attributes.remove(amCategory);245}246247attributes.addAll(newas);248249Fidelity fd = (Fidelity)attributes.get(fdCategory);250if (fd != null) {251if (fd == Fidelity.FIDELITY_TRUE) {252removeUnsupportedAttributes(dialog.getPrintService(),253flavor, attributes);254}255}256}257258return dialog.getPrintService();259}260261/**262* POSSIBLE FUTURE API: This method may be used down the road if we263* decide to allow developers to explicitly display a "page setup" dialog.264* Currently we use that functionality internally for the AWT print model.265*/266/*267public static void pageDialog(GraphicsConfiguration gc,268int x, int y,269PrintService service,270DocFlavor flavor,271PrintRequestAttributeSet attributes)272throws HeadlessException273{274if (GraphicsEnvironment.isHeadless()) {275throw new HeadlessException();276} else if (service == null) {277throw new IllegalArgumentException("service must be non-null");278} else if (attributes == null) {279throw new IllegalArgumentException("attributes must be non-null");280}281282ServiceDialog dialog = new ServiceDialog(gc, x, y, service,283flavor, attributes);284dialog.show();285286if (dialog.getStatus() == ServiceDialog.APPROVE) {287PrintRequestAttributeSet newas = dialog.getAttributes();288Class amCategory = SunAlternateMedia.class;289290if (attributes.containsKey(amCategory) &&291!newas.containsKey(amCategory))292{293attributes.remove(amCategory);294}295296attributes.addAll(newas.values());297}298299dialog.getOwner().dispose();300}301*/302303/**304* Removes any attributes from the given AttributeSet that are305* unsupported by the given PrintService/DocFlavor combination.306*/307private static void removeUnsupportedAttributes(PrintService ps,308DocFlavor flavor,309AttributeSet aset)310{311AttributeSet asUnsupported = ps.getUnsupportedAttributes(flavor,312aset);313314if (asUnsupported != null) {315Attribute[] usAttrs = asUnsupported.toArray();316317for (int i=0; i<usAttrs.length; i++) {318Class category = usAttrs[i].getCategory();319320if (ps.isAttributeCategorySupported(category)) {321Attribute attr =322(Attribute)ps.getDefaultAttributeValue(category);323324if (attr != null) {325aset.add(attr);326} else {327aset.remove(category);328}329} else {330aset.remove(category);331}332}333}334}335}336337338