src/share/classes/sun/print/ServiceDialog.java

Print this page




 378         if (source == btnApprove) {
 379             approved = true;
 380 
 381             if (pnlGeneral != null) {
 382                 if (pnlGeneral.isPrintToFileRequested()) {
 383                     approved = showFileChooser();
 384                 } else {
 385                     asCurrent.remove(Destination.class);
 386                 }
 387             }
 388         }
 389 
 390         dispose(approved ? APPROVE : CANCEL);
 391     }
 392 
 393     /**
 394      * Displays a JFileChooser that allows the user to select the destination
 395      * for "Print To File"
 396      */
 397     private boolean showFileChooser() {
 398         Class dstCategory = Destination.class;
 399 
 400         Destination dst = (Destination)asCurrent.get(dstCategory);
 401         if (dst == null) {
 402             dst = (Destination)asOriginal.get(dstCategory);
 403             if (dst == null) {
 404                 dst = (Destination)psCurrent.getDefaultAttributeValue(dstCategory);
 405                 // "dst" should not be null. The following code
 406                 // is only added to safeguard against a possible
 407                 // buggy implementation of a PrintService having a
 408                 // null default Destination.
 409                 if (dst == null) {
 410                     try {
 411                         dst = new Destination(new URI("file:out.prn"));
 412                     } catch (URISyntaxException e) {
 413                     }
 414                 }
 415             }
 416         }
 417 
 418         File fileDest;


 446             asCurrent.remove(dstCategory);
 447         }
 448 
 449         return (returnVal == JFileChooser.APPROVE_OPTION);
 450     }
 451 
 452     /**
 453      * Updates each of the top level panels
 454      */
 455     private void updatePanels() {
 456         pnlGeneral.updateInfo();
 457         pnlPageSetup.updateInfo();
 458         pnlAppearance.updateInfo();
 459     }
 460 
 461     /**
 462      * Initialize ResourceBundle
 463      */
 464     public static void initResource() {
 465         java.security.AccessController.doPrivileged(
 466             new java.security.PrivilegedAction() {
 467                 public Object run() {
 468                     try {
 469                         messageRB = ResourceBundle.getBundle(strBundle);
 470                         return null;
 471                     } catch (java.util.MissingResourceException e) {
 472                         throw new Error("Fatal: Resource for ServiceUI " +
 473                                         "is missing");
 474                     }
 475                 }
 476             }
 477         );
 478     }
 479 
 480     /**
 481      * Returns message string from resource
 482      */
 483     public static String getMsg(String key) {
 484         try {
 485             return removeMnemonics(messageRB.getString(key));
 486         } catch (java.util.MissingResourceException e) {


 512     }
 513 
 514 
 515     /**
 516      * Returns mnemonic character from resource
 517      */
 518     private static char getMnemonic(String key) {
 519         String str = messageRB.getString(key).replace("&&", "");
 520         int index = str.indexOf('&');
 521         if (0 <= index && index < str.length() - 1) {
 522             char c = str.charAt(index + 1);
 523             return Character.toUpperCase(c);
 524         } else {
 525             return (char)0;
 526         }
 527     }
 528 
 529     /**
 530      * Returns the mnemonic as a KeyEvent.VK constant from the resource.
 531      */
 532     static Class _keyEventClazz = null;
 533     private static int getVKMnemonic(String key) {
 534         String s = String.valueOf(getMnemonic(key));
 535         if ( s == null || s.length() != 1) {
 536             return 0;
 537         }
 538         String vkString = "VK_" + s.toUpperCase();
 539 
 540         try {
 541             if (_keyEventClazz == null) {
 542                 _keyEventClazz= Class.forName("java.awt.event.KeyEvent",
 543                                  true, (ServiceDialog.class).getClassLoader());
 544             }
 545             Field field = _keyEventClazz.getDeclaredField(vkString);
 546             int value = field.getInt(null);
 547             return value;
 548         } catch (Exception e) {
 549         }
 550         return 0;
 551     }
 552 
 553     /**
 554      * Returns URL for image resource
 555      */
 556     private static URL getImageResource(final String key) {
 557         URL url = (URL)java.security.AccessController.doPrivileged(
 558                        new java.security.PrivilegedAction() {
 559                 public Object run() {
 560                     URL url = ServiceDialog.class.getResource(
 561                                                   "resources/" + key);
 562                     return url;
 563                 }
 564         });
 565 
 566         if (url == null) {
 567             throw new Error("Fatal: Resource for ServiceUI is broken; " +
 568                             "there is no " + key + " key in resource");
 569         }
 570 
 571         return url;
 572     }
 573 
 574     /**
 575      * Creates a new JButton and sets its text, mnemonic, and ActionListener
 576      */
 577     private static JButton createButton(String key, ActionListener al) {
 578         JButton btn = new JButton(getMsg(key));
 579         btn.setMnemonic(getMnemonic(key));


 693 
 694         public boolean isPrintToFileRequested() {
 695             return (pnlPrintService.isPrintToFileSelected());
 696         }
 697 
 698         public void updateInfo() {
 699             pnlPrintService.updateInfo();
 700             pnlPrintRange.updateInfo();
 701             pnlCopies.updateInfo();
 702         }
 703     }
 704 
 705     @SuppressWarnings("serial") // Superclass is not serializable across versions
 706     private class PrintServicePanel extends JPanel
 707         implements ActionListener, ItemListener, PopupMenuListener
 708     {
 709         private final String strTitle = getMsg("border.printservice");
 710         private FilePermission printToFilePermission;
 711         private JButton btnProperties;
 712         private JCheckBox cbPrintToFile;
 713         private JComboBox cbName;
 714         private JLabel lblType, lblStatus, lblInfo;
 715         private ServiceUIFactory uiFactory;
 716         private boolean changedService = false;
 717         private boolean filePermission;
 718 
 719         public PrintServicePanel() {
 720             super();
 721 
 722             uiFactory = psCurrent.getServiceUIFactory();
 723 
 724             GridBagLayout gridbag = new GridBagLayout();
 725             GridBagConstraints c = new GridBagConstraints();
 726 
 727             setLayout(gridbag);
 728             setBorder(BorderFactory.createTitledBorder(strTitle));
 729 
 730             String[] psnames = new String[services.length];
 731             for (int i = 0; i < psnames.length; i++) {
 732                 psnames[i] = services[i].getName();
 733             }
 734             cbName = new JComboBox(psnames);
 735             cbName.setSelectedIndex(defaultServiceIndex);
 736             cbName.addItemListener(this);
 737             cbName.addPopupMenuListener(this);
 738 
 739             c.fill = GridBagConstraints.BOTH;
 740             c.insets = compInsets;
 741 
 742             c.weightx = 0.0;
 743             JLabel lblName = new JLabel(getMsg("label.psname"), JLabel.TRAILING);
 744             lblName.setDisplayedMnemonic(getMnemonic("label.psname"));
 745             lblName.setLabelFor(cbName);
 746             addToGB(lblName, this, gridbag, c);
 747             c.weightx = 1.0;
 748             c.gridwidth = GridBagConstraints.RELATIVE;
 749             addToGB(cbName, this, gridbag, c);
 750             c.weightx = 0.0;
 751             c.gridwidth = GridBagConstraints.REMAINDER;
 752             btnProperties = createButton("button.properties", this);
 753             addToGB(btnProperties, this, gridbag, c);
 754 


 907             }
 908         }
 909 
 910         /**
 911          * Break this out as it may be useful when we allow API to
 912          * specify printing to a file. In that case its probably right
 913          * to throw a SecurityException if the permission is not granted.
 914          */
 915         private void throwPrintToFile() {
 916             SecurityManager security = System.getSecurityManager();
 917             if (security != null) {
 918                 if (printToFilePermission == null) {
 919                     printToFilePermission =
 920                         new FilePermission("<<ALL FILES>>", "read,write");
 921                 }
 922                 security.checkPermission(printToFilePermission);
 923             }
 924         }
 925 
 926         public void updateInfo() {
 927             Class dstCategory = Destination.class;
 928             boolean dstSupported = false;
 929             boolean dstSelected = false;
 930             boolean dstAllowed = filePermission ?
 931                 allowedToPrintToFile() : false;
 932 
 933             // setup Destination (print-to-file) widgets
 934             if (psCurrent.isAttributeCategorySupported(dstCategory)) {
 935                 dstSupported = true;
 936             }
 937             Destination dst = (Destination)asCurrent.get(dstCategory);
 938             if (dst != null) {
 939                 dstSelected = true;
 940             }
 941             cbPrintToFile.setEnabled(dstSupported && dstAllowed);
 942             cbPrintToFile.setSelected(dstSelected && dstAllowed
 943                                       && dstSupported);
 944 
 945             // setup PrintService information widgets
 946             Attribute type = psCurrent.getAttribute(PrinterMakeAndModel.class);
 947             if (type != null) {


1106                 max = Integer.parseInt(strTo);
1107             } catch (NumberFormatException e) {
1108                 max = min;
1109             }
1110 
1111             if (min < 1) {
1112                 min = 1;
1113                 tfRangeFrom.setValue(new Integer(1));
1114             }
1115 
1116             if (max < min) {
1117                 max = min;
1118                 tfRangeTo.setValue(new Integer(min));
1119             }
1120 
1121             PageRanges pr = new PageRanges(min, max);
1122             asCurrent.add(pr);
1123         }
1124 
1125         public void updateInfo() {
1126             Class prCategory = PageRanges.class;
1127             prSupported = false;
1128 
1129             if (psCurrent.isAttributeCategorySupported(prCategory) ||
1130                    isAWT) {
1131                 prSupported = true;
1132             }
1133 
1134             SunPageSelection select = SunPageSelection.ALL;
1135             int min = 1;
1136             int max = 1;
1137 
1138             PageRanges pr = (PageRanges)asCurrent.get(prCategory);
1139             if (pr != null) {
1140                 if (!pr.equals(prAll)) {
1141                     select = SunPageSelection.RANGE;
1142 
1143                     int[][] members = pr.getMembers();
1144                     if ((members.length > 0) &&
1145                         (members[0].length > 1)) {
1146                         min = members[0][0];


1223                 asCurrent.add(SheetCollate.UNCOLLATED);
1224             }
1225         }
1226 
1227         public void stateChanged(ChangeEvent e) {
1228             updateCollateCB();
1229 
1230             asCurrent.add(new Copies(snModel.getNumber().intValue()));
1231         }
1232 
1233         private void updateCollateCB() {
1234             int num = snModel.getNumber().intValue();
1235             if (isAWT) {
1236                 cbCollate.setEnabled(true);
1237             } else {
1238                 cbCollate.setEnabled((num > 1) && scSupported);
1239             }
1240         }
1241 
1242         public void updateInfo() {
1243             Class cpCategory = Copies.class;
1244             Class csCategory = CopiesSupported.class;
1245             Class scCategory = SheetCollate.class;
1246             boolean cpSupported = false;
1247             scSupported = false;
1248 
1249             // setup Copies spinner
1250             if (psCurrent.isAttributeCategorySupported(cpCategory)) {
1251                 cpSupported = true;
1252             }
1253             CopiesSupported cs =
1254                 (CopiesSupported)psCurrent.getSupportedAttributeValues(
1255                                                        cpCategory, null, null);
1256             if (cs == null) {
1257                 cs = new CopiesSupported(1, 999);
1258             }
1259             Copies cp = (Copies)asCurrent.get(cpCategory);
1260             if (cp == null) {
1261                 cp = (Copies)psCurrent.getDefaultAttributeValue(cpCategory);
1262                 if (cp == null) {
1263                     cp = new Copies(1);
1264                 }
1265             }


1508                 }
1509                 if (tf == topMargin && val.equals(tmObj)) {
1510                     return;
1511                 }
1512                 if (tf == bottomMargin && val.equals(bmObj)) {
1513                     return;
1514                 }
1515             }
1516 
1517             Float lmTmpObj = (Float)leftMargin.getValue();
1518             Float rmTmpObj = (Float)rightMargin.getValue();
1519             Float tmTmpObj = (Float)topMargin.getValue();
1520             Float bmTmpObj = (Float)bottomMargin.getValue();
1521 
1522             float lm = lmTmpObj.floatValue();
1523             float rm = rmTmpObj.floatValue();
1524             float tm = tmTmpObj.floatValue();
1525             float bm = bmTmpObj.floatValue();
1526 
1527             /* adjust for orientation */
1528             Class orCategory = OrientationRequested.class;
1529             OrientationRequested or =
1530                 (OrientationRequested)asCurrent.get(orCategory);
1531 
1532             if (or == null) {
1533                 or = (OrientationRequested)
1534                      psCurrent.getDefaultAttributeValue(orCategory);
1535             }
1536 
1537             float tmp;
1538             if (or == OrientationRequested.REVERSE_PORTRAIT) {
1539                 tmp = lm; lm = rm; rm = tmp;
1540                 tmp = tm; tm = bm; bm = tmp;
1541             } else if (or == OrientationRequested.LANDSCAPE) {
1542                 tmp = lm;
1543                 lm = tm;
1544                 tm = rm;
1545                 rm = bm;
1546                 bm = tmp;
1547             } else if (or == OrientationRequested.REVERSE_LANDSCAPE) {
1548                 tmp = lm;


1572                     topMargin.setValue(tmObj);
1573                     bottomMargin.setValue(bmObj);
1574 
1575                 }
1576             }
1577         }
1578 
1579         /*
1580          * This method either accepts the values and creates a new
1581          * MediaPrintableArea, or does nothing.
1582          * It should not attempt to create a printable area from anything
1583          * other than the exact values passed in.
1584          * But REMIND/TBD: it would be user friendly to replace margins the
1585          * user entered but are out of bounds with the minimum.
1586          * At that point this method will need to take responsibility for
1587          * updating the "stored" values and the UI.
1588          */
1589         private MediaPrintableArea validateMargins(float lm, float rm,
1590                                                    float tm, float bm) {
1591 
1592             Class mpaCategory = MediaPrintableArea.class;
1593             MediaPrintableArea mpa;
1594             MediaPrintableArea mpaMax = null;
1595             MediaSize mediaSize = null;
1596 
1597             Media media = (Media)asCurrent.get(Media.class);
1598             if (media == null || !(media instanceof MediaSizeName)) {
1599                 media = (Media)psCurrent.getDefaultAttributeValue(Media.class);
1600             }
1601             if (media != null && (media instanceof MediaSizeName)) {
1602                 MediaSizeName msn = (MediaSizeName)media;
1603                 mediaSize = MediaSize.getMediaSizeForName(msn);
1604             }
1605             if (mediaSize == null) {
1606                 mediaSize = new MediaSize(8.5f, 11f, Size2DSyntax.INCH);
1607             }
1608 
1609             if (media != null) {
1610                 PrintRequestAttributeSet tmpASet =
1611                     new HashPrintRequestAttributeSet(asCurrent);
1612                 tmpASet.add(media);


1654          *
1655          * If an application doesn't define a MediaPrintableArea, we need to
1656          * create a suitable one, this is created using the specified (or
1657          * default) Media and default 1 inch margins. This is validated
1658          * against the paper in case this is too large for tiny media.
1659          */
1660         public void updateInfo() {
1661 
1662             if (isAWT) {
1663                 leftMargin.setEnabled(false);
1664                 rightMargin.setEnabled(false);
1665                 topMargin.setEnabled(false);
1666                 bottomMargin.setEnabled(false);
1667                 lblLeft.setEnabled(false);
1668                 lblRight.setEnabled(false);
1669                 lblTop.setEnabled(false);
1670                 lblBottom.setEnabled(false);
1671                 return;
1672             }
1673 
1674             Class mpaCategory = MediaPrintableArea.class;
1675             MediaPrintableArea mpa =
1676                  (MediaPrintableArea)asCurrent.get(mpaCategory);
1677             MediaPrintableArea mpaMax = null;
1678             MediaSize mediaSize = null;
1679 
1680             Media media = (Media)asCurrent.get(Media.class);
1681             if (media == null || !(media instanceof MediaSizeName)) {
1682                 media = (Media)psCurrent.getDefaultAttributeValue(Media.class);
1683             }
1684             if (media != null && (media instanceof MediaSizeName)) {
1685                 MediaSizeName msn = (MediaSizeName)media;
1686                 mediaSize = MediaSize.getMediaSizeForName(msn);
1687             }
1688             if (mediaSize == null) {
1689                 mediaSize = new MediaSize(8.5f, 11f, Size2DSyntax.INCH);
1690             }
1691 
1692             if (media != null) {
1693                 PrintRequestAttributeSet tmpASet =
1694                     new HashPrintRequestAttributeSet(asCurrent);


1828                 asCurrent.add(mpa);
1829             }
1830 
1831             /* We now have a valid printable area.
1832              * Turn it into margins, using the mediaSize
1833              */
1834             lmVal = pax;
1835             tmVal = pay;
1836             rmVal = mediaSize.getX(units) - pax - paw;
1837             bmVal = mediaSize.getY(units) - pay - pah;
1838 
1839             lmObj = new Float(lmVal);
1840             rmObj = new Float(rmVal);
1841             tmObj = new Float(tmVal);
1842             bmObj = new Float(bmVal);
1843 
1844             /* Now we know the values to use, we need to assign them
1845              * to the fields appropriate for the orientation.
1846              * Note: if orientation changes this method must be called.
1847              */
1848             Class orCategory = OrientationRequested.class;
1849             OrientationRequested or =
1850                 (OrientationRequested)asCurrent.get(orCategory);
1851 
1852             if (or == null) {
1853                 or = (OrientationRequested)
1854                      psCurrent.getDefaultAttributeValue(orCategory);
1855             }
1856 
1857             Float tmp;
1858 
1859             if (or == OrientationRequested.REVERSE_PORTRAIT) {
1860                 tmp = lmObj; lmObj = rmObj; rmObj = tmp;
1861                 tmp = tmObj; tmObj = bmObj; bmObj = tmp;
1862             }  else if (or == OrientationRequested.LANDSCAPE) {
1863                 tmp = lmObj;
1864                 lmObj = bmObj;
1865                 bmObj = rmObj;
1866                 rmObj = tmObj;
1867                 tmObj = tmp;
1868             }  else if (or == OrientationRequested.REVERSE_LANDSCAPE) {
1869                 tmp = lmObj;
1870                 lmObj = tmObj;
1871                 tmObj = rmObj;
1872                 rmObj = bmObj;
1873                 bmObj = tmp;
1874             }
1875 
1876             leftMargin.setValue(lmObj);
1877             rightMargin.setValue(rmObj);
1878             topMargin.setValue(tmObj);
1879             bottomMargin.setValue(bmObj);
1880         }
1881     }
1882 
1883     @SuppressWarnings("serial") // Superclass is not serializable across versions
1884     private class MediaPanel extends JPanel implements ItemListener {
1885 
1886         private final String strTitle = getMsg("border.media");
1887         private JLabel lblSize, lblSource;
1888         private JComboBox cbSize, cbSource;
1889         private Vector sizes = new Vector();
1890         private Vector sources = new Vector();
1891         private MarginsPanel pnlMargins = null;
1892 
1893         public MediaPanel() {
1894             super();
1895 
1896             GridBagLayout gridbag = new GridBagLayout();
1897             GridBagConstraints c = new GridBagConstraints();
1898 
1899             setLayout(gridbag);
1900             setBorder(BorderFactory.createTitledBorder(strTitle));
1901 
1902             cbSize = new JComboBox();
1903             cbSource = new JComboBox();
1904 
1905             c.fill = GridBagConstraints.BOTH;
1906             c.insets = compInsets;
1907             c.weighty = 1.0;
1908 
1909             c.weightx = 0.0;
1910             lblSize = new JLabel(getMsg("label.size"), JLabel.TRAILING);
1911             lblSize.setDisplayedMnemonic(getMnemonic("label.size"));
1912             lblSize.setLabelFor(cbSize);
1913             addToGB(lblSize, this, gridbag, c);
1914             c.weightx = 1.0;
1915             c.gridwidth = GridBagConstraints.REMAINDER;
1916             addToGB(cbSize, this, gridbag, c);
1917 
1918             c.weightx = 0.0;
1919             c.gridwidth = 1;
1920             lblSource = new JLabel(getMsg("label.source"), JLabel.TRAILING);
1921             lblSource.setDisplayedMnemonic(getMnemonic("label.source"));
1922             lblSource.setLabelFor(cbSource);
1923             addToGB(lblSource, this, gridbag, c);


1933                 newkey = newkey.replace('#', 'n');
1934 
1935                 return messageRB.getString(newkey);
1936             } catch (java.util.MissingResourceException e) {
1937                 return key;
1938             }
1939         }
1940 
1941         public void itemStateChanged(ItemEvent e) {
1942             Object source = e.getSource();
1943 
1944             if (e.getStateChange() == ItemEvent.SELECTED) {
1945                 if (source == cbSize) {
1946                     int index = cbSize.getSelectedIndex();
1947 
1948                     if ((index >= 0) && (index < sizes.size())) {
1949                         if ((cbSource.getItemCount() > 1) &&
1950                             (cbSource.getSelectedIndex() >= 1))
1951                         {
1952                             int src = cbSource.getSelectedIndex() - 1;
1953                             MediaTray mt = (MediaTray)sources.get(src);
1954                             asCurrent.add(new SunAlternateMedia(mt));
1955                         }
1956                         asCurrent.add((MediaSizeName)sizes.get(index));
1957                     }
1958                 } else if (source == cbSource) {
1959                     int index = cbSource.getSelectedIndex();
1960 
1961                     if ((index >= 1) && (index < (sources.size() + 1))) {
1962                        asCurrent.remove(SunAlternateMedia.class);
1963                        MediaTray newTray = (MediaTray)sources.get(index - 1);
1964                        Media m = (Media)asCurrent.get(Media.class);
1965                        if (m == null || m instanceof MediaTray) {
1966                            asCurrent.add(newTray);
1967                        } else if (m instanceof MediaSizeName) {
1968                            MediaSizeName msn = (MediaSizeName)m;
1969                            Media def = (Media)psCurrent.getDefaultAttributeValue(Media.class);
1970                            if (def instanceof MediaSizeName && def.equals(msn)) {
1971                                asCurrent.add(newTray);
1972                            } else {
1973                                /* Non-default paper size, so need to store tray
1974                                 * as SunAlternateMedia
1975                                 */
1976                                asCurrent.add(new SunAlternateMedia(newTray));
1977                            }
1978                        }
1979                     } else if (index == 0) {
1980                         asCurrent.remove(SunAlternateMedia.class);
1981                         if (cbSize.getItemCount() > 0) {
1982                             int size = cbSize.getSelectedIndex();
1983                             asCurrent.add((MediaSizeName)sizes.get(size));
1984                         }
1985                     }
1986                 }
1987             // orientation affects display of margins.
1988                 if (pnlMargins != null) {
1989                     pnlMargins.updateInfo();
1990                 }
1991             }
1992         }
1993 
1994 
1995         /* this is ad hoc to keep things simple */
1996         public void addMediaListener(MarginsPanel pnl) {
1997             pnlMargins = pnl;
1998         }
1999         public void updateInfo() {
2000             Class mdCategory = Media.class;
2001             Class amCategory = SunAlternateMedia.class;
2002             boolean mediaSupported = false;
2003 
2004             cbSize.removeItemListener(this);
2005             cbSize.removeAllItems();
2006             cbSource.removeItemListener(this);
2007             cbSource.removeAllItems();
2008             cbSource.addItem(getMediaName("auto-select"));
2009 
2010             sizes.clear();
2011             sources.clear();
2012 
2013             if (psCurrent.isAttributeCategorySupported(mdCategory)) {
2014                 mediaSupported = true;
2015 
2016                 Object values =
2017                     psCurrent.getSupportedAttributeValues(mdCategory,
2018                                                           docFlavor,
2019                                                           asCurrent);
2020 
2021                 if (values instanceof Media[]) {
2022                     Media[] media = (Media[])values;
2023 
2024                     for (int i = 0; i < media.length; i++) {
2025                         Media medium = media[i];
2026 
2027                         if (medium instanceof MediaSizeName) {
2028                             sizes.add(medium);
2029                             cbSize.addItem(getMediaName(medium.toString()));
2030                         } else if (medium instanceof MediaTray) {
2031                             sources.add(medium);
2032                             cbSource.addItem(getMediaName(medium.toString()));
2033                         }
2034                     }
2035                 }
2036             }
2037 
2038             boolean msSupported = (mediaSupported && (sizes.size() > 0));
2039             lblSize.setEnabled(msSupported);
2040             cbSize.setEnabled(msSupported);
2041 
2042             if (isAWT) {
2043                 cbSource.setEnabled(false);
2044                 lblSource.setEnabled(false);
2045             } else {
2046                 cbSource.setEnabled(mediaSupported);
2047             }
2048 
2049             if (mediaSupported) {
2050 
2051                 Media medium = (Media)asCurrent.get(mdCategory);


2078                     } else if (medium instanceof MediaTray) {
2079                         MediaTray mt = (MediaTray)medium;
2080                         cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
2081                     }
2082                 } else {
2083                     cbSize.setSelectedIndex(sizes.size() > 0 ? 0 : -1);
2084                     cbSource.setSelectedIndex(0);
2085                 }
2086 
2087                 SunAlternateMedia alt = (SunAlternateMedia)asCurrent.get(amCategory);
2088                 if (alt != null) {
2089                     Media md = alt.getMedia();
2090                     if (md instanceof MediaTray) {
2091                         MediaTray mt = (MediaTray)md;
2092                         cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
2093                     }
2094                 }
2095 
2096                 int selIndex = cbSize.getSelectedIndex();
2097                 if ((selIndex >= 0) && (selIndex < sizes.size())) {
2098                   asCurrent.add((MediaSizeName)sizes.get(selIndex));
2099                 }
2100 
2101                 selIndex = cbSource.getSelectedIndex();
2102                 if ((selIndex >= 1) && (selIndex < (sources.size()+1))) {
2103                     MediaTray mt = (MediaTray)sources.get(selIndex-1);
2104                     if (medium instanceof MediaTray) {
2105                         asCurrent.add(mt);
2106                     } else {
2107                         asCurrent.add(new SunAlternateMedia(mt));
2108                     }
2109                 }
2110 
2111 
2112             }
2113             cbSize.addItemListener(this);
2114             cbSource.addItemListener(this);
2115         }
2116     }
2117 
2118     @SuppressWarnings("serial") // Superclass is not serializable across versions
2119     private class OrientationPanel extends JPanel
2120         implements ActionListener
2121     {
2122         private final String strTitle = getMsg("border.orientation");
2123         private IconRadioButton rbPortrait, rbLandscape,


2168                 asCurrent.add(OrientationRequested.PORTRAIT);
2169             } else if (rbLandscape.isSameAs(source)) {
2170                 asCurrent.add(OrientationRequested.LANDSCAPE);
2171             } else if (rbRevPortrait.isSameAs(source)) {
2172                 asCurrent.add(OrientationRequested.REVERSE_PORTRAIT);
2173             } else if (rbRevLandscape.isSameAs(source)) {
2174                 asCurrent.add(OrientationRequested.REVERSE_LANDSCAPE);
2175             }
2176             // orientation affects display of margins.
2177             if (pnlMargins != null) {
2178                 pnlMargins.updateInfo();
2179             }
2180         }
2181 
2182         /* This is ad hoc to keep things simple */
2183         void addOrientationListener(MarginsPanel pnl) {
2184             pnlMargins = pnl;
2185         }
2186 
2187         public void updateInfo() {
2188             Class orCategory = OrientationRequested.class;
2189             boolean pSupported = false;
2190             boolean lSupported = false;
2191             boolean rpSupported = false;
2192             boolean rlSupported = false;
2193 
2194             if (isAWT) {
2195                 pSupported = true;
2196                 lSupported = true;
2197             } else
2198             if (psCurrent.isAttributeCategorySupported(orCategory)) {
2199                 Object values =
2200                     psCurrent.getSupportedAttributeValues(orCategory,
2201                                                           docFlavor,
2202                                                           asCurrent);
2203 
2204                 if (values instanceof OrientationRequested[]) {
2205                     OrientationRequested[] ovalues =
2206                         (OrientationRequested[])values;
2207 
2208                     for (int i = 0; i < ovalues.length; i++) {


2346             rbMonochrome.setSelected(true);
2347             bg.add(rbMonochrome);
2348             addToGB(rbMonochrome, this, gridbag, c);
2349             rbColor = createRadioButton("radiobutton.color", this);
2350             bg.add(rbColor);
2351             addToGB(rbColor, this, gridbag, c);
2352         }
2353 
2354         public void actionPerformed(ActionEvent e) {
2355             Object source = e.getSource();
2356 
2357             // REMIND: use isSameAs if we move to a IconRB in the future
2358             if (source == rbMonochrome) {
2359                 asCurrent.add(Chromaticity.MONOCHROME);
2360             } else if (source == rbColor) {
2361                 asCurrent.add(Chromaticity.COLOR);
2362             }
2363         }
2364 
2365         public void updateInfo() {
2366             Class chCategory = Chromaticity.class;
2367             boolean monoSupported = false;
2368             boolean colorSupported = false;
2369 
2370             if (isAWT) {
2371                 monoSupported = true;
2372                 colorSupported = true;
2373             } else
2374             if (psCurrent.isAttributeCategorySupported(chCategory)) {
2375                 Object values =
2376                     psCurrent.getSupportedAttributeValues(chCategory,
2377                                                           docFlavor,
2378                                                           asCurrent);
2379 
2380                 if (values instanceof Chromaticity[]) {
2381                     Chromaticity[] cvalues = (Chromaticity[])values;
2382 
2383                     for (int i = 0; i < cvalues.length; i++) {
2384                         Chromaticity value = cvalues[i];
2385 
2386                         if (value == Chromaticity.MONOCHROME) {


2441             bg.add(rbNormal);
2442             addToGB(rbNormal, this, gridbag, c);
2443             rbHigh = createRadioButton("radiobutton.highq", this);
2444             bg.add(rbHigh);
2445             addToGB(rbHigh, this, gridbag, c);
2446         }
2447 
2448         public void actionPerformed(ActionEvent e) {
2449             Object source = e.getSource();
2450 
2451             if (source == rbDraft) {
2452                 asCurrent.add(PrintQuality.DRAFT);
2453             } else if (source == rbNormal) {
2454                 asCurrent.add(PrintQuality.NORMAL);
2455             } else if (source == rbHigh) {
2456                 asCurrent.add(PrintQuality.HIGH);
2457             }
2458         }
2459 
2460         public void updateInfo() {
2461             Class pqCategory = PrintQuality.class;
2462             boolean draftSupported = false;
2463             boolean normalSupported = false;
2464             boolean highSupported = false;
2465 
2466             if (isAWT) {
2467                 draftSupported = true;
2468                 normalSupported = true;
2469                 highSupported = true;
2470             } else
2471             if (psCurrent.isAttributeCategorySupported(pqCategory)) {
2472                 Object values =
2473                     psCurrent.getSupportedAttributeValues(pqCategory,
2474                                                           docFlavor,
2475                                                           asCurrent);
2476 
2477                 if (values instanceof PrintQuality[]) {
2478                     PrintQuality[] qvalues = (PrintQuality[])values;
2479 
2480                     for (int i = 0; i < qvalues.length; i++) {
2481                         PrintQuality value = qvalues[i];


2551                                            "duplex.png", false,
2552                                            bg, this);
2553             rbDuplex.addActionListener(this);
2554             c.gridwidth = GridBagConstraints.REMAINDER;
2555             addToGB(rbDuplex, this, gridbag, c);
2556         }
2557 
2558         public void actionPerformed(ActionEvent e) {
2559             Object source = e.getSource();
2560 
2561             if (rbOneSide.isSameAs(source)) {
2562                 asCurrent.add(Sides.ONE_SIDED);
2563             } else if (rbTumble.isSameAs(source)) {
2564                 asCurrent.add(Sides.TUMBLE);
2565             } else if (rbDuplex.isSameAs(source)) {
2566                 asCurrent.add(Sides.DUPLEX);
2567             }
2568         }
2569 
2570         public void updateInfo() {
2571             Class sdCategory = Sides.class;
2572             boolean osSupported = false;
2573             boolean tSupported = false;
2574             boolean dSupported = false;
2575 
2576             if (psCurrent.isAttributeCategorySupported(sdCategory)) {
2577                 Object values =
2578                     psCurrent.getSupportedAttributeValues(sdCategory,
2579                                                           docFlavor,
2580                                                           asCurrent);
2581 
2582                 if (values instanceof Sides[]) {
2583                     Sides[] svalues = (Sides[])values;
2584 
2585                     for (int i = 0; i < svalues.length; i++) {
2586                         Sides value = svalues[i];
2587 
2588                         if (value == Sides.ONE_SIDED) {
2589                             osSupported = true;
2590                         } else if (value == Sides.TUMBLE) {
2591                             tSupported = true;


2708 
2709         public void stateChanged(ChangeEvent e) {
2710             asCurrent.add(new JobPriority(snModel.getNumber().intValue()));
2711         }
2712 
2713         public void focusLost(FocusEvent e) {
2714             Object source = e.getSource();
2715 
2716             if (source == tfJobName) {
2717                 asCurrent.add(new JobName(tfJobName.getText(),
2718                                           Locale.getDefault()));
2719             } else if (source == tfUserName) {
2720                 asCurrent.add(new RequestingUserName(tfUserName.getText(),
2721                                                      Locale.getDefault()));
2722             }
2723         }
2724 
2725         public void focusGained(FocusEvent e) {}
2726 
2727         public void updateInfo() {
2728             Class jsCategory = JobSheets.class;
2729             Class jpCategory = JobPriority.class;
2730             Class jnCategory = JobName.class;
2731             Class unCategory = RequestingUserName.class;
2732             boolean jsSupported = false;
2733             boolean jpSupported = false;
2734             boolean jnSupported = false;
2735             boolean unSupported = false;
2736 
2737             // setup JobSheets checkbox
2738             if (psCurrent.isAttributeCategorySupported(jsCategory)) {
2739                 jsSupported = true;
2740             }
2741             JobSheets js = (JobSheets)asCurrent.get(jsCategory);
2742             if (js == null) {
2743                 js = (JobSheets)psCurrent.getDefaultAttributeValue(jsCategory);
2744                 if (js == null) {
2745                     js = JobSheets.NONE;
2746                 }
2747             }
2748             cbJobSheets.setSelected(js != JobSheets.NONE);
2749             cbJobSheets.setEnabled(jsSupported);
2750 
2751             // setup JobPriority spinner


2800     }
2801 
2802 
2803 
2804 
2805     /**
2806      * A special widget that groups a JRadioButton with an associated icon,
2807      * placed to the left of the radio button.
2808      */
2809     @SuppressWarnings("serial") // Superclass is not serializable across versions
2810     private class IconRadioButton extends JPanel {
2811 
2812         private JRadioButton rb;
2813         private JLabel lbl;
2814 
2815         public IconRadioButton(String key, String img, boolean selected,
2816                                ButtonGroup bg, ActionListener al)
2817         {
2818             super(new FlowLayout(FlowLayout.LEADING));
2819             final URL imgURL = getImageResource(img);
2820             Icon icon = (Icon)java.security.AccessController.doPrivileged(
2821                                  new java.security.PrivilegedAction() {
2822                 public Object run() {
2823                     Icon icon = new ImageIcon(imgURL);
2824                     return icon;
2825                 }
2826             });
2827             lbl = new JLabel(icon);
2828             add(lbl);
2829 
2830             rb = createRadioButton(key, al);
2831             rb.setSelected(selected);
2832             addToBG(rb, this, bg);
2833         }
2834 
2835         public void addActionListener(ActionListener al) {
2836             rb.addActionListener(al);
2837         }
2838 
2839         public boolean isSameAs(Object source) {
2840             return (rb == source);
2841         }
2842 




 378         if (source == btnApprove) {
 379             approved = true;
 380 
 381             if (pnlGeneral != null) {
 382                 if (pnlGeneral.isPrintToFileRequested()) {
 383                     approved = showFileChooser();
 384                 } else {
 385                     asCurrent.remove(Destination.class);
 386                 }
 387             }
 388         }
 389 
 390         dispose(approved ? APPROVE : CANCEL);
 391     }
 392 
 393     /**
 394      * Displays a JFileChooser that allows the user to select the destination
 395      * for "Print To File"
 396      */
 397     private boolean showFileChooser() {
 398         Class<Destination> dstCategory = Destination.class;
 399 
 400         Destination dst = (Destination)asCurrent.get(dstCategory);
 401         if (dst == null) {
 402             dst = (Destination)asOriginal.get(dstCategory);
 403             if (dst == null) {
 404                 dst = (Destination)psCurrent.getDefaultAttributeValue(dstCategory);
 405                 // "dst" should not be null. The following code
 406                 // is only added to safeguard against a possible
 407                 // buggy implementation of a PrintService having a
 408                 // null default Destination.
 409                 if (dst == null) {
 410                     try {
 411                         dst = new Destination(new URI("file:out.prn"));
 412                     } catch (URISyntaxException e) {
 413                     }
 414                 }
 415             }
 416         }
 417 
 418         File fileDest;


 446             asCurrent.remove(dstCategory);
 447         }
 448 
 449         return (returnVal == JFileChooser.APPROVE_OPTION);
 450     }
 451 
 452     /**
 453      * Updates each of the top level panels
 454      */
 455     private void updatePanels() {
 456         pnlGeneral.updateInfo();
 457         pnlPageSetup.updateInfo();
 458         pnlAppearance.updateInfo();
 459     }
 460 
 461     /**
 462      * Initialize ResourceBundle
 463      */
 464     public static void initResource() {
 465         java.security.AccessController.doPrivileged(
 466             new java.security.PrivilegedAction<Object>() {
 467                 public Object run() {
 468                     try {
 469                         messageRB = ResourceBundle.getBundle(strBundle);
 470                         return null;
 471                     } catch (java.util.MissingResourceException e) {
 472                         throw new Error("Fatal: Resource for ServiceUI " +
 473                                         "is missing");
 474                     }
 475                 }
 476             }
 477         );
 478     }
 479 
 480     /**
 481      * Returns message string from resource
 482      */
 483     public static String getMsg(String key) {
 484         try {
 485             return removeMnemonics(messageRB.getString(key));
 486         } catch (java.util.MissingResourceException e) {


 512     }
 513 
 514 
 515     /**
 516      * Returns mnemonic character from resource
 517      */
 518     private static char getMnemonic(String key) {
 519         String str = messageRB.getString(key).replace("&&", "");
 520         int index = str.indexOf('&');
 521         if (0 <= index && index < str.length() - 1) {
 522             char c = str.charAt(index + 1);
 523             return Character.toUpperCase(c);
 524         } else {
 525             return (char)0;
 526         }
 527     }
 528 
 529     /**
 530      * Returns the mnemonic as a KeyEvent.VK constant from the resource.
 531      */
 532     static Class<?> _keyEventClazz = null;
 533     private static int getVKMnemonic(String key) {
 534         String s = String.valueOf(getMnemonic(key));
 535         if ( s == null || s.length() != 1) {
 536             return 0;
 537         }
 538         String vkString = "VK_" + s.toUpperCase();
 539 
 540         try {
 541             if (_keyEventClazz == null) {
 542                 _keyEventClazz= Class.forName("java.awt.event.KeyEvent",
 543                                  true, (ServiceDialog.class).getClassLoader());
 544             }
 545             Field field = _keyEventClazz.getDeclaredField(vkString);
 546             int value = field.getInt(null);
 547             return value;
 548         } catch (Exception e) {
 549         }
 550         return 0;
 551     }
 552 
 553     /**
 554      * Returns URL for image resource
 555      */
 556     private static URL getImageResource(final String key) {
 557         URL url = java.security.AccessController.doPrivileged(
 558                        new java.security.PrivilegedAction<URL>() {
 559                 public URL run() {
 560                     URL url = ServiceDialog.class.getResource(
 561                                                   "resources/" + key);
 562                     return url;
 563                 }
 564         });
 565 
 566         if (url == null) {
 567             throw new Error("Fatal: Resource for ServiceUI is broken; " +
 568                             "there is no " + key + " key in resource");
 569         }
 570 
 571         return url;
 572     }
 573 
 574     /**
 575      * Creates a new JButton and sets its text, mnemonic, and ActionListener
 576      */
 577     private static JButton createButton(String key, ActionListener al) {
 578         JButton btn = new JButton(getMsg(key));
 579         btn.setMnemonic(getMnemonic(key));


 693 
 694         public boolean isPrintToFileRequested() {
 695             return (pnlPrintService.isPrintToFileSelected());
 696         }
 697 
 698         public void updateInfo() {
 699             pnlPrintService.updateInfo();
 700             pnlPrintRange.updateInfo();
 701             pnlCopies.updateInfo();
 702         }
 703     }
 704 
 705     @SuppressWarnings("serial") // Superclass is not serializable across versions
 706     private class PrintServicePanel extends JPanel
 707         implements ActionListener, ItemListener, PopupMenuListener
 708     {
 709         private final String strTitle = getMsg("border.printservice");
 710         private FilePermission printToFilePermission;
 711         private JButton btnProperties;
 712         private JCheckBox cbPrintToFile;
 713         private JComboBox<String> cbName;
 714         private JLabel lblType, lblStatus, lblInfo;
 715         private ServiceUIFactory uiFactory;
 716         private boolean changedService = false;
 717         private boolean filePermission;
 718 
 719         public PrintServicePanel() {
 720             super();
 721 
 722             uiFactory = psCurrent.getServiceUIFactory();
 723 
 724             GridBagLayout gridbag = new GridBagLayout();
 725             GridBagConstraints c = new GridBagConstraints();
 726 
 727             setLayout(gridbag);
 728             setBorder(BorderFactory.createTitledBorder(strTitle));
 729 
 730             String[] psnames = new String[services.length];
 731             for (int i = 0; i < psnames.length; i++) {
 732                 psnames[i] = services[i].getName();
 733             }
 734             cbName = new JComboBox<>(psnames);
 735             cbName.setSelectedIndex(defaultServiceIndex);
 736             cbName.addItemListener(this);
 737             cbName.addPopupMenuListener(this);
 738 
 739             c.fill = GridBagConstraints.BOTH;
 740             c.insets = compInsets;
 741 
 742             c.weightx = 0.0;
 743             JLabel lblName = new JLabel(getMsg("label.psname"), JLabel.TRAILING);
 744             lblName.setDisplayedMnemonic(getMnemonic("label.psname"));
 745             lblName.setLabelFor(cbName);
 746             addToGB(lblName, this, gridbag, c);
 747             c.weightx = 1.0;
 748             c.gridwidth = GridBagConstraints.RELATIVE;
 749             addToGB(cbName, this, gridbag, c);
 750             c.weightx = 0.0;
 751             c.gridwidth = GridBagConstraints.REMAINDER;
 752             btnProperties = createButton("button.properties", this);
 753             addToGB(btnProperties, this, gridbag, c);
 754 


 907             }
 908         }
 909 
 910         /**
 911          * Break this out as it may be useful when we allow API to
 912          * specify printing to a file. In that case its probably right
 913          * to throw a SecurityException if the permission is not granted.
 914          */
 915         private void throwPrintToFile() {
 916             SecurityManager security = System.getSecurityManager();
 917             if (security != null) {
 918                 if (printToFilePermission == null) {
 919                     printToFilePermission =
 920                         new FilePermission("<<ALL FILES>>", "read,write");
 921                 }
 922                 security.checkPermission(printToFilePermission);
 923             }
 924         }
 925 
 926         public void updateInfo() {
 927             Class<Destination> dstCategory = Destination.class;
 928             boolean dstSupported = false;
 929             boolean dstSelected = false;
 930             boolean dstAllowed = filePermission ?
 931                 allowedToPrintToFile() : false;
 932 
 933             // setup Destination (print-to-file) widgets
 934             if (psCurrent.isAttributeCategorySupported(dstCategory)) {
 935                 dstSupported = true;
 936             }
 937             Destination dst = (Destination)asCurrent.get(dstCategory);
 938             if (dst != null) {
 939                 dstSelected = true;
 940             }
 941             cbPrintToFile.setEnabled(dstSupported && dstAllowed);
 942             cbPrintToFile.setSelected(dstSelected && dstAllowed
 943                                       && dstSupported);
 944 
 945             // setup PrintService information widgets
 946             Attribute type = psCurrent.getAttribute(PrinterMakeAndModel.class);
 947             if (type != null) {


1106                 max = Integer.parseInt(strTo);
1107             } catch (NumberFormatException e) {
1108                 max = min;
1109             }
1110 
1111             if (min < 1) {
1112                 min = 1;
1113                 tfRangeFrom.setValue(new Integer(1));
1114             }
1115 
1116             if (max < min) {
1117                 max = min;
1118                 tfRangeTo.setValue(new Integer(min));
1119             }
1120 
1121             PageRanges pr = new PageRanges(min, max);
1122             asCurrent.add(pr);
1123         }
1124 
1125         public void updateInfo() {
1126             Class<PageRanges> prCategory = PageRanges.class;
1127             prSupported = false;
1128 
1129             if (psCurrent.isAttributeCategorySupported(prCategory) ||
1130                    isAWT) {
1131                 prSupported = true;
1132             }
1133 
1134             SunPageSelection select = SunPageSelection.ALL;
1135             int min = 1;
1136             int max = 1;
1137 
1138             PageRanges pr = (PageRanges)asCurrent.get(prCategory);
1139             if (pr != null) {
1140                 if (!pr.equals(prAll)) {
1141                     select = SunPageSelection.RANGE;
1142 
1143                     int[][] members = pr.getMembers();
1144                     if ((members.length > 0) &&
1145                         (members[0].length > 1)) {
1146                         min = members[0][0];


1223                 asCurrent.add(SheetCollate.UNCOLLATED);
1224             }
1225         }
1226 
1227         public void stateChanged(ChangeEvent e) {
1228             updateCollateCB();
1229 
1230             asCurrent.add(new Copies(snModel.getNumber().intValue()));
1231         }
1232 
1233         private void updateCollateCB() {
1234             int num = snModel.getNumber().intValue();
1235             if (isAWT) {
1236                 cbCollate.setEnabled(true);
1237             } else {
1238                 cbCollate.setEnabled((num > 1) && scSupported);
1239             }
1240         }
1241 
1242         public void updateInfo() {
1243             Class<Copies> cpCategory = Copies.class;
1244             Class<SheetCollate> scCategory = SheetCollate.class;

1245             boolean cpSupported = false;
1246             scSupported = false;
1247 
1248             // setup Copies spinner
1249             if (psCurrent.isAttributeCategorySupported(cpCategory)) {
1250                 cpSupported = true;
1251             }
1252             CopiesSupported cs =
1253                 (CopiesSupported)psCurrent.getSupportedAttributeValues(
1254                                                        cpCategory, null, null);
1255             if (cs == null) {
1256                 cs = new CopiesSupported(1, 999);
1257             }
1258             Copies cp = (Copies)asCurrent.get(cpCategory);
1259             if (cp == null) {
1260                 cp = (Copies)psCurrent.getDefaultAttributeValue(cpCategory);
1261                 if (cp == null) {
1262                     cp = new Copies(1);
1263                 }
1264             }


1507                 }
1508                 if (tf == topMargin && val.equals(tmObj)) {
1509                     return;
1510                 }
1511                 if (tf == bottomMargin && val.equals(bmObj)) {
1512                     return;
1513                 }
1514             }
1515 
1516             Float lmTmpObj = (Float)leftMargin.getValue();
1517             Float rmTmpObj = (Float)rightMargin.getValue();
1518             Float tmTmpObj = (Float)topMargin.getValue();
1519             Float bmTmpObj = (Float)bottomMargin.getValue();
1520 
1521             float lm = lmTmpObj.floatValue();
1522             float rm = rmTmpObj.floatValue();
1523             float tm = tmTmpObj.floatValue();
1524             float bm = bmTmpObj.floatValue();
1525 
1526             /* adjust for orientation */
1527             Class<OrientationRequested> orCategory = OrientationRequested.class;
1528             OrientationRequested or =
1529                 (OrientationRequested)asCurrent.get(orCategory);
1530 
1531             if (or == null) {
1532                 or = (OrientationRequested)
1533                      psCurrent.getDefaultAttributeValue(orCategory);
1534             }
1535 
1536             float tmp;
1537             if (or == OrientationRequested.REVERSE_PORTRAIT) {
1538                 tmp = lm; lm = rm; rm = tmp;
1539                 tmp = tm; tm = bm; bm = tmp;
1540             } else if (or == OrientationRequested.LANDSCAPE) {
1541                 tmp = lm;
1542                 lm = tm;
1543                 tm = rm;
1544                 rm = bm;
1545                 bm = tmp;
1546             } else if (or == OrientationRequested.REVERSE_LANDSCAPE) {
1547                 tmp = lm;


1571                     topMargin.setValue(tmObj);
1572                     bottomMargin.setValue(bmObj);
1573 
1574                 }
1575             }
1576         }
1577 
1578         /*
1579          * This method either accepts the values and creates a new
1580          * MediaPrintableArea, or does nothing.
1581          * It should not attempt to create a printable area from anything
1582          * other than the exact values passed in.
1583          * But REMIND/TBD: it would be user friendly to replace margins the
1584          * user entered but are out of bounds with the minimum.
1585          * At that point this method will need to take responsibility for
1586          * updating the "stored" values and the UI.
1587          */
1588         private MediaPrintableArea validateMargins(float lm, float rm,
1589                                                    float tm, float bm) {
1590 
1591             Class<MediaPrintableArea> mpaCategory = MediaPrintableArea.class;
1592             MediaPrintableArea mpa;
1593             MediaPrintableArea mpaMax = null;
1594             MediaSize mediaSize = null;
1595 
1596             Media media = (Media)asCurrent.get(Media.class);
1597             if (media == null || !(media instanceof MediaSizeName)) {
1598                 media = (Media)psCurrent.getDefaultAttributeValue(Media.class);
1599             }
1600             if (media != null && (media instanceof MediaSizeName)) {
1601                 MediaSizeName msn = (MediaSizeName)media;
1602                 mediaSize = MediaSize.getMediaSizeForName(msn);
1603             }
1604             if (mediaSize == null) {
1605                 mediaSize = new MediaSize(8.5f, 11f, Size2DSyntax.INCH);
1606             }
1607 
1608             if (media != null) {
1609                 PrintRequestAttributeSet tmpASet =
1610                     new HashPrintRequestAttributeSet(asCurrent);
1611                 tmpASet.add(media);


1653          *
1654          * If an application doesn't define a MediaPrintableArea, we need to
1655          * create a suitable one, this is created using the specified (or
1656          * default) Media and default 1 inch margins. This is validated
1657          * against the paper in case this is too large for tiny media.
1658          */
1659         public void updateInfo() {
1660 
1661             if (isAWT) {
1662                 leftMargin.setEnabled(false);
1663                 rightMargin.setEnabled(false);
1664                 topMargin.setEnabled(false);
1665                 bottomMargin.setEnabled(false);
1666                 lblLeft.setEnabled(false);
1667                 lblRight.setEnabled(false);
1668                 lblTop.setEnabled(false);
1669                 lblBottom.setEnabled(false);
1670                 return;
1671             }
1672 
1673             Class<MediaPrintableArea> mpaCategory = MediaPrintableArea.class;
1674             MediaPrintableArea mpa =
1675                  (MediaPrintableArea)asCurrent.get(mpaCategory);
1676             MediaPrintableArea mpaMax = null;
1677             MediaSize mediaSize = null;
1678 
1679             Media media = (Media)asCurrent.get(Media.class);
1680             if (media == null || !(media instanceof MediaSizeName)) {
1681                 media = (Media)psCurrent.getDefaultAttributeValue(Media.class);
1682             }
1683             if (media != null && (media instanceof MediaSizeName)) {
1684                 MediaSizeName msn = (MediaSizeName)media;
1685                 mediaSize = MediaSize.getMediaSizeForName(msn);
1686             }
1687             if (mediaSize == null) {
1688                 mediaSize = new MediaSize(8.5f, 11f, Size2DSyntax.INCH);
1689             }
1690 
1691             if (media != null) {
1692                 PrintRequestAttributeSet tmpASet =
1693                     new HashPrintRequestAttributeSet(asCurrent);


1827                 asCurrent.add(mpa);
1828             }
1829 
1830             /* We now have a valid printable area.
1831              * Turn it into margins, using the mediaSize
1832              */
1833             lmVal = pax;
1834             tmVal = pay;
1835             rmVal = mediaSize.getX(units) - pax - paw;
1836             bmVal = mediaSize.getY(units) - pay - pah;
1837 
1838             lmObj = new Float(lmVal);
1839             rmObj = new Float(rmVal);
1840             tmObj = new Float(tmVal);
1841             bmObj = new Float(bmVal);
1842 
1843             /* Now we know the values to use, we need to assign them
1844              * to the fields appropriate for the orientation.
1845              * Note: if orientation changes this method must be called.
1846              */
1847             Class<OrientationRequested> orCategory = OrientationRequested.class;
1848             OrientationRequested or =
1849                 (OrientationRequested)asCurrent.get(orCategory);
1850 
1851             if (or == null) {
1852                 or = (OrientationRequested)
1853                      psCurrent.getDefaultAttributeValue(orCategory);
1854             }
1855 
1856             Float tmp;
1857 
1858             if (or == OrientationRequested.REVERSE_PORTRAIT) {
1859                 tmp = lmObj; lmObj = rmObj; rmObj = tmp;
1860                 tmp = tmObj; tmObj = bmObj; bmObj = tmp;
1861             }  else if (or == OrientationRequested.LANDSCAPE) {
1862                 tmp = lmObj;
1863                 lmObj = bmObj;
1864                 bmObj = rmObj;
1865                 rmObj = tmObj;
1866                 tmObj = tmp;
1867             }  else if (or == OrientationRequested.REVERSE_LANDSCAPE) {
1868                 tmp = lmObj;
1869                 lmObj = tmObj;
1870                 tmObj = rmObj;
1871                 rmObj = bmObj;
1872                 bmObj = tmp;
1873             }
1874 
1875             leftMargin.setValue(lmObj);
1876             rightMargin.setValue(rmObj);
1877             topMargin.setValue(tmObj);
1878             bottomMargin.setValue(bmObj);
1879         }
1880     }
1881 
1882     @SuppressWarnings("serial") // Superclass is not serializable across versions
1883     private class MediaPanel extends JPanel implements ItemListener {
1884 
1885         private final String strTitle = getMsg("border.media");
1886         private JLabel lblSize, lblSource;
1887         private JComboBox<Object> cbSize, cbSource;
1888         private Vector<MediaSizeName> sizes = new Vector<>();
1889         private Vector<MediaTray> sources = new Vector<>();
1890         private MarginsPanel pnlMargins = null;
1891 
1892         public MediaPanel() {
1893             super();
1894 
1895             GridBagLayout gridbag = new GridBagLayout();
1896             GridBagConstraints c = new GridBagConstraints();
1897 
1898             setLayout(gridbag);
1899             setBorder(BorderFactory.createTitledBorder(strTitle));
1900 
1901             cbSize = new JComboBox<>();
1902             cbSource = new JComboBox<>();
1903 
1904             c.fill = GridBagConstraints.BOTH;
1905             c.insets = compInsets;
1906             c.weighty = 1.0;
1907 
1908             c.weightx = 0.0;
1909             lblSize = new JLabel(getMsg("label.size"), JLabel.TRAILING);
1910             lblSize.setDisplayedMnemonic(getMnemonic("label.size"));
1911             lblSize.setLabelFor(cbSize);
1912             addToGB(lblSize, this, gridbag, c);
1913             c.weightx = 1.0;
1914             c.gridwidth = GridBagConstraints.REMAINDER;
1915             addToGB(cbSize, this, gridbag, c);
1916 
1917             c.weightx = 0.0;
1918             c.gridwidth = 1;
1919             lblSource = new JLabel(getMsg("label.source"), JLabel.TRAILING);
1920             lblSource.setDisplayedMnemonic(getMnemonic("label.source"));
1921             lblSource.setLabelFor(cbSource);
1922             addToGB(lblSource, this, gridbag, c);


1932                 newkey = newkey.replace('#', 'n');
1933 
1934                 return messageRB.getString(newkey);
1935             } catch (java.util.MissingResourceException e) {
1936                 return key;
1937             }
1938         }
1939 
1940         public void itemStateChanged(ItemEvent e) {
1941             Object source = e.getSource();
1942 
1943             if (e.getStateChange() == ItemEvent.SELECTED) {
1944                 if (source == cbSize) {
1945                     int index = cbSize.getSelectedIndex();
1946 
1947                     if ((index >= 0) && (index < sizes.size())) {
1948                         if ((cbSource.getItemCount() > 1) &&
1949                             (cbSource.getSelectedIndex() >= 1))
1950                         {
1951                             int src = cbSource.getSelectedIndex() - 1;
1952                             MediaTray mt = sources.get(src);
1953                             asCurrent.add(new SunAlternateMedia(mt));
1954                         }
1955                         asCurrent.add(sizes.get(index));
1956                     }
1957                 } else if (source == cbSource) {
1958                     int index = cbSource.getSelectedIndex();
1959 
1960                     if ((index >= 1) && (index < (sources.size() + 1))) {
1961                        asCurrent.remove(SunAlternateMedia.class);
1962                        MediaTray newTray = sources.get(index - 1);
1963                        Media m = (Media)asCurrent.get(Media.class);
1964                        if (m == null || m instanceof MediaTray) {
1965                            asCurrent.add(newTray);
1966                        } else if (m instanceof MediaSizeName) {
1967                            MediaSizeName msn = (MediaSizeName)m;
1968                            Media def = (Media)psCurrent.getDefaultAttributeValue(Media.class);
1969                            if (def instanceof MediaSizeName && def.equals(msn)) {
1970                                asCurrent.add(newTray);
1971                            } else {
1972                                /* Non-default paper size, so need to store tray
1973                                 * as SunAlternateMedia
1974                                 */
1975                                asCurrent.add(new SunAlternateMedia(newTray));
1976                            }
1977                        }
1978                     } else if (index == 0) {
1979                         asCurrent.remove(SunAlternateMedia.class);
1980                         if (cbSize.getItemCount() > 0) {
1981                             int size = cbSize.getSelectedIndex();
1982                             asCurrent.add(sizes.get(size));
1983                         }
1984                     }
1985                 }
1986             // orientation affects display of margins.
1987                 if (pnlMargins != null) {
1988                     pnlMargins.updateInfo();
1989                 }
1990             }
1991         }
1992 
1993 
1994         /* this is ad hoc to keep things simple */
1995         public void addMediaListener(MarginsPanel pnl) {
1996             pnlMargins = pnl;
1997         }
1998         public void updateInfo() {
1999             Class<Media> mdCategory = Media.class;
2000             Class<SunAlternateMedia> amCategory = SunAlternateMedia.class;
2001             boolean mediaSupported = false;
2002 
2003             cbSize.removeItemListener(this);
2004             cbSize.removeAllItems();
2005             cbSource.removeItemListener(this);
2006             cbSource.removeAllItems();
2007             cbSource.addItem(getMediaName("auto-select"));
2008 
2009             sizes.clear();
2010             sources.clear();
2011 
2012             if (psCurrent.isAttributeCategorySupported(mdCategory)) {
2013                 mediaSupported = true;
2014 
2015                 Object values =
2016                     psCurrent.getSupportedAttributeValues(mdCategory,
2017                                                           docFlavor,
2018                                                           asCurrent);
2019 
2020                 if (values instanceof Media[]) {
2021                     Media[] media = (Media[])values;
2022 
2023                     for (int i = 0; i < media.length; i++) {
2024                         Media medium = media[i];
2025 
2026                         if (medium instanceof MediaSizeName) {
2027                             sizes.add((MediaSizeName)medium);
2028                             cbSize.addItem(getMediaName(medium.toString()));
2029                         } else if (medium instanceof MediaTray) {
2030                             sources.add((MediaTray)medium);
2031                             cbSource.addItem(getMediaName(medium.toString()));
2032                         }
2033                     }
2034                 }
2035             }
2036 
2037             boolean msSupported = (mediaSupported && (sizes.size() > 0));
2038             lblSize.setEnabled(msSupported);
2039             cbSize.setEnabled(msSupported);
2040 
2041             if (isAWT) {
2042                 cbSource.setEnabled(false);
2043                 lblSource.setEnabled(false);
2044             } else {
2045                 cbSource.setEnabled(mediaSupported);
2046             }
2047 
2048             if (mediaSupported) {
2049 
2050                 Media medium = (Media)asCurrent.get(mdCategory);


2077                     } else if (medium instanceof MediaTray) {
2078                         MediaTray mt = (MediaTray)medium;
2079                         cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
2080                     }
2081                 } else {
2082                     cbSize.setSelectedIndex(sizes.size() > 0 ? 0 : -1);
2083                     cbSource.setSelectedIndex(0);
2084                 }
2085 
2086                 SunAlternateMedia alt = (SunAlternateMedia)asCurrent.get(amCategory);
2087                 if (alt != null) {
2088                     Media md = alt.getMedia();
2089                     if (md instanceof MediaTray) {
2090                         MediaTray mt = (MediaTray)md;
2091                         cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
2092                     }
2093                 }
2094 
2095                 int selIndex = cbSize.getSelectedIndex();
2096                 if ((selIndex >= 0) && (selIndex < sizes.size())) {
2097                   asCurrent.add(sizes.get(selIndex));
2098                 }
2099 
2100                 selIndex = cbSource.getSelectedIndex();
2101                 if ((selIndex >= 1) && (selIndex < (sources.size()+1))) {
2102                     MediaTray mt = sources.get(selIndex-1);
2103                     if (medium instanceof MediaTray) {
2104                         asCurrent.add(mt);
2105                     } else {
2106                         asCurrent.add(new SunAlternateMedia(mt));
2107                     }
2108                 }
2109 
2110 
2111             }
2112             cbSize.addItemListener(this);
2113             cbSource.addItemListener(this);
2114         }
2115     }
2116 
2117     @SuppressWarnings("serial") // Superclass is not serializable across versions
2118     private class OrientationPanel extends JPanel
2119         implements ActionListener
2120     {
2121         private final String strTitle = getMsg("border.orientation");
2122         private IconRadioButton rbPortrait, rbLandscape,


2167                 asCurrent.add(OrientationRequested.PORTRAIT);
2168             } else if (rbLandscape.isSameAs(source)) {
2169                 asCurrent.add(OrientationRequested.LANDSCAPE);
2170             } else if (rbRevPortrait.isSameAs(source)) {
2171                 asCurrent.add(OrientationRequested.REVERSE_PORTRAIT);
2172             } else if (rbRevLandscape.isSameAs(source)) {
2173                 asCurrent.add(OrientationRequested.REVERSE_LANDSCAPE);
2174             }
2175             // orientation affects display of margins.
2176             if (pnlMargins != null) {
2177                 pnlMargins.updateInfo();
2178             }
2179         }
2180 
2181         /* This is ad hoc to keep things simple */
2182         void addOrientationListener(MarginsPanel pnl) {
2183             pnlMargins = pnl;
2184         }
2185 
2186         public void updateInfo() {
2187             Class<OrientationRequested> orCategory = OrientationRequested.class;
2188             boolean pSupported = false;
2189             boolean lSupported = false;
2190             boolean rpSupported = false;
2191             boolean rlSupported = false;
2192 
2193             if (isAWT) {
2194                 pSupported = true;
2195                 lSupported = true;
2196             } else
2197             if (psCurrent.isAttributeCategorySupported(orCategory)) {
2198                 Object values =
2199                     psCurrent.getSupportedAttributeValues(orCategory,
2200                                                           docFlavor,
2201                                                           asCurrent);
2202 
2203                 if (values instanceof OrientationRequested[]) {
2204                     OrientationRequested[] ovalues =
2205                         (OrientationRequested[])values;
2206 
2207                     for (int i = 0; i < ovalues.length; i++) {


2345             rbMonochrome.setSelected(true);
2346             bg.add(rbMonochrome);
2347             addToGB(rbMonochrome, this, gridbag, c);
2348             rbColor = createRadioButton("radiobutton.color", this);
2349             bg.add(rbColor);
2350             addToGB(rbColor, this, gridbag, c);
2351         }
2352 
2353         public void actionPerformed(ActionEvent e) {
2354             Object source = e.getSource();
2355 
2356             // REMIND: use isSameAs if we move to a IconRB in the future
2357             if (source == rbMonochrome) {
2358                 asCurrent.add(Chromaticity.MONOCHROME);
2359             } else if (source == rbColor) {
2360                 asCurrent.add(Chromaticity.COLOR);
2361             }
2362         }
2363 
2364         public void updateInfo() {
2365             Class<Chromaticity> chCategory = Chromaticity.class;
2366             boolean monoSupported = false;
2367             boolean colorSupported = false;
2368 
2369             if (isAWT) {
2370                 monoSupported = true;
2371                 colorSupported = true;
2372             } else
2373             if (psCurrent.isAttributeCategorySupported(chCategory)) {
2374                 Object values =
2375                     psCurrent.getSupportedAttributeValues(chCategory,
2376                                                           docFlavor,
2377                                                           asCurrent);
2378 
2379                 if (values instanceof Chromaticity[]) {
2380                     Chromaticity[] cvalues = (Chromaticity[])values;
2381 
2382                     for (int i = 0; i < cvalues.length; i++) {
2383                         Chromaticity value = cvalues[i];
2384 
2385                         if (value == Chromaticity.MONOCHROME) {


2440             bg.add(rbNormal);
2441             addToGB(rbNormal, this, gridbag, c);
2442             rbHigh = createRadioButton("radiobutton.highq", this);
2443             bg.add(rbHigh);
2444             addToGB(rbHigh, this, gridbag, c);
2445         }
2446 
2447         public void actionPerformed(ActionEvent e) {
2448             Object source = e.getSource();
2449 
2450             if (source == rbDraft) {
2451                 asCurrent.add(PrintQuality.DRAFT);
2452             } else if (source == rbNormal) {
2453                 asCurrent.add(PrintQuality.NORMAL);
2454             } else if (source == rbHigh) {
2455                 asCurrent.add(PrintQuality.HIGH);
2456             }
2457         }
2458 
2459         public void updateInfo() {
2460             Class<PrintQuality> pqCategory = PrintQuality.class;
2461             boolean draftSupported = false;
2462             boolean normalSupported = false;
2463             boolean highSupported = false;
2464 
2465             if (isAWT) {
2466                 draftSupported = true;
2467                 normalSupported = true;
2468                 highSupported = true;
2469             } else
2470             if (psCurrent.isAttributeCategorySupported(pqCategory)) {
2471                 Object values =
2472                     psCurrent.getSupportedAttributeValues(pqCategory,
2473                                                           docFlavor,
2474                                                           asCurrent);
2475 
2476                 if (values instanceof PrintQuality[]) {
2477                     PrintQuality[] qvalues = (PrintQuality[])values;
2478 
2479                     for (int i = 0; i < qvalues.length; i++) {
2480                         PrintQuality value = qvalues[i];


2550                                            "duplex.png", false,
2551                                            bg, this);
2552             rbDuplex.addActionListener(this);
2553             c.gridwidth = GridBagConstraints.REMAINDER;
2554             addToGB(rbDuplex, this, gridbag, c);
2555         }
2556 
2557         public void actionPerformed(ActionEvent e) {
2558             Object source = e.getSource();
2559 
2560             if (rbOneSide.isSameAs(source)) {
2561                 asCurrent.add(Sides.ONE_SIDED);
2562             } else if (rbTumble.isSameAs(source)) {
2563                 asCurrent.add(Sides.TUMBLE);
2564             } else if (rbDuplex.isSameAs(source)) {
2565                 asCurrent.add(Sides.DUPLEX);
2566             }
2567         }
2568 
2569         public void updateInfo() {
2570             Class<Sides> sdCategory = Sides.class;
2571             boolean osSupported = false;
2572             boolean tSupported = false;
2573             boolean dSupported = false;
2574 
2575             if (psCurrent.isAttributeCategorySupported(sdCategory)) {
2576                 Object values =
2577                     psCurrent.getSupportedAttributeValues(sdCategory,
2578                                                           docFlavor,
2579                                                           asCurrent);
2580 
2581                 if (values instanceof Sides[]) {
2582                     Sides[] svalues = (Sides[])values;
2583 
2584                     for (int i = 0; i < svalues.length; i++) {
2585                         Sides value = svalues[i];
2586 
2587                         if (value == Sides.ONE_SIDED) {
2588                             osSupported = true;
2589                         } else if (value == Sides.TUMBLE) {
2590                             tSupported = true;


2707 
2708         public void stateChanged(ChangeEvent e) {
2709             asCurrent.add(new JobPriority(snModel.getNumber().intValue()));
2710         }
2711 
2712         public void focusLost(FocusEvent e) {
2713             Object source = e.getSource();
2714 
2715             if (source == tfJobName) {
2716                 asCurrent.add(new JobName(tfJobName.getText(),
2717                                           Locale.getDefault()));
2718             } else if (source == tfUserName) {
2719                 asCurrent.add(new RequestingUserName(tfUserName.getText(),
2720                                                      Locale.getDefault()));
2721             }
2722         }
2723 
2724         public void focusGained(FocusEvent e) {}
2725 
2726         public void updateInfo() {
2727             Class<JobSheets>          jsCategory = JobSheets.class;
2728             Class<JobPriority>        jpCategory = JobPriority.class;
2729             Class<JobName>            jnCategory = JobName.class;
2730             Class<RequestingUserName> unCategory = RequestingUserName.class;
2731             boolean jsSupported = false;
2732             boolean jpSupported = false;
2733             boolean jnSupported = false;
2734             boolean unSupported = false;
2735 
2736             // setup JobSheets checkbox
2737             if (psCurrent.isAttributeCategorySupported(jsCategory)) {
2738                 jsSupported = true;
2739             }
2740             JobSheets js = (JobSheets)asCurrent.get(jsCategory);
2741             if (js == null) {
2742                 js = (JobSheets)psCurrent.getDefaultAttributeValue(jsCategory);
2743                 if (js == null) {
2744                     js = JobSheets.NONE;
2745                 }
2746             }
2747             cbJobSheets.setSelected(js != JobSheets.NONE);
2748             cbJobSheets.setEnabled(jsSupported);
2749 
2750             // setup JobPriority spinner


2799     }
2800 
2801 
2802 
2803 
2804     /**
2805      * A special widget that groups a JRadioButton with an associated icon,
2806      * placed to the left of the radio button.
2807      */
2808     @SuppressWarnings("serial") // Superclass is not serializable across versions
2809     private class IconRadioButton extends JPanel {
2810 
2811         private JRadioButton rb;
2812         private JLabel lbl;
2813 
2814         public IconRadioButton(String key, String img, boolean selected,
2815                                ButtonGroup bg, ActionListener al)
2816         {
2817             super(new FlowLayout(FlowLayout.LEADING));
2818             final URL imgURL = getImageResource(img);
2819             Icon icon = java.security.AccessController.doPrivileged(
2820                                  new java.security.PrivilegedAction<Icon>() {
2821                 public Icon run() {
2822                     Icon icon = new ImageIcon(imgURL);
2823                     return icon;
2824                 }
2825             });
2826             lbl = new JLabel(icon);
2827             add(lbl);
2828 
2829             rb = createRadioButton(key, al);
2830             rb.setSelected(selected);
2831             addToBG(rb, this, bg);
2832         }
2833 
2834         public void addActionListener(ActionListener al) {
2835             rb.addActionListener(al);
2836         }
2837 
2838         public boolean isSameAs(Object source) {
2839             return (rb == source);
2840         }
2841