Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/print/ServiceDialog.java
38829 views
1
/*
2
* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.print;
27
28
import java.awt.BorderLayout;
29
import java.awt.Color;
30
import java.awt.Component;
31
import java.awt.Container;
32
import java.awt.Dialog;
33
import java.awt.FlowLayout;
34
import java.awt.Frame;
35
import java.awt.GraphicsConfiguration;
36
import java.awt.GridBagLayout;
37
import java.awt.GridBagConstraints;
38
import java.awt.GridLayout;
39
import java.awt.Insets;
40
import java.awt.Toolkit;
41
import java.awt.event.ActionEvent;
42
import java.awt.event.ActionListener;
43
import java.awt.event.FocusEvent;
44
import java.awt.event.FocusListener;
45
import java.awt.event.ItemEvent;
46
import java.awt.event.ItemListener;
47
import java.awt.event.WindowEvent;
48
import java.awt.event.WindowAdapter;
49
import java.awt.print.PrinterJob;
50
import java.io.File;
51
import java.io.FilePermission;
52
import java.io.IOException;
53
import java.net.URI;
54
import java.net.URL;
55
import java.text.DecimalFormat;
56
import java.util.Locale;
57
import java.util.ResourceBundle;
58
import java.util.Vector;
59
import javax.print.*;
60
import javax.print.attribute.*;
61
import javax.print.attribute.standard.*;
62
import javax.swing.*;
63
import javax.swing.border.Border;
64
import javax.swing.border.EmptyBorder;
65
import javax.swing.border.TitledBorder;
66
import javax.swing.event.ChangeEvent;
67
import javax.swing.event.ChangeListener;
68
import javax.swing.event.DocumentEvent;
69
import javax.swing.event.DocumentListener;
70
import javax.swing.event.PopupMenuEvent;
71
import javax.swing.event.PopupMenuListener;
72
import javax.swing.text.NumberFormatter;
73
import sun.print.SunPageSelection;
74
import java.awt.event.KeyEvent;
75
import java.net.URISyntaxException;
76
import java.lang.reflect.Field;
77
78
79
/**
80
* A class which implements a cross-platform print dialog.
81
*
82
* @author Chris Campbell
83
*/
84
public class ServiceDialog extends JDialog implements ActionListener {
85
86
/**
87
* Waiting print status (user response pending).
88
*/
89
public final static int WAITING = 0;
90
91
/**
92
* Approve print status (user activated "Print" or "OK").
93
*/
94
public final static int APPROVE = 1;
95
96
/**
97
* Cancel print status (user activated "Cancel");
98
*/
99
public final static int CANCEL = 2;
100
101
private static final String strBundle = "sun.print.resources.serviceui";
102
private static final Insets panelInsets = new Insets(6, 6, 6, 6);
103
private static final Insets compInsets = new Insets(3, 6, 3, 6);
104
105
private static ResourceBundle messageRB;
106
private JTabbedPane tpTabs;
107
private JButton btnCancel, btnApprove;
108
private PrintService[] services;
109
private int defaultServiceIndex;
110
private PrintRequestAttributeSet asOriginal;
111
private HashPrintRequestAttributeSet asCurrent;
112
private PrintService psCurrent;
113
private DocFlavor docFlavor;
114
private int status;
115
116
private ValidatingFileChooser jfc;
117
118
private GeneralPanel pnlGeneral;
119
private PageSetupPanel pnlPageSetup;
120
private AppearancePanel pnlAppearance;
121
122
private boolean isAWT = false;
123
static {
124
initResource();
125
}
126
127
128
/**
129
* Constructor for the "standard" print dialog (containing all relevant
130
* tabs)
131
*/
132
public ServiceDialog(GraphicsConfiguration gc,
133
int x, int y,
134
PrintService[] services,
135
int defaultServiceIndex,
136
DocFlavor flavor,
137
PrintRequestAttributeSet attributes,
138
Dialog dialog)
139
{
140
super(dialog, getMsg("dialog.printtitle"), true, gc);
141
initPrintDialog(x, y, services, defaultServiceIndex,
142
flavor, attributes);
143
}
144
145
146
147
/**
148
* Constructor for the "standard" print dialog (containing all relevant
149
* tabs)
150
*/
151
public ServiceDialog(GraphicsConfiguration gc,
152
int x, int y,
153
PrintService[] services,
154
int defaultServiceIndex,
155
DocFlavor flavor,
156
PrintRequestAttributeSet attributes,
157
Frame frame)
158
{
159
super(frame, getMsg("dialog.printtitle"), true, gc);
160
initPrintDialog(x, y, services, defaultServiceIndex,
161
flavor, attributes);
162
}
163
164
165
/**
166
* Initialize print dialog.
167
*/
168
void initPrintDialog(int x, int y,
169
PrintService[] services,
170
int defaultServiceIndex,
171
DocFlavor flavor,
172
PrintRequestAttributeSet attributes)
173
{
174
this.services = services;
175
this.defaultServiceIndex = defaultServiceIndex;
176
this.asOriginal = attributes;
177
this.asCurrent = new HashPrintRequestAttributeSet(attributes);
178
this.psCurrent = services[defaultServiceIndex];
179
this.docFlavor = flavor;
180
SunPageSelection pages =
181
(SunPageSelection)attributes.get(SunPageSelection.class);
182
if (pages != null) {
183
isAWT = true;
184
}
185
186
if (attributes.get(DialogOnTop.class) != null) {
187
setAlwaysOnTop(true);
188
}
189
Container c = getContentPane();
190
c.setLayout(new BorderLayout());
191
192
tpTabs = new JTabbedPane();
193
tpTabs.setBorder(new EmptyBorder(5, 5, 5, 5));
194
195
String gkey = getMsg("tab.general");
196
int gmnemonic = getVKMnemonic("tab.general");
197
pnlGeneral = new GeneralPanel();
198
tpTabs.add(gkey, pnlGeneral);
199
tpTabs.setMnemonicAt(0, gmnemonic);
200
201
String pkey = getMsg("tab.pagesetup");
202
int pmnemonic = getVKMnemonic("tab.pagesetup");
203
pnlPageSetup = new PageSetupPanel();
204
tpTabs.add(pkey, pnlPageSetup);
205
tpTabs.setMnemonicAt(1, pmnemonic);
206
207
String akey = getMsg("tab.appearance");
208
int amnemonic = getVKMnemonic("tab.appearance");
209
pnlAppearance = new AppearancePanel();
210
tpTabs.add(akey, pnlAppearance);
211
tpTabs.setMnemonicAt(2, amnemonic);
212
213
c.add(tpTabs, BorderLayout.CENTER);
214
215
updatePanels();
216
217
JPanel pnlSouth = new JPanel(new FlowLayout(FlowLayout.TRAILING));
218
btnApprove = createExitButton("button.print", this);
219
pnlSouth.add(btnApprove);
220
getRootPane().setDefaultButton(btnApprove);
221
btnCancel = createExitButton("button.cancel", this);
222
handleEscKey(btnCancel);
223
pnlSouth.add(btnCancel);
224
c.add(pnlSouth, BorderLayout.SOUTH);
225
226
addWindowListener(new WindowAdapter() {
227
public void windowClosing(WindowEvent event) {
228
dispose(CANCEL);
229
}
230
});
231
232
getAccessibleContext().setAccessibleDescription(getMsg("dialog.printtitle"));
233
setResizable(false);
234
setLocation(x, y);
235
pack();
236
}
237
238
/**
239
* Constructor for the solitary "page setup" dialog
240
*/
241
public ServiceDialog(GraphicsConfiguration gc,
242
int x, int y,
243
PrintService ps,
244
DocFlavor flavor,
245
PrintRequestAttributeSet attributes,
246
Dialog dialog)
247
{
248
super(dialog, getMsg("dialog.pstitle"), true, gc);
249
initPageDialog(x, y, ps, flavor, attributes);
250
}
251
252
/**
253
* Constructor for the solitary "page setup" dialog
254
*/
255
public ServiceDialog(GraphicsConfiguration gc,
256
int x, int y,
257
PrintService ps,
258
DocFlavor flavor,
259
PrintRequestAttributeSet attributes,
260
Frame frame)
261
{
262
super(frame, getMsg("dialog.pstitle"), true, gc);
263
initPageDialog(x, y, ps, flavor, attributes);
264
}
265
266
267
/**
268
* Initialize "page setup" dialog
269
*/
270
void initPageDialog(int x, int y,
271
PrintService ps,
272
DocFlavor flavor,
273
PrintRequestAttributeSet attributes)
274
{
275
this.psCurrent = ps;
276
this.docFlavor = flavor;
277
this.asOriginal = attributes;
278
this.asCurrent = new HashPrintRequestAttributeSet(attributes);
279
280
if (attributes.get(DialogOnTop.class) != null) {
281
setAlwaysOnTop(true);
282
}
283
284
Container c = getContentPane();
285
c.setLayout(new BorderLayout());
286
287
pnlPageSetup = new PageSetupPanel();
288
c.add(pnlPageSetup, BorderLayout.CENTER);
289
290
pnlPageSetup.updateInfo();
291
292
JPanel pnlSouth = new JPanel(new FlowLayout(FlowLayout.TRAILING));
293
btnApprove = createExitButton("button.ok", this);
294
pnlSouth.add(btnApprove);
295
getRootPane().setDefaultButton(btnApprove);
296
btnCancel = createExitButton("button.cancel", this);
297
handleEscKey(btnCancel);
298
pnlSouth.add(btnCancel);
299
c.add(pnlSouth, BorderLayout.SOUTH);
300
301
addWindowListener(new WindowAdapter() {
302
public void windowClosing(WindowEvent event) {
303
dispose(CANCEL);
304
}
305
});
306
307
getAccessibleContext().setAccessibleDescription(getMsg("dialog.pstitle"));
308
setResizable(false);
309
setLocation(x, y);
310
pack();
311
}
312
313
/**
314
* Performs Cancel when Esc key is pressed.
315
*/
316
private void handleEscKey(JButton btnCancel) {
317
Action cancelKeyAction = new AbstractAction() {
318
public void actionPerformed(ActionEvent e) {
319
dispose(CANCEL);
320
}
321
};
322
KeyStroke cancelKeyStroke =
323
KeyStroke.getKeyStroke((char)KeyEvent.VK_ESCAPE, 0);
324
InputMap inputMap =
325
btnCancel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
326
ActionMap actionMap = btnCancel.getActionMap();
327
328
if (inputMap != null && actionMap != null) {
329
inputMap.put(cancelKeyStroke, "cancel");
330
actionMap.put("cancel", cancelKeyAction);
331
}
332
}
333
334
335
/**
336
* Returns the current status of the dialog (whether the user has selected
337
* the "Print" or "Cancel" button)
338
*/
339
public int getStatus() {
340
return status;
341
}
342
343
/**
344
* Returns an AttributeSet based on whether or not the user cancelled the
345
* dialog. If the user selected "Print" we return their new selections,
346
* otherwise we return the attributes that were passed in initially.
347
*/
348
public PrintRequestAttributeSet getAttributes() {
349
if (status == APPROVE) {
350
return asCurrent;
351
} else {
352
return asOriginal;
353
}
354
}
355
356
/**
357
* Returns a PrintService based on whether or not the user cancelled the
358
* dialog. If the user selected "Print" we return the user's selection
359
* for the PrintService, otherwise we return null.
360
*/
361
public PrintService getPrintService() {
362
if (status == APPROVE) {
363
return psCurrent;
364
} else {
365
return null;
366
}
367
}
368
369
/**
370
* Sets the current status flag for the dialog and disposes it (thus
371
* returning control of the parent frame back to the user)
372
*/
373
public void dispose(int status) {
374
this.status = status;
375
376
super.dispose();
377
}
378
379
public void actionPerformed(ActionEvent e) {
380
Object source = e.getSource();
381
boolean approved = false;
382
383
if (source == btnApprove) {
384
approved = true;
385
386
if (pnlGeneral != null) {
387
if (pnlGeneral.isPrintToFileRequested()) {
388
approved = showFileChooser();
389
} else {
390
asCurrent.remove(Destination.class);
391
}
392
}
393
}
394
395
dispose(approved ? APPROVE : CANCEL);
396
}
397
398
/**
399
* Displays a JFileChooser that allows the user to select the destination
400
* for "Print To File"
401
*/
402
private boolean showFileChooser() {
403
Class dstCategory = Destination.class;
404
405
Destination dst = (Destination)asCurrent.get(dstCategory);
406
if (dst == null) {
407
dst = (Destination)asOriginal.get(dstCategory);
408
if (dst == null) {
409
dst = (Destination)psCurrent.getDefaultAttributeValue(dstCategory);
410
// "dst" should not be null. The following code
411
// is only added to safeguard against a possible
412
// buggy implementation of a PrintService having a
413
// null default Destination.
414
if (dst == null) {
415
try {
416
dst = new Destination(new URI("file:out.prn"));
417
} catch (URISyntaxException e) {
418
}
419
}
420
}
421
}
422
423
File fileDest;
424
if (dst != null) {
425
try {
426
fileDest = new File(dst.getURI());
427
} catch (Exception e) {
428
// all manner of runtime exceptions possible
429
fileDest = new File("out.prn");
430
}
431
} else {
432
fileDest = new File("out.prn");
433
}
434
435
ValidatingFileChooser jfc = new ValidatingFileChooser();
436
jfc.setApproveButtonText(getMsg("button.ok"));
437
jfc.setDialogTitle(getMsg("dialog.printtofile"));
438
jfc.setDialogType(JFileChooser.SAVE_DIALOG);
439
jfc.setSelectedFile(fileDest);
440
441
int returnVal = jfc.showDialog(this, null);
442
if (returnVal == JFileChooser.APPROVE_OPTION) {
443
fileDest = jfc.getSelectedFile();
444
445
try {
446
asCurrent.add(new Destination(fileDest.toURI()));
447
} catch (Exception e) {
448
asCurrent.remove(dstCategory);
449
}
450
} else {
451
asCurrent.remove(dstCategory);
452
}
453
454
return (returnVal == JFileChooser.APPROVE_OPTION);
455
}
456
457
/**
458
* Updates each of the top level panels
459
*/
460
private void updatePanels() {
461
pnlGeneral.updateInfo();
462
pnlPageSetup.updateInfo();
463
pnlAppearance.updateInfo();
464
}
465
466
/**
467
* Initialize ResourceBundle
468
*/
469
public static void initResource() {
470
java.security.AccessController.doPrivileged(
471
new java.security.PrivilegedAction() {
472
public Object run() {
473
try {
474
messageRB = ResourceBundle.getBundle(strBundle);
475
return null;
476
} catch (java.util.MissingResourceException e) {
477
throw new Error("Fatal: Resource for ServiceUI " +
478
"is missing");
479
}
480
}
481
}
482
);
483
}
484
485
/**
486
* Returns message string from resource
487
*/
488
public static String getMsg(String key) {
489
try {
490
return removeMnemonics(messageRB.getString(key));
491
} catch (java.util.MissingResourceException e) {
492
throw new Error("Fatal: Resource for ServiceUI is broken; " +
493
"there is no " + key + " key in resource");
494
}
495
}
496
497
private static String removeMnemonics(String s) {
498
int i = s.indexOf('&');
499
int len = s.length();
500
if (i < 0 || i == (len - 1)) {
501
return s;
502
}
503
int j = s.indexOf('&', i+1);
504
if (j == i+1) {
505
if (j+1 == len) {
506
return s.substring(0, i+1); // string ends with &&
507
} else {
508
return s.substring(0, i+1) + removeMnemonics(s.substring(j+1));
509
}
510
}
511
// ok first & not double &&
512
if (i == 0) {
513
return removeMnemonics(s.substring(1));
514
} else {
515
return (s.substring(0, i) + removeMnemonics(s.substring(i+1)));
516
}
517
}
518
519
520
/**
521
* Returns mnemonic character from resource
522
*/
523
private static char getMnemonic(String key) {
524
String str = messageRB.getString(key).replace("&&", "");
525
int index = str.indexOf('&');
526
if (0 <= index && index < str.length() - 1) {
527
char c = str.charAt(index + 1);
528
return Character.toUpperCase(c);
529
} else {
530
return (char)0;
531
}
532
}
533
534
/**
535
* Returns the mnemonic as a KeyEvent.VK constant from the resource.
536
*/
537
static Class _keyEventClazz = null;
538
private static int getVKMnemonic(String key) {
539
String s = String.valueOf(getMnemonic(key));
540
if ( s == null || s.length() != 1) {
541
return 0;
542
}
543
String vkString = "VK_" + s.toUpperCase();
544
545
try {
546
if (_keyEventClazz == null) {
547
_keyEventClazz= Class.forName("java.awt.event.KeyEvent",
548
true, (ServiceDialog.class).getClassLoader());
549
}
550
Field field = _keyEventClazz.getDeclaredField(vkString);
551
int value = field.getInt(null);
552
return value;
553
} catch (Exception e) {
554
}
555
return 0;
556
}
557
558
/**
559
* Returns URL for image resource
560
*/
561
private static URL getImageResource(final String key) {
562
URL url = (URL)java.security.AccessController.doPrivileged(
563
new java.security.PrivilegedAction() {
564
public Object run() {
565
URL url = ServiceDialog.class.getResource(
566
"resources/" + key);
567
return url;
568
}
569
});
570
571
if (url == null) {
572
throw new Error("Fatal: Resource for ServiceUI is broken; " +
573
"there is no " + key + " key in resource");
574
}
575
576
return url;
577
}
578
579
/**
580
* Creates a new JButton and sets its text, mnemonic, and ActionListener
581
*/
582
private static JButton createButton(String key, ActionListener al) {
583
JButton btn = new JButton(getMsg(key));
584
btn.setMnemonic(getMnemonic(key));
585
btn.addActionListener(al);
586
587
return btn;
588
}
589
590
/**
591
* Creates a new JButton and sets its text, and ActionListener
592
*/
593
private static JButton createExitButton(String key, ActionListener al) {
594
String str = getMsg(key);
595
JButton btn = new JButton(str);
596
btn.addActionListener(al);
597
btn.getAccessibleContext().setAccessibleDescription(str);
598
return btn;
599
}
600
601
/**
602
* Creates a new JCheckBox and sets its text, mnemonic, and ActionListener
603
*/
604
private static JCheckBox createCheckBox(String key, ActionListener al) {
605
JCheckBox cb = new JCheckBox(getMsg(key));
606
cb.setMnemonic(getMnemonic(key));
607
cb.addActionListener(al);
608
609
return cb;
610
}
611
612
/**
613
* Creates a new JRadioButton and sets its text, mnemonic,
614
* and ActionListener
615
*/
616
private static JRadioButton createRadioButton(String key,
617
ActionListener al)
618
{
619
JRadioButton rb = new JRadioButton(getMsg(key));
620
rb.setMnemonic(getMnemonic(key));
621
rb.addActionListener(al);
622
623
return rb;
624
}
625
626
/**
627
* Creates a pop-up dialog for "no print service"
628
*/
629
public static void showNoPrintService(GraphicsConfiguration gc)
630
{
631
Frame dlgFrame = new Frame(gc);
632
JOptionPane.showMessageDialog(dlgFrame,
633
getMsg("dialog.noprintermsg"));
634
dlgFrame.dispose();
635
}
636
637
/**
638
* Sets the constraints for the GridBagLayout and adds the Component
639
* to the given Container
640
*/
641
private static void addToGB(Component comp, Container cont,
642
GridBagLayout gridbag,
643
GridBagConstraints constraints)
644
{
645
gridbag.setConstraints(comp, constraints);
646
cont.add(comp);
647
}
648
649
/**
650
* Adds the AbstractButton to both the given ButtonGroup and Container
651
*/
652
private static void addToBG(AbstractButton button, Container cont,
653
ButtonGroup bg)
654
{
655
bg.add(button);
656
cont.add(button);
657
}
658
659
660
661
662
/**
663
* The "General" tab. Includes the controls for PrintService,
664
* PageRange, and Copies/Collate.
665
*/
666
private class GeneralPanel extends JPanel {
667
668
private PrintServicePanel pnlPrintService;
669
private PrintRangePanel pnlPrintRange;
670
private CopiesPanel pnlCopies;
671
672
public GeneralPanel() {
673
super();
674
675
GridBagLayout gridbag = new GridBagLayout();
676
GridBagConstraints c = new GridBagConstraints();
677
678
setLayout(gridbag);
679
680
c.fill = GridBagConstraints.BOTH;
681
c.insets = panelInsets;
682
c.weightx = 1.0;
683
c.weighty = 1.0;
684
685
c.gridwidth = GridBagConstraints.REMAINDER;
686
pnlPrintService = new PrintServicePanel();
687
addToGB(pnlPrintService, this, gridbag, c);
688
689
c.gridwidth = GridBagConstraints.RELATIVE;
690
pnlPrintRange = new PrintRangePanel();
691
addToGB(pnlPrintRange, this, gridbag, c);
692
693
c.gridwidth = GridBagConstraints.REMAINDER;
694
pnlCopies = new CopiesPanel();
695
addToGB(pnlCopies, this, gridbag, c);
696
}
697
698
public boolean isPrintToFileRequested() {
699
return (pnlPrintService.isPrintToFileSelected());
700
}
701
702
public void updateInfo() {
703
pnlPrintService.updateInfo();
704
pnlPrintRange.updateInfo();
705
pnlCopies.updateInfo();
706
}
707
}
708
709
private class PrintServicePanel extends JPanel
710
implements ActionListener, ItemListener, PopupMenuListener
711
{
712
private final String strTitle = getMsg("border.printservice");
713
private FilePermission printToFilePermission;
714
private JButton btnProperties;
715
private JCheckBox cbPrintToFile;
716
private JComboBox cbName;
717
private JLabel lblType, lblStatus, lblInfo;
718
private ServiceUIFactory uiFactory;
719
private boolean changedService = false;
720
private boolean filePermission;
721
722
public PrintServicePanel() {
723
super();
724
725
uiFactory = psCurrent.getServiceUIFactory();
726
727
GridBagLayout gridbag = new GridBagLayout();
728
GridBagConstraints c = new GridBagConstraints();
729
730
setLayout(gridbag);
731
setBorder(BorderFactory.createTitledBorder(strTitle));
732
733
String[] psnames = new String[services.length];
734
for (int i = 0; i < psnames.length; i++) {
735
psnames[i] = services[i].getName();
736
}
737
cbName = new JComboBox(psnames);
738
cbName.setSelectedIndex(defaultServiceIndex);
739
cbName.addItemListener(this);
740
cbName.addPopupMenuListener(this);
741
742
c.fill = GridBagConstraints.BOTH;
743
c.insets = compInsets;
744
745
c.weightx = 0.0;
746
JLabel lblName = new JLabel(getMsg("label.psname"), JLabel.TRAILING);
747
lblName.setDisplayedMnemonic(getMnemonic("label.psname"));
748
lblName.setLabelFor(cbName);
749
addToGB(lblName, this, gridbag, c);
750
c.weightx = 1.0;
751
c.gridwidth = GridBagConstraints.RELATIVE;
752
addToGB(cbName, this, gridbag, c);
753
c.weightx = 0.0;
754
c.gridwidth = GridBagConstraints.REMAINDER;
755
btnProperties = createButton("button.properties", this);
756
addToGB(btnProperties, this, gridbag, c);
757
758
c.weighty = 1.0;
759
lblStatus = addLabel(getMsg("label.status"), gridbag, c);
760
lblStatus.setLabelFor(null);
761
762
lblType = addLabel(getMsg("label.pstype"), gridbag, c);
763
lblType.setLabelFor(null);
764
765
c.gridwidth = 1;
766
addToGB(new JLabel(getMsg("label.info"), JLabel.TRAILING),
767
this, gridbag, c);
768
c.gridwidth = GridBagConstraints.RELATIVE;
769
lblInfo = new JLabel();
770
lblInfo.setLabelFor(null);
771
772
addToGB(lblInfo, this, gridbag, c);
773
774
c.gridwidth = GridBagConstraints.REMAINDER;
775
cbPrintToFile = createCheckBox("checkbox.printtofile", this);
776
addToGB(cbPrintToFile, this, gridbag, c);
777
778
filePermission = allowedToPrintToFile();
779
}
780
781
public boolean isPrintToFileSelected() {
782
return cbPrintToFile.isSelected();
783
}
784
785
private JLabel addLabel(String text,
786
GridBagLayout gridbag, GridBagConstraints c)
787
{
788
c.gridwidth = 1;
789
addToGB(new JLabel(text, JLabel.TRAILING), this, gridbag, c);
790
791
c.gridwidth = GridBagConstraints.REMAINDER;
792
JLabel label = new JLabel();
793
addToGB(label, this, gridbag, c);
794
795
return label;
796
}
797
798
public void actionPerformed(ActionEvent e) {
799
Object source = e.getSource();
800
801
if (source == btnProperties) {
802
if (uiFactory != null) {
803
JDialog dialog = (JDialog)uiFactory.getUI(
804
ServiceUIFactory.MAIN_UIROLE,
805
ServiceUIFactory.JDIALOG_UI);
806
807
if (dialog != null) {
808
dialog.show();
809
} else {
810
DocumentPropertiesUI docPropertiesUI = null;
811
try {
812
docPropertiesUI =
813
(DocumentPropertiesUI)uiFactory.getUI
814
(DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE,
815
DocumentPropertiesUI.DOCPROPERTIESCLASSNAME);
816
} catch (Exception ex) {
817
}
818
if (docPropertiesUI != null) {
819
PrinterJobWrapper wrapper = (PrinterJobWrapper)
820
asCurrent.get(PrinterJobWrapper.class);
821
if (wrapper == null) {
822
return; // should not happen, defensive only.
823
}
824
PrinterJob job = wrapper.getPrinterJob();
825
if (job == null) {
826
return; // should not happen, defensive only.
827
}
828
PrintRequestAttributeSet newAttrs =
829
docPropertiesUI.showDocumentProperties
830
(job, ServiceDialog.this, psCurrent, asCurrent);
831
if (newAttrs != null) {
832
asCurrent.addAll(newAttrs);
833
updatePanels();
834
}
835
}
836
}
837
}
838
}
839
}
840
841
public void itemStateChanged(ItemEvent e) {
842
if (e.getStateChange() == ItemEvent.SELECTED) {
843
int index = cbName.getSelectedIndex();
844
845
if ((index >= 0) && (index < services.length)) {
846
if (!services[index].equals(psCurrent)) {
847
psCurrent = services[index];
848
uiFactory = psCurrent.getServiceUIFactory();
849
changedService = true;
850
851
Destination dest =
852
(Destination)asOriginal.get(Destination.class);
853
// to preserve the state of Print To File
854
if ((dest != null || isPrintToFileSelected())
855
&& psCurrent.isAttributeCategorySupported(
856
Destination.class)) {
857
858
if (dest != null) {
859
asCurrent.add(dest);
860
} else {
861
dest = (Destination)psCurrent.
862
getDefaultAttributeValue(Destination.class);
863
// "dest" should not be null. The following code
864
// is only added to safeguard against a possible
865
// buggy implementation of a PrintService having a
866
// null default Destination.
867
if (dest == null) {
868
try {
869
dest =
870
new Destination(new URI("file:out.prn"));
871
} catch (URISyntaxException ue) {
872
}
873
}
874
875
if (dest != null) {
876
asCurrent.add(dest);
877
}
878
}
879
} else {
880
asCurrent.remove(Destination.class);
881
}
882
}
883
}
884
}
885
}
886
887
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
888
changedService = false;
889
}
890
891
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
892
if (changedService) {
893
changedService = false;
894
updatePanels();
895
}
896
}
897
898
public void popupMenuCanceled(PopupMenuEvent e) {
899
}
900
901
/**
902
* We disable the "Print To File" checkbox if this returns false
903
*/
904
private boolean allowedToPrintToFile() {
905
try {
906
throwPrintToFile();
907
return true;
908
} catch (SecurityException e) {
909
return false;
910
}
911
}
912
913
/**
914
* Break this out as it may be useful when we allow API to
915
* specify printing to a file. In that case its probably right
916
* to throw a SecurityException if the permission is not granted.
917
*/
918
private void throwPrintToFile() {
919
SecurityManager security = System.getSecurityManager();
920
if (security != null) {
921
if (printToFilePermission == null) {
922
printToFilePermission =
923
new FilePermission("<<ALL FILES>>", "read,write");
924
}
925
security.checkPermission(printToFilePermission);
926
}
927
}
928
929
public void updateInfo() {
930
Class dstCategory = Destination.class;
931
boolean dstSupported = false;
932
boolean dstSelected = false;
933
boolean dstAllowed = filePermission ?
934
allowedToPrintToFile() : false;
935
936
// setup Destination (print-to-file) widgets
937
if (psCurrent.isAttributeCategorySupported(dstCategory)) {
938
dstSupported = true;
939
}
940
Destination dst = (Destination)asCurrent.get(dstCategory);
941
if (dst != null) {
942
dstSelected = true;
943
}
944
cbPrintToFile.setEnabled(dstSupported && dstAllowed);
945
cbPrintToFile.setSelected(dstSelected && dstAllowed
946
&& dstSupported);
947
948
// setup PrintService information widgets
949
Attribute type = psCurrent.getAttribute(PrinterMakeAndModel.class);
950
if (type != null) {
951
lblType.setText(type.toString());
952
}
953
Attribute status =
954
psCurrent.getAttribute(PrinterIsAcceptingJobs.class);
955
if (status != null) {
956
lblStatus.setText(getMsg(status.toString()));
957
}
958
Attribute info = psCurrent.getAttribute(PrinterInfo.class);
959
if (info != null) {
960
lblInfo.setText(info.toString());
961
}
962
btnProperties.setEnabled(uiFactory != null);
963
}
964
}
965
966
private class PrintRangePanel extends JPanel
967
implements ActionListener, FocusListener
968
{
969
private final String strTitle = getMsg("border.printrange");
970
private final PageRanges prAll = new PageRanges(1, Integer.MAX_VALUE);
971
private JRadioButton rbAll, rbPages, rbSelect;
972
private JFormattedTextField tfRangeFrom, tfRangeTo;
973
private JLabel lblRangeTo;
974
private boolean prSupported;
975
976
public PrintRangePanel() {
977
super();
978
979
GridBagLayout gridbag = new GridBagLayout();
980
GridBagConstraints c = new GridBagConstraints();
981
982
setLayout(gridbag);
983
setBorder(BorderFactory.createTitledBorder(strTitle));
984
985
c.fill = GridBagConstraints.BOTH;
986
c.insets = compInsets;
987
c.gridwidth = GridBagConstraints.REMAINDER;
988
989
ButtonGroup bg = new ButtonGroup();
990
JPanel pnlTop = new JPanel(new FlowLayout(FlowLayout.LEADING));
991
rbAll = createRadioButton("radiobutton.rangeall", this);
992
rbAll.setSelected(true);
993
bg.add(rbAll);
994
pnlTop.add(rbAll);
995
addToGB(pnlTop, this, gridbag, c);
996
997
// Selection never seemed to work so I'm commenting this part.
998
/*
999
if (isAWT) {
1000
JPanel pnlMiddle =
1001
new JPanel(new FlowLayout(FlowLayout.LEADING));
1002
rbSelect =
1003
createRadioButton("radiobutton.selection", this);
1004
bg.add(rbSelect);
1005
pnlMiddle.add(rbSelect);
1006
addToGB(pnlMiddle, this, gridbag, c);
1007
}
1008
*/
1009
1010
JPanel pnlBottom = new JPanel(new FlowLayout(FlowLayout.LEADING));
1011
rbPages = createRadioButton("radiobutton.rangepages", this);
1012
bg.add(rbPages);
1013
pnlBottom.add(rbPages);
1014
DecimalFormat format = new DecimalFormat("####0");
1015
format.setMinimumFractionDigits(0);
1016
format.setMaximumFractionDigits(0);
1017
format.setMinimumIntegerDigits(0);
1018
format.setMaximumIntegerDigits(5);
1019
format.setParseIntegerOnly(true);
1020
format.setDecimalSeparatorAlwaysShown(false);
1021
NumberFormatter nf = new NumberFormatter(format);
1022
nf.setMinimum(new Integer(1));
1023
nf.setMaximum(new Integer(Integer.MAX_VALUE));
1024
nf.setAllowsInvalid(true);
1025
nf.setCommitsOnValidEdit(true);
1026
tfRangeFrom = new JFormattedTextField(nf);
1027
tfRangeFrom.setColumns(4);
1028
tfRangeFrom.setEnabled(false);
1029
tfRangeFrom.addActionListener(this);
1030
tfRangeFrom.addFocusListener(this);
1031
tfRangeFrom.setFocusLostBehavior(
1032
JFormattedTextField.PERSIST);
1033
tfRangeFrom.getAccessibleContext().setAccessibleName(
1034
getMsg("radiobutton.rangepages"));
1035
pnlBottom.add(tfRangeFrom);
1036
lblRangeTo = new JLabel(getMsg("label.rangeto"));
1037
lblRangeTo.setEnabled(false);
1038
pnlBottom.add(lblRangeTo);
1039
NumberFormatter nfto;
1040
try {
1041
nfto = (NumberFormatter)nf.clone();
1042
} catch (CloneNotSupportedException e) {
1043
nfto = new NumberFormatter();
1044
}
1045
tfRangeTo = new JFormattedTextField(nfto);
1046
tfRangeTo.setColumns(4);
1047
tfRangeTo.setEnabled(false);
1048
tfRangeTo.addFocusListener(this);
1049
tfRangeTo.getAccessibleContext().setAccessibleName(
1050
getMsg("label.rangeto"));
1051
pnlBottom.add(tfRangeTo);
1052
addToGB(pnlBottom, this, gridbag, c);
1053
}
1054
1055
public void actionPerformed(ActionEvent e) {
1056
Object source = e.getSource();
1057
SunPageSelection select = SunPageSelection.ALL;
1058
1059
setupRangeWidgets();
1060
1061
if (source == rbAll) {
1062
asCurrent.add(prAll);
1063
} else if (source == rbSelect) {
1064
select = SunPageSelection.SELECTION;
1065
} else if (source == rbPages ||
1066
source == tfRangeFrom ||
1067
source == tfRangeTo) {
1068
updateRangeAttribute();
1069
select = SunPageSelection.RANGE;
1070
}
1071
1072
if (isAWT) {
1073
asCurrent.add(select);
1074
}
1075
}
1076
1077
public void focusLost(FocusEvent e) {
1078
Object source = e.getSource();
1079
1080
if ((source == tfRangeFrom) || (source == tfRangeTo)) {
1081
updateRangeAttribute();
1082
}
1083
}
1084
1085
public void focusGained(FocusEvent e) {}
1086
1087
private void setupRangeWidgets() {
1088
boolean rangeEnabled = (rbPages.isSelected() && prSupported);
1089
tfRangeFrom.setEnabled(rangeEnabled);
1090
tfRangeTo.setEnabled(rangeEnabled);
1091
lblRangeTo.setEnabled(rangeEnabled);
1092
}
1093
1094
private void updateRangeAttribute() {
1095
String strFrom = tfRangeFrom.getText();
1096
String strTo = tfRangeTo.getText();
1097
1098
int min;
1099
int max;
1100
1101
try {
1102
min = Integer.parseInt(strFrom);
1103
} catch (NumberFormatException e) {
1104
min = 1;
1105
}
1106
1107
try {
1108
max = Integer.parseInt(strTo);
1109
} catch (NumberFormatException e) {
1110
max = min;
1111
}
1112
1113
if (min < 1) {
1114
min = 1;
1115
tfRangeFrom.setValue(new Integer(1));
1116
}
1117
1118
if (max < min) {
1119
max = min;
1120
tfRangeTo.setValue(new Integer(min));
1121
}
1122
1123
PageRanges pr = new PageRanges(min, max);
1124
asCurrent.add(pr);
1125
}
1126
1127
public void updateInfo() {
1128
Class prCategory = PageRanges.class;
1129
prSupported = false;
1130
1131
if (psCurrent.isAttributeCategorySupported(prCategory) ||
1132
isAWT) {
1133
prSupported = true;
1134
}
1135
1136
SunPageSelection select = SunPageSelection.ALL;
1137
int min = 1;
1138
int max = 1;
1139
1140
PageRanges pr = (PageRanges)asCurrent.get(prCategory);
1141
if (pr != null) {
1142
if (!pr.equals(prAll)) {
1143
select = SunPageSelection.RANGE;
1144
1145
int[][] members = pr.getMembers();
1146
if ((members.length > 0) &&
1147
(members[0].length > 1)) {
1148
min = members[0][0];
1149
max = members[0][1];
1150
}
1151
}
1152
}
1153
1154
if (isAWT) {
1155
select = (SunPageSelection)asCurrent.get(
1156
SunPageSelection.class);
1157
}
1158
1159
if (select == SunPageSelection.ALL) {
1160
rbAll.setSelected(true);
1161
} else if (select == SunPageSelection.SELECTION) {
1162
// Comment this for now - rbSelect is not initialized
1163
// because Selection button is not added.
1164
// See PrintRangePanel above.
1165
1166
//rbSelect.setSelected(true);
1167
} else { // RANGE
1168
rbPages.setSelected(true);
1169
}
1170
tfRangeFrom.setValue(new Integer(min));
1171
tfRangeTo.setValue(new Integer(max));
1172
rbAll.setEnabled(prSupported);
1173
rbPages.setEnabled(prSupported);
1174
setupRangeWidgets();
1175
}
1176
}
1177
1178
private class CopiesPanel extends JPanel
1179
implements ActionListener, ChangeListener
1180
{
1181
private final String strTitle = getMsg("border.copies");
1182
private SpinnerNumberModel snModel;
1183
private JSpinner spinCopies;
1184
private JLabel lblCopies;
1185
private JCheckBox cbCollate;
1186
private boolean scSupported;
1187
1188
public CopiesPanel() {
1189
super();
1190
1191
GridBagLayout gridbag = new GridBagLayout();
1192
GridBagConstraints c = new GridBagConstraints();
1193
1194
setLayout(gridbag);
1195
setBorder(BorderFactory.createTitledBorder(strTitle));
1196
1197
c.fill = GridBagConstraints.HORIZONTAL;
1198
c.insets = compInsets;
1199
1200
lblCopies = new JLabel(getMsg("label.numcopies"), JLabel.TRAILING);
1201
lblCopies.setDisplayedMnemonic(getMnemonic("label.numcopies"));
1202
lblCopies.getAccessibleContext().setAccessibleName(
1203
getMsg("label.numcopies"));
1204
addToGB(lblCopies, this, gridbag, c);
1205
1206
snModel = new SpinnerNumberModel(1, 1, 999, 1);
1207
spinCopies = new JSpinner(snModel);
1208
lblCopies.setLabelFor(spinCopies);
1209
// REMIND
1210
((JSpinner.NumberEditor)spinCopies.getEditor()).getTextField().setColumns(3);
1211
spinCopies.addChangeListener(this);
1212
c.gridwidth = GridBagConstraints.REMAINDER;
1213
addToGB(spinCopies, this, gridbag, c);
1214
1215
cbCollate = createCheckBox("checkbox.collate", this);
1216
cbCollate.setEnabled(false);
1217
addToGB(cbCollate, this, gridbag, c);
1218
}
1219
1220
public void actionPerformed(ActionEvent e) {
1221
if (cbCollate.isSelected()) {
1222
asCurrent.add(SheetCollate.COLLATED);
1223
} else {
1224
asCurrent.add(SheetCollate.UNCOLLATED);
1225
}
1226
}
1227
1228
public void stateChanged(ChangeEvent e) {
1229
updateCollateCB();
1230
1231
asCurrent.add(new Copies(snModel.getNumber().intValue()));
1232
}
1233
1234
private void updateCollateCB() {
1235
int num = snModel.getNumber().intValue();
1236
if (isAWT) {
1237
cbCollate.setEnabled(true);
1238
} else {
1239
cbCollate.setEnabled((num > 1) && scSupported);
1240
}
1241
}
1242
1243
public void updateInfo() {
1244
Class cpCategory = Copies.class;
1245
Class csCategory = CopiesSupported.class;
1246
Class scCategory = SheetCollate.class;
1247
boolean cpSupported = false;
1248
scSupported = false;
1249
1250
// setup Copies spinner
1251
if (psCurrent.isAttributeCategorySupported(cpCategory)) {
1252
cpSupported = true;
1253
}
1254
CopiesSupported cs =
1255
(CopiesSupported)psCurrent.getSupportedAttributeValues(
1256
cpCategory, null, null);
1257
if (cs == null) {
1258
cs = new CopiesSupported(1, 999);
1259
}
1260
Copies cp = (Copies)asCurrent.get(cpCategory);
1261
if (cp == null) {
1262
cp = (Copies)psCurrent.getDefaultAttributeValue(cpCategory);
1263
if (cp == null) {
1264
cp = new Copies(1);
1265
}
1266
}
1267
spinCopies.setEnabled(cpSupported);
1268
lblCopies.setEnabled(cpSupported);
1269
1270
int[][] members = cs.getMembers();
1271
int min, max;
1272
if ((members.length > 0) && (members[0].length > 0)) {
1273
min = members[0][0];
1274
max = members[0][1];
1275
} else {
1276
min = 1;
1277
max = Integer.MAX_VALUE;
1278
}
1279
snModel.setMinimum(new Integer(min));
1280
snModel.setMaximum(new Integer(max));
1281
1282
int value = cp.getValue();
1283
if ((value < min) || (value > max)) {
1284
value = min;
1285
}
1286
snModel.setValue(new Integer(value));
1287
1288
// setup Collate checkbox
1289
if (psCurrent.isAttributeCategorySupported(scCategory)) {
1290
scSupported = true;
1291
}
1292
SheetCollate sc = (SheetCollate)asCurrent.get(scCategory);
1293
if (sc == null) {
1294
sc = (SheetCollate)psCurrent.getDefaultAttributeValue(scCategory);
1295
if (sc == null) {
1296
sc = SheetCollate.UNCOLLATED;
1297
}
1298
}
1299
cbCollate.setSelected(sc == SheetCollate.COLLATED);
1300
updateCollateCB();
1301
}
1302
}
1303
1304
1305
1306
1307
/**
1308
* The "Page Setup" tab. Includes the controls for MediaSource/MediaTray,
1309
* OrientationRequested, and Sides.
1310
*/
1311
private class PageSetupPanel extends JPanel {
1312
1313
private MediaPanel pnlMedia;
1314
private OrientationPanel pnlOrientation;
1315
private MarginsPanel pnlMargins;
1316
1317
public PageSetupPanel() {
1318
super();
1319
1320
GridBagLayout gridbag = new GridBagLayout();
1321
GridBagConstraints c = new GridBagConstraints();
1322
1323
setLayout(gridbag);
1324
1325
c.fill = GridBagConstraints.BOTH;
1326
c.insets = panelInsets;
1327
c.weightx = 1.0;
1328
c.weighty = 1.0;
1329
1330
c.gridwidth = GridBagConstraints.REMAINDER;
1331
pnlMedia = new MediaPanel();
1332
addToGB(pnlMedia, this, gridbag, c);
1333
1334
pnlOrientation = new OrientationPanel();
1335
c.gridwidth = GridBagConstraints.RELATIVE;
1336
addToGB(pnlOrientation, this, gridbag, c);
1337
1338
pnlMargins = new MarginsPanel();
1339
pnlOrientation.addOrientationListener(pnlMargins);
1340
pnlMedia.addMediaListener(pnlMargins);
1341
c.gridwidth = GridBagConstraints.REMAINDER;
1342
addToGB(pnlMargins, this, gridbag, c);
1343
}
1344
1345
public void updateInfo() {
1346
pnlMedia.updateInfo();
1347
pnlOrientation.updateInfo();
1348
pnlMargins.updateInfo();
1349
}
1350
}
1351
1352
private class MarginsPanel extends JPanel
1353
implements ActionListener, FocusListener {
1354
1355
private final String strTitle = getMsg("border.margins");
1356
private JFormattedTextField leftMargin, rightMargin,
1357
topMargin, bottomMargin;
1358
private JLabel lblLeft, lblRight, lblTop, lblBottom;
1359
private int units = MediaPrintableArea.MM;
1360
// storage for the last margin values calculated, -ve is uninitialised
1361
private float lmVal = -1f,rmVal = -1f, tmVal = -1f, bmVal = -1f;
1362
// storage for margins as objects mapped into orientation for display
1363
private Float lmObj,rmObj,tmObj,bmObj;
1364
1365
public MarginsPanel() {
1366
super();
1367
1368
GridBagLayout gridbag = new GridBagLayout();
1369
GridBagConstraints c = new GridBagConstraints();
1370
c.fill = GridBagConstraints.HORIZONTAL;
1371
c.weightx = 1.0;
1372
c.weighty = 0.0;
1373
c.insets = compInsets;
1374
1375
setLayout(gridbag);
1376
setBorder(BorderFactory.createTitledBorder(strTitle));
1377
1378
String unitsKey = "label.millimetres";
1379
String defaultCountry = Locale.getDefault().getCountry();
1380
if (defaultCountry != null &&
1381
(defaultCountry.equals("") ||
1382
defaultCountry.equals(Locale.US.getCountry()) ||
1383
defaultCountry.equals(Locale.CANADA.getCountry()))) {
1384
unitsKey = "label.inches";
1385
units = MediaPrintableArea.INCH;
1386
}
1387
String unitsMsg = getMsg(unitsKey);
1388
1389
DecimalFormat format;
1390
if (units == MediaPrintableArea.MM) {
1391
format = new DecimalFormat("###.##");
1392
format.setMaximumIntegerDigits(3);
1393
} else {
1394
format = new DecimalFormat("##.##");
1395
format.setMaximumIntegerDigits(2);
1396
}
1397
1398
format.setMinimumFractionDigits(1);
1399
format.setMaximumFractionDigits(2);
1400
format.setMinimumIntegerDigits(1);
1401
format.setParseIntegerOnly(false);
1402
format.setDecimalSeparatorAlwaysShown(true);
1403
NumberFormatter nf = new NumberFormatter(format);
1404
nf.setMinimum(new Float(0.0f));
1405
nf.setMaximum(new Float(999.0f));
1406
nf.setAllowsInvalid(true);
1407
nf.setCommitsOnValidEdit(true);
1408
1409
leftMargin = new JFormattedTextField(nf);
1410
leftMargin.addFocusListener(this);
1411
leftMargin.addActionListener(this);
1412
leftMargin.getAccessibleContext().setAccessibleName(
1413
getMsg("label.leftmargin"));
1414
rightMargin = new JFormattedTextField(nf);
1415
rightMargin.addFocusListener(this);
1416
rightMargin.addActionListener(this);
1417
rightMargin.getAccessibleContext().setAccessibleName(
1418
getMsg("label.rightmargin"));
1419
topMargin = new JFormattedTextField(nf);
1420
topMargin.addFocusListener(this);
1421
topMargin.addActionListener(this);
1422
topMargin.getAccessibleContext().setAccessibleName(
1423
getMsg("label.topmargin"));
1424
topMargin = new JFormattedTextField(nf);
1425
bottomMargin = new JFormattedTextField(nf);
1426
bottomMargin.addFocusListener(this);
1427
bottomMargin.addActionListener(this);
1428
bottomMargin.getAccessibleContext().setAccessibleName(
1429
getMsg("label.bottommargin"));
1430
topMargin = new JFormattedTextField(nf);
1431
c.gridwidth = GridBagConstraints.RELATIVE;
1432
lblLeft = new JLabel(getMsg("label.leftmargin") + " " + unitsMsg,
1433
JLabel.LEADING);
1434
lblLeft.setDisplayedMnemonic(getMnemonic("label.leftmargin"));
1435
lblLeft.setLabelFor(leftMargin);
1436
addToGB(lblLeft, this, gridbag, c);
1437
1438
c.gridwidth = GridBagConstraints.REMAINDER;
1439
lblRight = new JLabel(getMsg("label.rightmargin") + " " + unitsMsg,
1440
JLabel.LEADING);
1441
lblRight.setDisplayedMnemonic(getMnemonic("label.rightmargin"));
1442
lblRight.setLabelFor(rightMargin);
1443
addToGB(lblRight, this, gridbag, c);
1444
1445
c.gridwidth = GridBagConstraints.RELATIVE;
1446
addToGB(leftMargin, this, gridbag, c);
1447
1448
c.gridwidth = GridBagConstraints.REMAINDER;
1449
addToGB(rightMargin, this, gridbag, c);
1450
1451
// add an invisible spacing component.
1452
addToGB(new JPanel(), this, gridbag, c);
1453
1454
c.gridwidth = GridBagConstraints.RELATIVE;
1455
lblTop = new JLabel(getMsg("label.topmargin") + " " + unitsMsg,
1456
JLabel.LEADING);
1457
lblTop.setDisplayedMnemonic(getMnemonic("label.topmargin"));
1458
lblTop.setLabelFor(topMargin);
1459
addToGB(lblTop, this, gridbag, c);
1460
1461
c.gridwidth = GridBagConstraints.REMAINDER;
1462
lblBottom = new JLabel(getMsg("label.bottommargin") +
1463
" " + unitsMsg, JLabel.LEADING);
1464
lblBottom.setDisplayedMnemonic(getMnemonic("label.bottommargin"));
1465
lblBottom.setLabelFor(bottomMargin);
1466
addToGB(lblBottom, this, gridbag, c);
1467
1468
c.gridwidth = GridBagConstraints.RELATIVE;
1469
addToGB(topMargin, this, gridbag, c);
1470
1471
c.gridwidth = GridBagConstraints.REMAINDER;
1472
addToGB(bottomMargin, this, gridbag, c);
1473
1474
}
1475
1476
public void actionPerformed(ActionEvent e) {
1477
Object source = e.getSource();
1478
updateMargins(source);
1479
}
1480
1481
public void focusLost(FocusEvent e) {
1482
Object source = e.getSource();
1483
updateMargins(source);
1484
}
1485
1486
public void focusGained(FocusEvent e) {}
1487
1488
/* Get the numbers, use to create a MPA.
1489
* If its valid, accept it and update the attribute set.
1490
* If its not valid, then reject it and call updateInfo()
1491
* to re-establish the previous entries.
1492
*/
1493
public void updateMargins(Object source) {
1494
if (!(source instanceof JFormattedTextField)) {
1495
return;
1496
} else {
1497
JFormattedTextField tf = (JFormattedTextField)source;
1498
Float val = (Float)tf.getValue();
1499
if (val == null) {
1500
return;
1501
}
1502
if (tf == leftMargin && val.equals(lmObj)) {
1503
return;
1504
}
1505
if (tf == rightMargin && val.equals(rmObj)) {
1506
return;
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 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;
1548
lm = bm;
1549
bm = rm;
1550
rm = tm;
1551
tm = tmp;
1552
}
1553
MediaPrintableArea mpa;
1554
if ((mpa = validateMargins(lm, rm, tm, bm)) != null) {
1555
asCurrent.add(mpa);
1556
lmVal = lm;
1557
rmVal = rm;
1558
tmVal = tm;
1559
bmVal = bm;
1560
lmObj = lmTmpObj;
1561
rmObj = rmTmpObj;
1562
tmObj = tmTmpObj;
1563
bmObj = bmTmpObj;
1564
} else {
1565
if (lmObj == null || rmObj == null ||
1566
tmObj == null || rmObj == null) {
1567
return;
1568
} else {
1569
leftMargin.setValue(lmObj);
1570
rightMargin.setValue(rmObj);
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 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);
1612
1613
Object values =
1614
psCurrent.getSupportedAttributeValues(mpaCategory,
1615
docFlavor,
1616
tmpASet);
1617
if (values instanceof MediaPrintableArea[] &&
1618
((MediaPrintableArea[])values).length > 0) {
1619
mpaMax = ((MediaPrintableArea[])values)[0];
1620
1621
}
1622
}
1623
if (mpaMax == null) {
1624
mpaMax = new MediaPrintableArea(0f, 0f,
1625
mediaSize.getX(units),
1626
mediaSize.getY(units),
1627
units);
1628
}
1629
1630
float wid = mediaSize.getX(units);
1631
float hgt = mediaSize.getY(units);
1632
float pax = lm;
1633
float pay = tm;
1634
float paw = wid - lm - rm;
1635
float pah = hgt - tm - bm;
1636
1637
if (paw <= 0f || pah <= 0f || pax < 0f || pay < 0f ||
1638
pax < mpaMax.getX(units) || paw > mpaMax.getWidth(units) ||
1639
pay < mpaMax.getY(units) || pah > mpaMax.getHeight(units)) {
1640
return null;
1641
} else {
1642
return new MediaPrintableArea(lm, tm, paw, pah, units);
1643
}
1644
}
1645
1646
/* This is complex as a MediaPrintableArea is valid only within
1647
* a particular context of media size.
1648
* So we need a MediaSize as well as a MediaPrintableArea.
1649
* MediaSize can be obtained from MediaSizeName.
1650
* If the application specifies a MediaPrintableArea, we accept it
1651
* to the extent its valid for the Media they specify. If they
1652
* don't specify a Media, then the default is assumed.
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 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);
1694
tmpASet.add(media);
1695
1696
Object values =
1697
psCurrent.getSupportedAttributeValues(mpaCategory,
1698
docFlavor,
1699
tmpASet);
1700
if (values instanceof MediaPrintableArea[] &&
1701
((MediaPrintableArea[])values).length > 0) {
1702
mpaMax = ((MediaPrintableArea[])values)[0];
1703
1704
} else if (values instanceof MediaPrintableArea) {
1705
mpaMax = (MediaPrintableArea)values;
1706
}
1707
}
1708
if (mpaMax == null) {
1709
mpaMax = new MediaPrintableArea(0f, 0f,
1710
mediaSize.getX(units),
1711
mediaSize.getY(units),
1712
units);
1713
}
1714
1715
/*
1716
* At this point we now know as best we can :-
1717
* - the media size
1718
* - the maximum corresponding printable area
1719
* - the media printable area specified by the client, if any.
1720
* The next step is to create a default MPA if none was specified.
1721
* 1" margins are used unless they are disproportionately
1722
* large compared to the size of the media.
1723
*/
1724
1725
float wid = mediaSize.getX(MediaPrintableArea.INCH);
1726
float hgt = mediaSize.getY(MediaPrintableArea.INCH);
1727
float maxMarginRatio = 5f;
1728
float xMgn, yMgn;
1729
if (wid > maxMarginRatio) {
1730
xMgn = 1f;
1731
} else {
1732
xMgn = wid / maxMarginRatio;
1733
}
1734
if (hgt > maxMarginRatio) {
1735
yMgn = 1f;
1736
} else {
1737
yMgn = hgt / maxMarginRatio;
1738
}
1739
1740
if (mpa == null) {
1741
mpa = new MediaPrintableArea(xMgn, yMgn,
1742
wid-(2*xMgn), hgt-(2*yMgn),
1743
MediaPrintableArea.INCH);
1744
asCurrent.add(mpa);
1745
}
1746
float pax = mpa.getX(units);
1747
float pay = mpa.getY(units);
1748
float paw = mpa.getWidth(units);
1749
float pah = mpa.getHeight(units);
1750
float paxMax = mpaMax.getX(units);
1751
float payMax = mpaMax.getY(units);
1752
float pawMax = mpaMax.getWidth(units);
1753
float pahMax = mpaMax.getHeight(units);
1754
1755
1756
boolean invalid = false;
1757
1758
// If the paper is set to something which is too small to
1759
// accommodate a specified printable area, perhaps carried
1760
// over from a larger paper, the adjustment that needs to be
1761
// performed should seem the most natural from a user's viewpoint.
1762
// Since the user is specifying margins, then we are biased
1763
// towards keeping the margins as close to what is specified as
1764
// possible, shrinking or growing the printable area.
1765
// But the API uses printable area, so you need to know the
1766
// media size in which the margins were previously interpreted,
1767
// or at least have a record of the margins.
1768
// In the case that this is the creation of this UI we do not
1769
// have this record, so we are somewhat reliant on the client
1770
// to supply a reasonable default
1771
wid = mediaSize.getX(units);
1772
hgt = mediaSize.getY(units);
1773
if (lmVal >= 0f) {
1774
invalid = true;
1775
1776
if (lmVal + rmVal > wid) {
1777
// margins impossible, but maintain P.A if can
1778
if (paw > pawMax) {
1779
paw = pawMax;
1780
}
1781
// try to centre the printable area.
1782
pax = (wid - paw)/2f;
1783
} else {
1784
pax = (lmVal >= paxMax) ? lmVal : paxMax;
1785
paw = wid - pax - rmVal;
1786
}
1787
if (tmVal + bmVal > hgt) {
1788
if (pah > pahMax) {
1789
pah = pahMax;
1790
}
1791
pay = (hgt - pah)/2f;
1792
} else {
1793
pay = (tmVal >= payMax) ? tmVal : payMax;
1794
pah = hgt - pay - bmVal;
1795
}
1796
}
1797
if (pax < paxMax) {
1798
invalid = true;
1799
pax = paxMax;
1800
}
1801
if (pay < payMax) {
1802
invalid = true;
1803
pay = payMax;
1804
}
1805
if (paw > pawMax) {
1806
invalid = true;
1807
paw = pawMax;
1808
}
1809
if (pah > pahMax) {
1810
invalid = true;
1811
pah = pahMax;
1812
}
1813
1814
if ((pax + paw > paxMax + pawMax) || (paw <= 0f)) {
1815
invalid = true;
1816
pax = paxMax;
1817
paw = pawMax;
1818
}
1819
if ((pay + pah > payMax + pahMax) || (pah <= 0f)) {
1820
invalid = true;
1821
pay = payMax;
1822
pah = pahMax;
1823
}
1824
1825
if (invalid) {
1826
mpa = new MediaPrintableArea(pax, pay, paw, pah, units);
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 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
private class MediaPanel extends JPanel implements ItemListener {
1883
1884
private final String strTitle = getMsg("border.media");
1885
private JLabel lblSize, lblSource;
1886
private JComboBox cbSize, cbSource;
1887
private Vector sizes = new Vector();
1888
private Vector sources = new Vector();
1889
private MarginsPanel pnlMargins = null;
1890
1891
public MediaPanel() {
1892
super();
1893
1894
GridBagLayout gridbag = new GridBagLayout();
1895
GridBagConstraints c = new GridBagConstraints();
1896
1897
setLayout(gridbag);
1898
setBorder(BorderFactory.createTitledBorder(strTitle));
1899
1900
cbSize = new JComboBox();
1901
cbSource = new JComboBox();
1902
1903
c.fill = GridBagConstraints.BOTH;
1904
c.insets = compInsets;
1905
c.weighty = 1.0;
1906
1907
c.weightx = 0.0;
1908
lblSize = new JLabel(getMsg("label.size"), JLabel.TRAILING);
1909
lblSize.setDisplayedMnemonic(getMnemonic("label.size"));
1910
lblSize.setLabelFor(cbSize);
1911
addToGB(lblSize, this, gridbag, c);
1912
c.weightx = 1.0;
1913
c.gridwidth = GridBagConstraints.REMAINDER;
1914
addToGB(cbSize, this, gridbag, c);
1915
1916
c.weightx = 0.0;
1917
c.gridwidth = 1;
1918
lblSource = new JLabel(getMsg("label.source"), JLabel.TRAILING);
1919
lblSource.setDisplayedMnemonic(getMnemonic("label.source"));
1920
lblSource.setLabelFor(cbSource);
1921
addToGB(lblSource, this, gridbag, c);
1922
c.gridwidth = GridBagConstraints.REMAINDER;
1923
addToGB(cbSource, this, gridbag, c);
1924
}
1925
1926
private String getMediaName(String key) {
1927
try {
1928
// replace characters that would be invalid in
1929
// a resource key with valid characters
1930
String newkey = key.replace(' ', '-');
1931
newkey = newkey.replace('#', 'n');
1932
1933
return messageRB.getString(newkey);
1934
} catch (java.util.MissingResourceException e) {
1935
return key;
1936
}
1937
}
1938
1939
public void itemStateChanged(ItemEvent e) {
1940
Object source = e.getSource();
1941
1942
if (e.getStateChange() == ItemEvent.SELECTED) {
1943
if (source == cbSize) {
1944
int index = cbSize.getSelectedIndex();
1945
1946
if ((index >= 0) && (index < sizes.size())) {
1947
if ((cbSource.getItemCount() > 1) &&
1948
(cbSource.getSelectedIndex() >= 1))
1949
{
1950
int src = cbSource.getSelectedIndex() - 1;
1951
MediaTray mt = (MediaTray)sources.get(src);
1952
asCurrent.add(new SunAlternateMedia(mt));
1953
}
1954
asCurrent.add((MediaSizeName)sizes.get(index));
1955
}
1956
} else if (source == cbSource) {
1957
int index = cbSource.getSelectedIndex();
1958
1959
if ((index >= 1) && (index < (sources.size() + 1))) {
1960
asCurrent.remove(SunAlternateMedia.class);
1961
MediaTray newTray = (MediaTray)sources.get(index - 1);
1962
Media m = (Media)asCurrent.get(Media.class);
1963
if (m == null || m instanceof MediaTray) {
1964
asCurrent.add(newTray);
1965
} else if (m instanceof MediaSizeName) {
1966
MediaSizeName msn = (MediaSizeName)m;
1967
Media def = (Media)psCurrent.getDefaultAttributeValue(Media.class);
1968
if (def instanceof MediaSizeName && def.equals(msn)) {
1969
asCurrent.add(newTray);
1970
} else {
1971
/* Non-default paper size, so need to store tray
1972
* as SunAlternateMedia
1973
*/
1974
asCurrent.add(new SunAlternateMedia(newTray));
1975
}
1976
}
1977
} else if (index == 0) {
1978
asCurrent.remove(SunAlternateMedia.class);
1979
if (cbSize.getItemCount() > 0) {
1980
int size = cbSize.getSelectedIndex();
1981
asCurrent.add((MediaSizeName)sizes.get(size));
1982
}
1983
}
1984
}
1985
// orientation affects display of margins.
1986
if (pnlMargins != null) {
1987
pnlMargins.updateInfo();
1988
}
1989
}
1990
}
1991
1992
1993
/* this is ad hoc to keep things simple */
1994
public void addMediaListener(MarginsPanel pnl) {
1995
pnlMargins = pnl;
1996
}
1997
public void updateInfo() {
1998
Class mdCategory = Media.class;
1999
Class amCategory = SunAlternateMedia.class;
2000
boolean mediaSupported = false;
2001
2002
cbSize.removeItemListener(this);
2003
cbSize.removeAllItems();
2004
cbSource.removeItemListener(this);
2005
cbSource.removeAllItems();
2006
cbSource.addItem(getMediaName("auto-select"));
2007
2008
sizes.clear();
2009
sources.clear();
2010
2011
if (psCurrent.isAttributeCategorySupported(mdCategory)) {
2012
mediaSupported = true;
2013
2014
Object values =
2015
psCurrent.getSupportedAttributeValues(mdCategory,
2016
docFlavor,
2017
asCurrent);
2018
2019
if (values instanceof Media[]) {
2020
Media[] media = (Media[])values;
2021
2022
for (int i = 0; i < media.length; i++) {
2023
Media medium = media[i];
2024
2025
if (medium instanceof MediaSizeName) {
2026
sizes.add(medium);
2027
cbSize.addItem(getMediaName(medium.toString()));
2028
} else if (medium instanceof MediaTray) {
2029
sources.add(medium);
2030
cbSource.addItem(getMediaName(medium.toString()));
2031
}
2032
}
2033
}
2034
}
2035
2036
boolean msSupported = (mediaSupported && (sizes.size() > 0));
2037
lblSize.setEnabled(msSupported);
2038
cbSize.setEnabled(msSupported);
2039
2040
if (isAWT) {
2041
cbSource.setEnabled(false);
2042
lblSource.setEnabled(false);
2043
} else {
2044
cbSource.setEnabled(mediaSupported);
2045
}
2046
2047
if (mediaSupported) {
2048
2049
Media medium = (Media)asCurrent.get(mdCategory);
2050
2051
// initialize size selection to default
2052
Media defMedia = (Media)psCurrent.getDefaultAttributeValue(mdCategory);
2053
if (defMedia instanceof MediaSizeName) {
2054
cbSize.setSelectedIndex(sizes.size() > 0 ? sizes.indexOf(defMedia) : -1);
2055
}
2056
2057
if (medium == null ||
2058
!psCurrent.isAttributeValueSupported(medium,
2059
docFlavor, asCurrent)) {
2060
2061
medium = defMedia;
2062
2063
if (medium == null) {
2064
if (sizes.size() > 0) {
2065
medium = (Media)sizes.get(0);
2066
}
2067
}
2068
if (medium != null) {
2069
asCurrent.add(medium);
2070
}
2071
}
2072
if (medium != null) {
2073
if (medium instanceof MediaSizeName) {
2074
MediaSizeName ms = (MediaSizeName)medium;
2075
cbSize.setSelectedIndex(sizes.indexOf(ms));
2076
} else if (medium instanceof MediaTray) {
2077
MediaTray mt = (MediaTray)medium;
2078
cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
2079
}
2080
} else {
2081
cbSize.setSelectedIndex(sizes.size() > 0 ? 0 : -1);
2082
cbSource.setSelectedIndex(0);
2083
}
2084
2085
SunAlternateMedia alt = (SunAlternateMedia)asCurrent.get(amCategory);
2086
if (alt != null) {
2087
Media md = alt.getMedia();
2088
if (md instanceof MediaTray) {
2089
MediaTray mt = (MediaTray)md;
2090
cbSource.setSelectedIndex(sources.indexOf(mt) + 1);
2091
}
2092
}
2093
2094
int selIndex = cbSize.getSelectedIndex();
2095
if ((selIndex >= 0) && (selIndex < sizes.size())) {
2096
asCurrent.add((MediaSizeName)sizes.get(selIndex));
2097
}
2098
2099
selIndex = cbSource.getSelectedIndex();
2100
if ((selIndex >= 1) && (selIndex < (sources.size()+1))) {
2101
MediaTray mt = (MediaTray)sources.get(selIndex-1);
2102
if (medium instanceof MediaTray) {
2103
asCurrent.add(mt);
2104
} else {
2105
asCurrent.add(new SunAlternateMedia(mt));
2106
}
2107
}
2108
2109
2110
}
2111
cbSize.addItemListener(this);
2112
cbSource.addItemListener(this);
2113
}
2114
}
2115
2116
private class OrientationPanel extends JPanel
2117
implements ActionListener
2118
{
2119
private final String strTitle = getMsg("border.orientation");
2120
private IconRadioButton rbPortrait, rbLandscape,
2121
rbRevPortrait, rbRevLandscape;
2122
private MarginsPanel pnlMargins = null;
2123
2124
public OrientationPanel() {
2125
super();
2126
2127
GridBagLayout gridbag = new GridBagLayout();
2128
GridBagConstraints c = new GridBagConstraints();
2129
2130
setLayout(gridbag);
2131
setBorder(BorderFactory.createTitledBorder(strTitle));
2132
2133
c.fill = GridBagConstraints.BOTH;
2134
c.insets = compInsets;
2135
c.weighty = 1.0;
2136
c.gridwidth = GridBagConstraints.REMAINDER;
2137
2138
ButtonGroup bg = new ButtonGroup();
2139
rbPortrait = new IconRadioButton("radiobutton.portrait",
2140
"orientPortrait.png", true,
2141
bg, this);
2142
rbPortrait.addActionListener(this);
2143
addToGB(rbPortrait, this, gridbag, c);
2144
rbLandscape = new IconRadioButton("radiobutton.landscape",
2145
"orientLandscape.png", false,
2146
bg, this);
2147
rbLandscape.addActionListener(this);
2148
addToGB(rbLandscape, this, gridbag, c);
2149
rbRevPortrait = new IconRadioButton("radiobutton.revportrait",
2150
"orientRevPortrait.png", false,
2151
bg, this);
2152
rbRevPortrait.addActionListener(this);
2153
addToGB(rbRevPortrait, this, gridbag, c);
2154
rbRevLandscape = new IconRadioButton("radiobutton.revlandscape",
2155
"orientRevLandscape.png", false,
2156
bg, this);
2157
rbRevLandscape.addActionListener(this);
2158
addToGB(rbRevLandscape, this, gridbag, c);
2159
}
2160
2161
public void actionPerformed(ActionEvent e) {
2162
Object source = e.getSource();
2163
2164
if (rbPortrait.isSameAs(source)) {
2165
asCurrent.add(OrientationRequested.PORTRAIT);
2166
} else if (rbLandscape.isSameAs(source)) {
2167
asCurrent.add(OrientationRequested.LANDSCAPE);
2168
} else if (rbRevPortrait.isSameAs(source)) {
2169
asCurrent.add(OrientationRequested.REVERSE_PORTRAIT);
2170
} else if (rbRevLandscape.isSameAs(source)) {
2171
asCurrent.add(OrientationRequested.REVERSE_LANDSCAPE);
2172
}
2173
// orientation affects display of margins.
2174
if (pnlMargins != null) {
2175
pnlMargins.updateInfo();
2176
}
2177
}
2178
2179
/* This is ad hoc to keep things simple */
2180
void addOrientationListener(MarginsPanel pnl) {
2181
pnlMargins = pnl;
2182
}
2183
2184
public void updateInfo() {
2185
Class orCategory = OrientationRequested.class;
2186
boolean pSupported = false;
2187
boolean lSupported = false;
2188
boolean rpSupported = false;
2189
boolean rlSupported = false;
2190
2191
if (isAWT) {
2192
pSupported = true;
2193
lSupported = true;
2194
} else
2195
if (psCurrent.isAttributeCategorySupported(orCategory)) {
2196
Object values =
2197
psCurrent.getSupportedAttributeValues(orCategory,
2198
docFlavor,
2199
asCurrent);
2200
2201
if (values instanceof OrientationRequested[]) {
2202
OrientationRequested[] ovalues =
2203
(OrientationRequested[])values;
2204
2205
for (int i = 0; i < ovalues.length; i++) {
2206
OrientationRequested value = ovalues[i];
2207
2208
if (value == OrientationRequested.PORTRAIT) {
2209
pSupported = true;
2210
} else if (value == OrientationRequested.LANDSCAPE) {
2211
lSupported = true;
2212
} else if (value == OrientationRequested.REVERSE_PORTRAIT) {
2213
rpSupported = true;
2214
} else if (value == OrientationRequested.REVERSE_LANDSCAPE) {
2215
rlSupported = true;
2216
}
2217
}
2218
}
2219
}
2220
2221
2222
rbPortrait.setEnabled(pSupported);
2223
rbLandscape.setEnabled(lSupported);
2224
rbRevPortrait.setEnabled(rpSupported);
2225
rbRevLandscape.setEnabled(rlSupported);
2226
2227
OrientationRequested or = (OrientationRequested)asCurrent.get(orCategory);
2228
if (or == null ||
2229
!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
2230
2231
or = (OrientationRequested)psCurrent.getDefaultAttributeValue(orCategory);
2232
// need to validate if default is not supported
2233
if ((or != null) &&
2234
!psCurrent.isAttributeValueSupported(or, docFlavor, asCurrent)) {
2235
or = null;
2236
Object values =
2237
psCurrent.getSupportedAttributeValues(orCategory,
2238
docFlavor,
2239
asCurrent);
2240
if (values instanceof OrientationRequested[]) {
2241
OrientationRequested[] orValues =
2242
(OrientationRequested[])values;
2243
if (orValues.length > 1) {
2244
// get the first in the list
2245
or = orValues[0];
2246
}
2247
}
2248
}
2249
2250
if (or == null) {
2251
or = OrientationRequested.PORTRAIT;
2252
}
2253
asCurrent.add(or);
2254
}
2255
2256
if (or == OrientationRequested.PORTRAIT) {
2257
rbPortrait.setSelected(true);
2258
} else if (or == OrientationRequested.LANDSCAPE) {
2259
rbLandscape.setSelected(true);
2260
} else if (or == OrientationRequested.REVERSE_PORTRAIT) {
2261
rbRevPortrait.setSelected(true);
2262
} else { // if (or == OrientationRequested.REVERSE_LANDSCAPE)
2263
rbRevLandscape.setSelected(true);
2264
}
2265
}
2266
}
2267
2268
2269
2270
/**
2271
* The "Appearance" tab. Includes the controls for Chromaticity,
2272
* PrintQuality, JobPriority, JobName, and other related job attributes.
2273
*/
2274
private class AppearancePanel extends JPanel {
2275
2276
private ChromaticityPanel pnlChromaticity;
2277
private QualityPanel pnlQuality;
2278
private JobAttributesPanel pnlJobAttributes;
2279
private SidesPanel pnlSides;
2280
2281
public AppearancePanel() {
2282
super();
2283
2284
GridBagLayout gridbag = new GridBagLayout();
2285
GridBagConstraints c = new GridBagConstraints();
2286
2287
setLayout(gridbag);
2288
2289
c.fill = GridBagConstraints.BOTH;
2290
c.insets = panelInsets;
2291
c.weightx = 1.0;
2292
c.weighty = 1.0;
2293
2294
c.gridwidth = GridBagConstraints.RELATIVE;
2295
pnlChromaticity = new ChromaticityPanel();
2296
addToGB(pnlChromaticity, this, gridbag, c);
2297
2298
c.gridwidth = GridBagConstraints.REMAINDER;
2299
pnlQuality = new QualityPanel();
2300
addToGB(pnlQuality, this, gridbag, c);
2301
2302
c.gridwidth = 1;
2303
pnlSides = new SidesPanel();
2304
addToGB(pnlSides, this, gridbag, c);
2305
2306
c.gridwidth = GridBagConstraints.REMAINDER;
2307
pnlJobAttributes = new JobAttributesPanel();
2308
addToGB(pnlJobAttributes, this, gridbag, c);
2309
2310
}
2311
2312
public void updateInfo() {
2313
pnlChromaticity.updateInfo();
2314
pnlQuality.updateInfo();
2315
pnlSides.updateInfo();
2316
pnlJobAttributes.updateInfo();
2317
}
2318
}
2319
2320
private class ChromaticityPanel extends JPanel
2321
implements ActionListener
2322
{
2323
private final String strTitle = getMsg("border.chromaticity");
2324
private JRadioButton rbMonochrome, rbColor;
2325
2326
public ChromaticityPanel() {
2327
super();
2328
2329
GridBagLayout gridbag = new GridBagLayout();
2330
GridBagConstraints c = new GridBagConstraints();
2331
2332
setLayout(gridbag);
2333
setBorder(BorderFactory.createTitledBorder(strTitle));
2334
2335
c.fill = GridBagConstraints.BOTH;
2336
c.gridwidth = GridBagConstraints.REMAINDER;
2337
c.weighty = 1.0;
2338
2339
ButtonGroup bg = new ButtonGroup();
2340
rbMonochrome = createRadioButton("radiobutton.monochrome", this);
2341
rbMonochrome.setSelected(true);
2342
bg.add(rbMonochrome);
2343
addToGB(rbMonochrome, this, gridbag, c);
2344
rbColor = createRadioButton("radiobutton.color", this);
2345
bg.add(rbColor);
2346
addToGB(rbColor, this, gridbag, c);
2347
}
2348
2349
public void actionPerformed(ActionEvent e) {
2350
Object source = e.getSource();
2351
2352
// REMIND: use isSameAs if we move to a IconRB in the future
2353
if (source == rbMonochrome) {
2354
asCurrent.add(Chromaticity.MONOCHROME);
2355
} else if (source == rbColor) {
2356
asCurrent.add(Chromaticity.COLOR);
2357
}
2358
}
2359
2360
public void updateInfo() {
2361
Class chCategory = Chromaticity.class;
2362
boolean monoSupported = false;
2363
boolean colorSupported = false;
2364
2365
if (isAWT) {
2366
monoSupported = true;
2367
colorSupported = true;
2368
} else
2369
if (psCurrent.isAttributeCategorySupported(chCategory)) {
2370
Object values =
2371
psCurrent.getSupportedAttributeValues(chCategory,
2372
docFlavor,
2373
asCurrent);
2374
2375
if (values instanceof Chromaticity[]) {
2376
Chromaticity[] cvalues = (Chromaticity[])values;
2377
2378
for (int i = 0; i < cvalues.length; i++) {
2379
Chromaticity value = cvalues[i];
2380
2381
if (value == Chromaticity.MONOCHROME) {
2382
monoSupported = true;
2383
} else if (value == Chromaticity.COLOR) {
2384
colorSupported = true;
2385
}
2386
}
2387
}
2388
}
2389
2390
2391
rbMonochrome.setEnabled(monoSupported);
2392
rbColor.setEnabled(colorSupported);
2393
2394
Chromaticity ch = (Chromaticity)asCurrent.get(chCategory);
2395
if (ch == null) {
2396
ch = (Chromaticity)psCurrent.getDefaultAttributeValue(chCategory);
2397
if (ch == null) {
2398
ch = Chromaticity.MONOCHROME;
2399
}
2400
}
2401
2402
if (ch == Chromaticity.MONOCHROME) {
2403
rbMonochrome.setSelected(true);
2404
} else { // if (ch == Chromaticity.COLOR)
2405
rbColor.setSelected(true);
2406
}
2407
}
2408
}
2409
2410
private class QualityPanel extends JPanel
2411
implements ActionListener
2412
{
2413
private final String strTitle = getMsg("border.quality");
2414
private JRadioButton rbDraft, rbNormal, rbHigh;
2415
2416
public QualityPanel() {
2417
super();
2418
2419
GridBagLayout gridbag = new GridBagLayout();
2420
GridBagConstraints c = new GridBagConstraints();
2421
2422
setLayout(gridbag);
2423
setBorder(BorderFactory.createTitledBorder(strTitle));
2424
2425
c.fill = GridBagConstraints.BOTH;
2426
c.gridwidth = GridBagConstraints.REMAINDER;
2427
c.weighty = 1.0;
2428
2429
ButtonGroup bg = new ButtonGroup();
2430
rbDraft = createRadioButton("radiobutton.draftq", this);
2431
bg.add(rbDraft);
2432
addToGB(rbDraft, this, gridbag, c);
2433
rbNormal = createRadioButton("radiobutton.normalq", this);
2434
rbNormal.setSelected(true);
2435
bg.add(rbNormal);
2436
addToGB(rbNormal, this, gridbag, c);
2437
rbHigh = createRadioButton("radiobutton.highq", this);
2438
bg.add(rbHigh);
2439
addToGB(rbHigh, this, gridbag, c);
2440
}
2441
2442
public void actionPerformed(ActionEvent e) {
2443
Object source = e.getSource();
2444
2445
if (source == rbDraft) {
2446
asCurrent.add(PrintQuality.DRAFT);
2447
} else if (source == rbNormal) {
2448
asCurrent.add(PrintQuality.NORMAL);
2449
} else if (source == rbHigh) {
2450
asCurrent.add(PrintQuality.HIGH);
2451
}
2452
}
2453
2454
public void updateInfo() {
2455
Class pqCategory = PrintQuality.class;
2456
boolean draftSupported = false;
2457
boolean normalSupported = false;
2458
boolean highSupported = false;
2459
2460
if (isAWT) {
2461
draftSupported = true;
2462
normalSupported = true;
2463
highSupported = true;
2464
} else
2465
if (psCurrent.isAttributeCategorySupported(pqCategory)) {
2466
Object values =
2467
psCurrent.getSupportedAttributeValues(pqCategory,
2468
docFlavor,
2469
asCurrent);
2470
2471
if (values instanceof PrintQuality[]) {
2472
PrintQuality[] qvalues = (PrintQuality[])values;
2473
2474
for (int i = 0; i < qvalues.length; i++) {
2475
PrintQuality value = qvalues[i];
2476
2477
if (value == PrintQuality.DRAFT) {
2478
draftSupported = true;
2479
} else if (value == PrintQuality.NORMAL) {
2480
normalSupported = true;
2481
} else if (value == PrintQuality.HIGH) {
2482
highSupported = true;
2483
}
2484
}
2485
}
2486
}
2487
2488
rbDraft.setEnabled(draftSupported);
2489
rbNormal.setEnabled(normalSupported);
2490
rbHigh.setEnabled(highSupported);
2491
2492
PrintQuality pq = (PrintQuality)asCurrent.get(pqCategory);
2493
if (pq == null) {
2494
pq = (PrintQuality)psCurrent.getDefaultAttributeValue(pqCategory);
2495
if (pq == null) {
2496
pq = PrintQuality.NORMAL;
2497
}
2498
}
2499
2500
if (pq == PrintQuality.DRAFT) {
2501
rbDraft.setSelected(true);
2502
} else if (pq == PrintQuality.NORMAL) {
2503
rbNormal.setSelected(true);
2504
} else { // if (pq == PrintQuality.HIGH)
2505
rbHigh.setSelected(true);
2506
}
2507
}
2508
2509
2510
}
2511
private class SidesPanel extends JPanel
2512
implements ActionListener
2513
{
2514
private final String strTitle = getMsg("border.sides");
2515
private IconRadioButton rbOneSide, rbTumble, rbDuplex;
2516
2517
public SidesPanel() {
2518
super();
2519
2520
GridBagLayout gridbag = new GridBagLayout();
2521
GridBagConstraints c = new GridBagConstraints();
2522
2523
setLayout(gridbag);
2524
setBorder(BorderFactory.createTitledBorder(strTitle));
2525
2526
c.fill = GridBagConstraints.BOTH;
2527
c.insets = compInsets;
2528
c.weighty = 1.0;
2529
c.gridwidth = GridBagConstraints.REMAINDER;
2530
2531
ButtonGroup bg = new ButtonGroup();
2532
rbOneSide = new IconRadioButton("radiobutton.oneside",
2533
"oneside.png", true,
2534
bg, this);
2535
rbOneSide.addActionListener(this);
2536
addToGB(rbOneSide, this, gridbag, c);
2537
rbTumble = new IconRadioButton("radiobutton.tumble",
2538
"tumble.png", false,
2539
bg, this);
2540
rbTumble.addActionListener(this);
2541
addToGB(rbTumble, this, gridbag, c);
2542
rbDuplex = new IconRadioButton("radiobutton.duplex",
2543
"duplex.png", false,
2544
bg, this);
2545
rbDuplex.addActionListener(this);
2546
c.gridwidth = GridBagConstraints.REMAINDER;
2547
addToGB(rbDuplex, this, gridbag, c);
2548
}
2549
2550
public void actionPerformed(ActionEvent e) {
2551
Object source = e.getSource();
2552
2553
if (rbOneSide.isSameAs(source)) {
2554
asCurrent.add(Sides.ONE_SIDED);
2555
} else if (rbTumble.isSameAs(source)) {
2556
asCurrent.add(Sides.TUMBLE);
2557
} else if (rbDuplex.isSameAs(source)) {
2558
asCurrent.add(Sides.DUPLEX);
2559
}
2560
}
2561
2562
public void updateInfo() {
2563
Class sdCategory = Sides.class;
2564
boolean osSupported = false;
2565
boolean tSupported = false;
2566
boolean dSupported = false;
2567
2568
if (psCurrent.isAttributeCategorySupported(sdCategory)) {
2569
Object values =
2570
psCurrent.getSupportedAttributeValues(sdCategory,
2571
docFlavor,
2572
asCurrent);
2573
2574
if (values instanceof Sides[]) {
2575
Sides[] svalues = (Sides[])values;
2576
2577
for (int i = 0; i < svalues.length; i++) {
2578
Sides value = svalues[i];
2579
2580
if (value == Sides.ONE_SIDED) {
2581
osSupported = true;
2582
} else if (value == Sides.TUMBLE) {
2583
tSupported = true;
2584
} else if (value == Sides.DUPLEX) {
2585
dSupported = true;
2586
}
2587
}
2588
}
2589
}
2590
rbOneSide.setEnabled(osSupported);
2591
rbTumble.setEnabled(tSupported);
2592
rbDuplex.setEnabled(dSupported);
2593
2594
Sides sd = (Sides)asCurrent.get(sdCategory);
2595
if (sd == null) {
2596
sd = (Sides)psCurrent.getDefaultAttributeValue(sdCategory);
2597
if (sd == null) {
2598
sd = Sides.ONE_SIDED;
2599
}
2600
}
2601
2602
if (sd == Sides.ONE_SIDED) {
2603
rbOneSide.setSelected(true);
2604
} else if (sd == Sides.TUMBLE) {
2605
rbTumble.setSelected(true);
2606
} else { // if (sd == Sides.DUPLEX)
2607
rbDuplex.setSelected(true);
2608
}
2609
}
2610
}
2611
2612
2613
2614
private class JobAttributesPanel extends JPanel
2615
implements ActionListener, ChangeListener, FocusListener
2616
{
2617
private final String strTitle = getMsg("border.jobattributes");
2618
private JLabel lblPriority, lblJobName, lblUserName;
2619
private JSpinner spinPriority;
2620
private SpinnerNumberModel snModel;
2621
private JCheckBox cbJobSheets;
2622
private JTextField tfJobName, tfUserName;
2623
2624
public JobAttributesPanel() {
2625
super();
2626
2627
GridBagLayout gridbag = new GridBagLayout();
2628
GridBagConstraints c = new GridBagConstraints();
2629
2630
setLayout(gridbag);
2631
setBorder(BorderFactory.createTitledBorder(strTitle));
2632
2633
c.fill = GridBagConstraints.NONE;
2634
c.insets = compInsets;
2635
c.weighty = 1.0;
2636
2637
cbJobSheets = createCheckBox("checkbox.jobsheets", this);
2638
c.anchor = GridBagConstraints.LINE_START;
2639
addToGB(cbJobSheets, this, gridbag, c);
2640
2641
JPanel pnlTop = new JPanel();
2642
lblPriority = new JLabel(getMsg("label.priority"), JLabel.TRAILING);
2643
lblPriority.setDisplayedMnemonic(getMnemonic("label.priority"));
2644
2645
pnlTop.add(lblPriority);
2646
snModel = new SpinnerNumberModel(1, 1, 100, 1);
2647
spinPriority = new JSpinner(snModel);
2648
lblPriority.setLabelFor(spinPriority);
2649
// REMIND
2650
((JSpinner.NumberEditor)spinPriority.getEditor()).getTextField().setColumns(3);
2651
spinPriority.addChangeListener(this);
2652
pnlTop.add(spinPriority);
2653
c.anchor = GridBagConstraints.LINE_END;
2654
c.gridwidth = GridBagConstraints.REMAINDER;
2655
pnlTop.getAccessibleContext().setAccessibleName(
2656
getMsg("label.priority"));
2657
addToGB(pnlTop, this, gridbag, c);
2658
2659
c.fill = GridBagConstraints.HORIZONTAL;
2660
c.anchor = GridBagConstraints.CENTER;
2661
c.weightx = 0.0;
2662
c.gridwidth = 1;
2663
char jmnemonic = getMnemonic("label.jobname");
2664
lblJobName = new JLabel(getMsg("label.jobname"), JLabel.TRAILING);
2665
lblJobName.setDisplayedMnemonic(jmnemonic);
2666
addToGB(lblJobName, this, gridbag, c);
2667
c.weightx = 1.0;
2668
c.gridwidth = GridBagConstraints.REMAINDER;
2669
tfJobName = new JTextField();
2670
lblJobName.setLabelFor(tfJobName);
2671
tfJobName.addFocusListener(this);
2672
tfJobName.setFocusAccelerator(jmnemonic);
2673
tfJobName.getAccessibleContext().setAccessibleName(
2674
getMsg("label.jobname"));
2675
addToGB(tfJobName, this, gridbag, c);
2676
2677
c.weightx = 0.0;
2678
c.gridwidth = 1;
2679
char umnemonic = getMnemonic("label.username");
2680
lblUserName = new JLabel(getMsg("label.username"), JLabel.TRAILING);
2681
lblUserName.setDisplayedMnemonic(umnemonic);
2682
addToGB(lblUserName, this, gridbag, c);
2683
c.gridwidth = GridBagConstraints.REMAINDER;
2684
tfUserName = new JTextField();
2685
lblUserName.setLabelFor(tfUserName);
2686
tfUserName.addFocusListener(this);
2687
tfUserName.setFocusAccelerator(umnemonic);
2688
tfUserName.getAccessibleContext().setAccessibleName(
2689
getMsg("label.username"));
2690
addToGB(tfUserName, this, gridbag, c);
2691
}
2692
2693
public void actionPerformed(ActionEvent e) {
2694
if (cbJobSheets.isSelected()) {
2695
asCurrent.add(JobSheets.STANDARD);
2696
} else {
2697
asCurrent.add(JobSheets.NONE);
2698
}
2699
}
2700
2701
public void stateChanged(ChangeEvent e) {
2702
asCurrent.add(new JobPriority(snModel.getNumber().intValue()));
2703
}
2704
2705
public void focusLost(FocusEvent e) {
2706
Object source = e.getSource();
2707
2708
if (source == tfJobName) {
2709
asCurrent.add(new JobName(tfJobName.getText(),
2710
Locale.getDefault()));
2711
} else if (source == tfUserName) {
2712
asCurrent.add(new RequestingUserName(tfUserName.getText(),
2713
Locale.getDefault()));
2714
}
2715
}
2716
2717
public void focusGained(FocusEvent e) {}
2718
2719
public void updateInfo() {
2720
Class jsCategory = JobSheets.class;
2721
Class jpCategory = JobPriority.class;
2722
Class jnCategory = JobName.class;
2723
Class unCategory = RequestingUserName.class;
2724
boolean jsSupported = false;
2725
boolean jpSupported = false;
2726
boolean jnSupported = false;
2727
boolean unSupported = false;
2728
2729
// setup JobSheets checkbox
2730
if (psCurrent.isAttributeCategorySupported(jsCategory)) {
2731
jsSupported = true;
2732
}
2733
JobSheets js = (JobSheets)asCurrent.get(jsCategory);
2734
if (js == null) {
2735
js = (JobSheets)psCurrent.getDefaultAttributeValue(jsCategory);
2736
if (js == null) {
2737
js = JobSheets.NONE;
2738
}
2739
}
2740
cbJobSheets.setSelected(js != JobSheets.NONE);
2741
cbJobSheets.setEnabled(jsSupported);
2742
2743
// setup JobPriority spinner
2744
if (!isAWT && psCurrent.isAttributeCategorySupported(jpCategory)) {
2745
jpSupported = true;
2746
}
2747
JobPriority jp = (JobPriority)asCurrent.get(jpCategory);
2748
if (jp == null) {
2749
jp = (JobPriority)psCurrent.getDefaultAttributeValue(jpCategory);
2750
if (jp == null) {
2751
jp = new JobPriority(1);
2752
}
2753
}
2754
int value = jp.getValue();
2755
if ((value < 1) || (value > 100)) {
2756
value = 1;
2757
}
2758
snModel.setValue(new Integer(value));
2759
lblPriority.setEnabled(jpSupported);
2760
spinPriority.setEnabled(jpSupported);
2761
2762
// setup JobName text field
2763
if (psCurrent.isAttributeCategorySupported(jnCategory)) {
2764
jnSupported = true;
2765
}
2766
JobName jn = (JobName)asCurrent.get(jnCategory);
2767
if (jn == null) {
2768
jn = (JobName)psCurrent.getDefaultAttributeValue(jnCategory);
2769
if (jn == null) {
2770
jn = new JobName("", Locale.getDefault());
2771
}
2772
}
2773
tfJobName.setText(jn.getValue());
2774
tfJobName.setEnabled(jnSupported);
2775
lblJobName.setEnabled(jnSupported);
2776
2777
// setup RequestingUserName text field
2778
if (!isAWT && psCurrent.isAttributeCategorySupported(unCategory)) {
2779
unSupported = true;
2780
}
2781
RequestingUserName un = (RequestingUserName)asCurrent.get(unCategory);
2782
if (un == null) {
2783
un = (RequestingUserName)psCurrent.getDefaultAttributeValue(unCategory);
2784
if (un == null) {
2785
un = new RequestingUserName("", Locale.getDefault());
2786
}
2787
}
2788
tfUserName.setText(un.getValue());
2789
tfUserName.setEnabled(unSupported);
2790
lblUserName.setEnabled(unSupported);
2791
}
2792
}
2793
2794
2795
2796
2797
/**
2798
* A special widget that groups a JRadioButton with an associated icon,
2799
* placed to the left of the radio button.
2800
*/
2801
private class IconRadioButton extends JPanel {
2802
2803
private JRadioButton rb;
2804
private JLabel lbl;
2805
2806
public IconRadioButton(String key, String img, boolean selected,
2807
ButtonGroup bg, ActionListener al)
2808
{
2809
super(new FlowLayout(FlowLayout.LEADING));
2810
final URL imgURL = getImageResource(img);
2811
Icon icon = (Icon)java.security.AccessController.doPrivileged(
2812
new java.security.PrivilegedAction() {
2813
public Object run() {
2814
Icon icon = new ImageIcon(imgURL);
2815
return icon;
2816
}
2817
});
2818
lbl = new JLabel(icon);
2819
add(lbl);
2820
2821
rb = createRadioButton(key, al);
2822
rb.setSelected(selected);
2823
addToBG(rb, this, bg);
2824
}
2825
2826
public void addActionListener(ActionListener al) {
2827
rb.addActionListener(al);
2828
}
2829
2830
public boolean isSameAs(Object source) {
2831
return (rb == source);
2832
}
2833
2834
public void setEnabled(boolean enabled) {
2835
rb.setEnabled(enabled);
2836
lbl.setEnabled(enabled);
2837
}
2838
2839
public boolean isSelected() {
2840
return rb.isSelected();
2841
}
2842
2843
public void setSelected(boolean selected) {
2844
rb.setSelected(selected);
2845
}
2846
}
2847
2848
/**
2849
* Similar in functionality to the default JFileChooser, except this
2850
* chooser will pop up a "Do you want to overwrite..." dialog if the
2851
* user selects a file that already exists.
2852
*/
2853
private class ValidatingFileChooser extends JFileChooser {
2854
public void approveSelection() {
2855
File selected = getSelectedFile();
2856
boolean exists;
2857
2858
try {
2859
exists = selected.exists();
2860
} catch (SecurityException e) {
2861
exists = false;
2862
}
2863
2864
if (exists) {
2865
int val;
2866
val = JOptionPane.showConfirmDialog(this,
2867
getMsg("dialog.overwrite"),
2868
getMsg("dialog.owtitle"),
2869
JOptionPane.YES_NO_OPTION);
2870
if (val != JOptionPane.YES_OPTION) {
2871
return;
2872
}
2873
}
2874
2875
try {
2876
if (selected.createNewFile()) {
2877
selected.delete();
2878
}
2879
} catch (IOException ioe) {
2880
JOptionPane.showMessageDialog(this,
2881
getMsg("dialog.writeerror")+" "+selected,
2882
getMsg("dialog.owtitle"),
2883
JOptionPane.WARNING_MESSAGE);
2884
return;
2885
} catch (SecurityException se) {
2886
//There is already file read/write access so at this point
2887
// only delete access is denied. Just ignore it because in
2888
// most cases the file created in createNewFile gets
2889
// overwritten anyway.
2890
}
2891
File pFile = selected.getParentFile();
2892
if ((selected.exists() &&
2893
(!selected.isFile() || !selected.canWrite())) ||
2894
((pFile != null) &&
2895
(!pFile.exists() || (pFile.exists() && !pFile.canWrite())))) {
2896
JOptionPane.showMessageDialog(this,
2897
getMsg("dialog.writeerror")+" "+selected,
2898
getMsg("dialog.owtitle"),
2899
JOptionPane.WARNING_MESSAGE);
2900
return;
2901
}
2902
2903
super.approveSelection();
2904
}
2905
}
2906
}
2907
2908