2 * PrintServiceDialog.java
\r
5 package net.sf.openrocket.gui.print;
\r
7 import net.miginfocom.swing.MigLayout;
\r
9 import javax.print.DocFlavor;
\r
10 import javax.print.PrintService;
\r
11 import javax.print.ServiceUIFactory;
\r
12 import javax.print.attribute.HashPrintRequestAttributeSet;
\r
13 import javax.print.attribute.PrintRequestAttribute;
\r
14 import javax.print.attribute.PrintRequestAttributeSet;
\r
15 import javax.print.attribute.standard.Destination;
\r
16 import javax.print.attribute.standard.Media;
\r
17 import javax.print.attribute.standard.MediaSizeName;
\r
18 import javax.print.attribute.standard.MediaTray;
\r
19 import javax.swing.AbstractAction;
\r
20 import javax.swing.ActionMap;
\r
21 import javax.swing.BorderFactory;
\r
22 import javax.swing.InputMap;
\r
23 import javax.swing.JButton;
\r
24 import javax.swing.JComboBox;
\r
25 import javax.swing.JDialog;
\r
26 import javax.swing.JLabel;
\r
27 import javax.swing.JPanel;
\r
28 import javax.swing.JTabbedPane;
\r
29 import javax.swing.KeyStroke;
\r
30 import javax.swing.border.EmptyBorder;
\r
31 import javax.swing.event.PopupMenuEvent;
\r
32 import javax.swing.event.PopupMenuListener;
\r
33 import java.awt.Container;
\r
34 import java.awt.Dialog;
\r
35 import java.awt.event.ActionEvent;
\r
36 import java.awt.event.ActionListener;
\r
37 import java.awt.event.ItemEvent;
\r
38 import java.awt.event.ItemListener;
\r
39 import java.awt.event.WindowAdapter;
\r
40 import java.awt.event.WindowEvent;
\r
41 import java.util.ArrayList;
\r
42 import java.util.Iterator;
\r
43 import java.util.Set;
\r
44 import java.util.TreeSet;
\r
46 public class PrintServiceDialog extends JDialog implements ActionListener {
\r
48 public static final int APPROVE = 1;
\r
49 private JButton btnCancel, btnPrint;
\r
50 private boolean pdfFlavorSupported = true;
\r
51 private PrintService services[];
\r
52 private int defaultServiceIndex = -1;
\r
54 private PrintRequestAttributeSet asOriginal;
\r
55 private HashPrintRequestAttributeSet asCurrent;
\r
56 private PrintService psCurrent;
\r
57 private DocFlavor docFlavor;
\r
58 private GeneralPanel pnlGeneral;
\r
59 private static final String GENERAL_TAB_TITLE = "General";
\r
60 private static final String PRINT_BUTTON_LABEL = "Print";
\r
61 private static final String CANCEL_BUTTON_LABEL = "Cancel";
\r
63 private class MediaPanel extends JPanel
\r
64 implements ItemListener {
\r
66 private static final String strTitle = "Media";
\r
67 private static final String SOURCE = "Source:";
\r
68 private static final String SIZE = "Size:";
\r
70 private JLabel lblSize, lblSource;
\r
71 private JComboBox cbSize, cbSource;
\r
72 private ArrayList<MediaSizeName> sizes;
\r
73 private ArrayList sources;
\r
75 private String getMediaName(String s) {
\r
76 String s1 = s.replace(' ', '-');
\r
77 s1 = s1.replace('#', 'n');
\r
78 return PaperSize.toDisplayable(s1);
\r
81 public void itemStateChanged(ItemEvent itemevent) {
\r
82 Object obj = itemevent.getSource();
\r
83 if (itemevent.getStateChange() == ItemEvent.SELECTED) {
\r
84 if (obj == cbSize) {
\r
85 int i = cbSize.getSelectedIndex();
\r
86 if (i >= 0 && i < sizes.size()) {
\r
87 if (cbSource.getItemCount() > 1 && cbSource.getSelectedIndex() >= 1) {
\r
88 int k = cbSource.getSelectedIndex() - 1;
\r
89 MediaTray mediatray = (MediaTray) sources.get(k);
\r
90 asCurrent.add(new MediaWrapper(mediatray));
\r
92 asCurrent.add(sizes.get(i));
\r
95 else if (obj == cbSource) {
\r
96 int j = cbSource.getSelectedIndex();
\r
97 if (j >= 1 && j < sources.size() + 1) {
\r
98 asCurrent.remove(MediaWrapper.class);
\r
99 asCurrent.add((MediaTray) sources.get(j - 1));
\r
102 asCurrent.remove(MediaWrapper.class);
\r
103 if (cbSize.getItemCount() > 0) {
\r
104 int l = cbSize.getSelectedIndex();
\r
105 asCurrent.add(sizes.get(l));
\r
113 public void updateInfo() {
\r
114 boolean flag = false;
\r
115 cbSize.removeItemListener(this);
\r
116 cbSize.removeAllItems();
\r
117 cbSource.removeItemListener(this);
\r
118 cbSource.removeAllItems();
\r
119 cbSource.addItem(getMediaName("auto-select"));
\r
122 if (psCurrent != null && psCurrent.isAttributeCategorySupported(Media.class)) {
\r
126 obj = psCurrent.getSupportedAttributeValues(Media.class, docFlavor, asCurrent);
\r
128 catch (IllegalArgumentException iae) {
\r
129 pdfFlavorSupported = false;
\r
132 if (obj instanceof Media[]) {
\r
133 Media amedia[] = (Media[]) obj;
\r
134 Set<SortableMediaSizeName> sizeSet = new TreeSet<SortableMediaSizeName>();
\r
136 for (int i = 0; i < amedia.length; i++) {
\r
137 Media media = amedia[i];
\r
138 if (media instanceof MediaSizeName) {
\r
139 sizeSet.add(new SortableMediaSizeName((MediaSizeName) media));
\r
141 else if (media instanceof MediaTray) {
\r
142 sources.add(media);
\r
143 cbSource.addItem(getMediaName(media.toString()));
\r
147 //The set eliminates duplicates.
\r
148 for (Iterator<SortableMediaSizeName> mediaSizeNameIterator = sizeSet.iterator(); mediaSizeNameIterator
\r
150 SortableMediaSizeName media = mediaSizeNameIterator.next();
\r
152 sizes.add(media.getMediaSizeName());
\r
153 cbSize.addItem(media.toString());
\r
158 boolean flag1 = flag && sizes.size() > 0;
\r
159 lblSize.setEnabled(flag1);
\r
160 cbSize.setEnabled(flag1);
\r
161 cbSource.setEnabled(false);
\r
162 lblSource.setEnabled(false);
\r
163 if (flag && psCurrent != null) {
\r
164 Media media = (Media) asCurrent.get(Media.class);
\r
165 boolean attributeValueSupported = false;
\r
167 attributeValueSupported = media == null ? false : psCurrent.isAttributeValueSupported(media,
\r
171 catch (IllegalArgumentException iae) {
\r
172 pdfFlavorSupported = false;
\r
174 if (media == null || !attributeValueSupported) {
\r
175 media = (Media) psCurrent.getDefaultAttributeValue(Media.class);
\r
176 if (media == null && sizes.size() > 0) {
\r
177 media = sizes.get(0);
\r
179 if (media != null) {
\r
180 asCurrent.add(media);
\r
183 if (media != null) {
\r
184 if (media instanceof MediaSizeName) {
\r
185 MediaSizeName mediasizename = (MediaSizeName) media;
\r
186 cbSize.setSelectedIndex(sizes.indexOf(mediasizename));
\r
188 else if (media instanceof MediaTray) {
\r
189 MediaTray mediatray = (MediaTray) media;
\r
190 cbSource.setSelectedIndex(sources.indexOf(mediatray) + 1);
\r
194 cbSize.setSelectedIndex(sizes.size() <= 0 ? -1 : 0);
\r
195 cbSource.setSelectedIndex(0);
\r
197 int j = cbSize.getSelectedIndex();
\r
198 if (j >= 0 && j < sizes.size()) {
\r
199 asCurrent.add(sizes.get(j));
\r
201 j = cbSource.getSelectedIndex();
\r
202 if (j >= 1 && j < sources.size() + 1) {
\r
203 asCurrent.add((MediaTray) sources.get(j - 1));
\r
206 cbSize.addItemListener(this);
\r
207 cbSource.addItemListener(this);
\r
210 public MediaPanel() {
\r
211 super(new MigLayout("fill, gap rel unrel"));
\r
212 sizes = new ArrayList<MediaSizeName>();
\r
213 sources = new ArrayList();
\r
214 setBorder(BorderFactory.createTitledBorder(strTitle));
\r
215 cbSize = new JComboBox();
\r
216 cbSource = new JComboBox();
\r
217 lblSize = new JLabel(SIZE, 11);
\r
218 lblSize.setDisplayedMnemonic(PrintServiceDialog.getMnemonic(SIZE));
\r
219 lblSize.setLabelFor(cbSize);
\r
221 add(cbSize, "wrap");
\r
222 lblSource = new JLabel(SOURCE, 11);
\r
223 lblSource.setDisplayedMnemonic(PrintServiceDialog.getMnemonic(SOURCE));
\r
224 lblSource.setLabelFor(cbSource);
\r
229 class SortableMediaSizeName implements Comparable {
\r
230 MediaSizeName delegate;
\r
232 String displayableName;
\r
234 SortableMediaSizeName(MediaSizeName msn) {
\r
236 displayableName = getMediaName(delegate.toString());
\r
237 if (displayableName == null) {
\r
238 displayableName = delegate.toString();
\r
243 * Returns a string value corresponding to this enumeration value.
\r
246 public String toString() {
\r
247 return displayableName;
\r
251 public int compareTo(final Object o) {
\r
252 String name = displayableName;
\r
253 if (name != null) {
\r
254 return name.compareTo(o.toString());
\r
260 public boolean equals(final Object o) {
\r
264 if (o == null || getClass() != o.getClass()) {
\r
268 final SortableMediaSizeName that = (SortableMediaSizeName) o;
\r
270 return displayableName.equals(that.displayableName);
\r
274 public int hashCode() {
\r
275 return displayableName.hashCode();
\r
278 MediaSizeName getMediaSizeName() {
\r
284 private class PrintServicePanel extends JPanel
\r
285 implements ActionListener, ItemListener, PopupMenuListener {
\r
287 private final String strTitle = "Print Service";
\r
288 private JButton btnProperties;
\r
289 private JComboBox cbName;
\r
290 private ServiceUIFactory uiFactory;
\r
291 private boolean changedService;
\r
293 public PrintServicePanel() {
\r
294 super(new MigLayout("fill, gap rel unrel"));
\r
295 changedService = false;
\r
296 if (psCurrent != null) {
\r
297 uiFactory = psCurrent.getServiceUIFactory();
\r
299 setBorder(BorderFactory.createTitledBorder(strTitle));
\r
300 String as[] = new String[services.length];
\r
301 for (int i = 0; i < as.length; i++) {
\r
302 as[i] = services[i].getName();
\r
305 cbName = new JComboBox(as);
\r
306 if (defaultServiceIndex != -1 && defaultServiceIndex < services.length) {
\r
307 cbName.setSelectedIndex(defaultServiceIndex);
\r
309 cbName.addItemListener(this);
\r
310 cbName.addPopupMenuListener(this);
\r
311 JLabel jlabel = new JLabel(("Name:"), 11);
\r
312 jlabel.setDisplayedMnemonic(PrintServiceDialog.getMnemonic("Name"));
\r
313 jlabel.setLabelFor(cbName);
\r
316 btnProperties = PrintServiceDialog.createButton("Properties...", this);
\r
317 add(btnProperties, "wrap");
\r
320 public void actionPerformed(ActionEvent actionevent) {
\r
321 Object obj = actionevent.getSource();
\r
322 if (obj == btnProperties && uiFactory != null) {
\r
323 JDialog jdialog = (JDialog) uiFactory.getUI(ServiceUIFactory.MAIN_UIROLE, "javax.swing.JDialog");
\r
324 if (jdialog != null) {
\r
328 btnProperties.setEnabled(false);
\r
336 * @param itemevent the event that indicates what changed
\r
339 public void itemStateChanged(ItemEvent itemevent) {
\r
340 if (itemevent.getStateChange() == ItemEvent.SELECTED) {
\r
341 int i = cbName.getSelectedIndex();
\r
342 if (services != null && i >= 0 && i < services.length && !services[i].equals(psCurrent)) {
\r
343 psCurrent = services[i];
\r
344 uiFactory = psCurrent.getServiceUIFactory();
\r
345 changedService = true;
\r
346 if (asOriginal != null) {
\r
347 Destination destination = (Destination) asOriginal.get(
\r
348 Destination.class);
\r
349 if ((destination != null) && psCurrent.isAttributeCategorySupported(
\r
350 Destination.class)) {
\r
351 asCurrent.add(destination);
\r
354 asCurrent.remove(Destination.class);
\r
364 * @param popupmenuevent
\r
367 public void popupMenuWillBecomeVisible(PopupMenuEvent popupmenuevent) {
\r
368 changedService = false;
\r
374 * @param popupmenuevent
\r
377 public void popupMenuWillBecomeInvisible(PopupMenuEvent popupmenuevent) {
\r
378 if (changedService) {
\r
379 changedService = false;
\r
387 * @param popupmenuevent
\r
390 public void popupMenuCanceled(PopupMenuEvent popupmenuevent) {
\r
394 * Modify the enablement of the properties button.
\r
396 public void updateInfo() {
\r
397 btnProperties.setEnabled(uiFactory != null);
\r
403 * The panel for general print services info.
\r
405 private class GeneralPanel extends JPanel {
\r
407 private PrintServicePanel pnlPrintService;
\r
408 private MediaPanel pnlMedia;
\r
410 public GeneralPanel() {
\r
411 super(new MigLayout("fill, gap rel unrel"));
\r
412 pnlPrintService = new PrintServicePanel();
\r
413 add(pnlPrintService, "wrap");
\r
414 pnlMedia = new MediaPanel();
\r
415 add(pnlMedia, "wrap");
\r
418 public void updateInfo() {
\r
419 pnlPrintService.updateInfo();
\r
420 pnlMedia.updateInfo();
\r
427 * @param x the <i>x</i>-coordinate of the new location's
\r
428 * top-left corner in the parent's coordinate space
\r
429 * @param y the <i>y</i>-coordinate of the new location's
\r
430 * top-left corner in the parent's coordinate space
\r
431 * @param aPrintService the array of installed print services
\r
432 * @param defaultServiceIndex the default service index (index into aPrintService)
\r
433 * @param docflavor the document flavor (i.e. PDF)
\r
434 * @param attributeSet the set of required attributes
\r
435 * @param dialog the parent
\r
436 * @param additional other panels to add in tabs
\r
438 public PrintServiceDialog(int x, int y, PrintService[] aPrintService,
\r
439 int defaultServiceIndex, DocFlavor docflavor, PrintRequestAttributeSet attributeSet,
\r
440 Dialog dialog, JPanel... additional) {
\r
441 super(dialog, PRINT_BUTTON_LABEL, true);
\r
442 setLayout(new MigLayout("fill, gap rel unrel"));
\r
443 services = aPrintService;
\r
444 this.defaultServiceIndex = defaultServiceIndex;
\r
445 asOriginal = attributeSet;
\r
446 asCurrent = new HashPrintRequestAttributeSet(attributeSet);
\r
448 if (services != null && defaultServiceIndex < services.length && defaultServiceIndex >= 0) {
\r
449 psCurrent = services[defaultServiceIndex];
\r
451 docFlavor = docflavor;
\r
452 Container container = getContentPane();
\r
453 container.setLayout(new MigLayout("fill, gap rel unrel"));
\r
454 // container.setLayout(new BorderLayout());
\r
455 final JTabbedPane tpTabs = new JTabbedPane();
\r
456 tpTabs.setBorder(new EmptyBorder(5, 5, 5, 5));
\r
458 if (additional != null) {
\r
459 for (JPanel anAdditional : additional) {
\r
460 tpTabs.add(anAdditional, anAdditional.getName(), 0);
\r
463 if (psCurrent != null) {
\r
464 pnlGeneral = new GeneralPanel();
\r
465 tpTabs.add(GENERAL_TAB_TITLE, pnlGeneral);
\r
468 container.add(tpTabs, "growx");
\r
471 JPanel jpanel = new JPanel(new MigLayout());
\r
472 btnPrint = createExitButton(PRINT_BUTTON_LABEL, this);
\r
473 jpanel.add(btnPrint, "x 300");
\r
474 getRootPane().setDefaultButton(btnPrint);
\r
475 btnPrint.setEnabled(pdfFlavorSupported && psCurrent != null);
\r
477 btnCancel = createExitButton(CANCEL_BUTTON_LABEL, this);
\r
478 handleEscKey(btnCancel);
\r
479 jpanel.add(btnCancel, "x 380");
\r
480 container.add(jpanel, "South");
\r
481 addWindowListener(new WindowAdapter() {
\r
482 public void windowClosing(WindowEvent windowevent) {
\r
487 setResizable(false);
\r
492 private void handleEscKey(JButton jbutton) {
\r
493 AbstractAction abstractaction = new AbstractAction() {
\r
495 public void actionPerformed(ActionEvent actionevent) {
\r
500 KeyStroke keystroke = KeyStroke.getKeyStroke('\033', false);
\r
501 InputMap inputmap = jbutton.getInputMap(2);
\r
502 ActionMap actionmap = jbutton.getActionMap();
\r
503 if (inputmap != null && actionmap != null) {
\r
504 inputmap.put(keystroke, "cancel");
\r
505 actionmap.put("cancel", abstractaction);
\r
509 public int getStatus() {
\r
513 public PrintRequestAttributeSet getAttributes() {
\r
522 public PrintService getPrintService() {
\r
531 public void dispose(int i) {
\r
536 public void actionPerformed(ActionEvent actionevent) {
\r
537 Object obj = actionevent.getSource();
\r
538 boolean flag = false;
\r
539 if (obj == btnPrint) {
\r
541 if (pnlGeneral != null) {
\r
542 asCurrent.remove(Destination.class);
\r
545 dispose(flag ? 1 : 2);
\r
549 private void updatePanels() {
\r
550 if (pnlGeneral != null) {
\r
551 pnlGeneral.updateInfo();
\r
555 private static char getMnemonic(String s) {
\r
556 if (s != null && s.length() > 0) {
\r
557 return s.charAt(0);
\r
564 private static JButton createButton(String s, ActionListener actionlistener) {
\r
565 JButton jbutton = new JButton(s);
\r
566 jbutton.setMnemonic(getMnemonic(s));
\r
567 jbutton.addActionListener(actionlistener);
\r
571 private static JButton createExitButton(String s, ActionListener actionlistener) {
\r
572 JButton jbutton = new JButton(s);
\r
573 jbutton.addActionListener(actionlistener);
\r
574 jbutton.getAccessibleContext().setAccessibleDescription(s);
\r
578 static class MediaWrapper
\r
579 implements PrintRequestAttribute {
\r
581 private Media media;
\r
583 MediaWrapper(Media theMedia) {
\r
591 public final Class getCategory() {
\r
592 return this.getClass();
\r
595 public final String getName() {
\r
599 public String toString() {
\r
600 return media.toString();
\r
603 public int hashCode() {
\r
604 return media.hashCode();
\r