001: /*
002: * $Id: JGraphpadDialogs.java,v 1.5 2005/10/09 12:00:04 gaudenz Exp $
003: * Copyright (c) 2001-2005, Gaudenz Alder
004: *
005: * All rights reserved.
006: *
007: * See LICENSE file for license details. If you are unable to locate
008: * this file please contact info (at) jgraph (dot) com.
009: */
010: package com.jgraph.pad.dialog;
011:
012: import java.awt.Color;
013: import java.awt.Component;
014: import java.awt.Dimension;
015: import java.awt.FlowLayout;
016: import java.awt.Font;
017: import java.awt.GraphicsEnvironment;
018: import java.awt.event.ActionEvent;
019: import java.awt.event.ActionListener;
020: import java.io.File;
021: import java.security.AccessControlException;
022:
023: import javax.swing.JButton;
024: import javax.swing.JColorChooser;
025: import javax.swing.JComboBox;
026: import javax.swing.JComponent;
027: import javax.swing.JFileChooser;
028: import javax.swing.JOptionPane;
029: import javax.swing.JPanel;
030: import javax.swing.JTextField;
031: import javax.swing.filechooser.FileFilter;
032:
033: import com.jgraph.JGraphEditor;
034: import com.jgraph.JGraphpad;
035: import com.jgraph.editor.JGraphEditorResources;
036: import com.jgraph.pad.util.JGraphpadFileFilter;
037: import com.jgraph.pad.util.JGraphpadFileFilter.EditorFileFilter;
038:
039: /**
040: * Singleton class that provides a set of standard dialogs.
041: */
042: public class JGraphpadDialogs {
043:
044: /**
045: * Shared singleton instance.
046: */
047: protected static JGraphpadDialogs sharedInstance = new JGraphpadDialogs();
048:
049: /**
050: * Shared simple font dialog.
051: */
052: protected static FontDialog fontDialog = new FontDialog();
053:
054: /**
055: * Holds the various file choosers to preserve their states between uses.
056: */
057: protected JFileChooser saveEditorChooser, openEditorChooser,
058: saveImageChooser, openImageChooser;
059:
060: /**
061: * Singleton constructor.
062: */
063: protected JGraphpadDialogs() {
064: // Defines the filters for editor files
065: try {
066: FileFilter allEditorFilter = new EditorFileFilter(
067: JGraphEditorResources
068: .getString("AllJGraphpadFilesDescription"));
069: FileFilter compressedEditorFilter = new JGraphpadFileFilter(
070: ".xml.gz",
071: JGraphEditorResources
072: .getString("JGraphpadCompressedFileDescription"));
073: FileFilter uncompressedEdiorFilter = new JGraphpadFileFilter(
074: ".xml", JGraphEditorResources
075: .getString("JGraphpadFileDescription"));
076:
077: // Constructs the save editor file chooser
078: saveEditorChooser = new JFileChooser();
079: saveEditorChooser
080: .addChoosableFileFilter(compressedEditorFilter);
081: saveEditorChooser
082: .addChoosableFileFilter(uncompressedEdiorFilter);
083: saveEditorChooser.setFileFilter(compressedEditorFilter);
084:
085: // Constructs the open editor file chooser
086: openEditorChooser = new JFileChooser();
087: openEditorChooser.addChoosableFileFilter(allEditorFilter);
088: openEditorChooser
089: .addChoosableFileFilter(compressedEditorFilter);
090: openEditorChooser
091: .addChoosableFileFilter(uncompressedEdiorFilter);
092: openEditorChooser.setFileFilter(allEditorFilter);
093:
094: // Defines the filter for image files
095: FileFilter allImageFilter = new JGraphpadFileFilter.ImageFileFilter(
096: JGraphEditorResources
097: .getString("AllImagesDescription"));
098: FileFilter pngFilter = new JGraphpadFileFilter(".png",
099: "PNG " + JGraphEditorResources.getString("File")
100: + " (.png)");
101: FileFilter jpgFilter = new JGraphpadFileFilter(".jpg",
102: "JPG " + JGraphEditorResources.getString("File")
103: + " (.jpg)");
104: FileFilter gifFilter = new JGraphpadFileFilter(".gif",
105: "GIF " + JGraphEditorResources.getString("File")
106: + " (.gif)");
107: FileFilter bmpFilter = new JGraphpadFileFilter(".bmp",
108: "BMP " + JGraphEditorResources.getString("File")
109: + " (.bmp)");
110:
111: // Constructs the save image file chooser
112: saveImageChooser = new JFileChooser();
113: saveImageChooser.addChoosableFileFilter(pngFilter);
114: saveImageChooser.addChoosableFileFilter(jpgFilter);
115: saveImageChooser.addChoosableFileFilter(gifFilter);
116: saveImageChooser.addChoosableFileFilter(bmpFilter);
117: saveImageChooser.setFileFilter(pngFilter);
118:
119: // Constructs the open image file chooser
120: openImageChooser = new JFileChooser();
121: openImageChooser.addChoosableFileFilter(allImageFilter);
122: openImageChooser.addChoosableFileFilter(jpgFilter);
123: openImageChooser.addChoosableFileFilter(pngFilter);
124: openImageChooser.addChoosableFileFilter(gifFilter);
125: openImageChooser.addChoosableFileFilter(bmpFilter);
126: openImageChooser.setFileFilter(allImageFilter);
127: } catch (AccessControlException e) {
128: // ignore
129: }
130: }
131:
132: /**
133: * Returns the singleton instance.
134: *
135: * @return Returns {@link #sharedInstance}.
136: */
137: public static JGraphpadDialogs getSharedInstance() {
138: return sharedInstance;
139: }
140:
141: /**
142: * Displays a color dialog using
143: * {@link JColorChooser#showDialog(java.awt.Component, java.lang.String, java.awt.Color)}.
144: *
145: * @param component
146: * The parent component for the dialog to be displayed.
147: * @param title
148: * The title of the dialog to be displayed.
149: * @param color
150: * The default color to use in the dialog.
151: * @return Returns the selected color.
152: */
153: public Color colorDialog(Component component, String title,
154: Color color) {
155: return JColorChooser.showDialog(component, title, color);
156: }
157:
158: /**
159: * Displays a simple font dialog using {@link FontDialog}.
160: *
161: * @param component
162: * The parent component for the dialog to be displayed.
163: * @param title
164: * The title of the dialog to be displayed.
165: * @return Returns the selected font.
166: */
167: public Font fontDialog(Component component, String title) {
168: fontDialog.setVisible(true);
169: return fontDialog.getFont();
170: }
171:
172: /**
173: * Shortcut method to {@link #valueDialog(String, String)} with an empty
174: * initial value.
175: *
176: * @param title
177: * The title of the dialog to be displayed.
178: * @return Returns the user input.
179: */
180: public String valueDialog(String title) {
181: return valueDialog(title, "");
182: }
183:
184: /**
185: * Displays a value dialog using
186: * {@link JOptionPane#showInputDialog(java.awt.Component, java.lang.Object)}.
187: *
188: * @param title
189: * The title of the dialog to be displayed.
190: * @param initialValue
191: * The intitial value to be displayed.
192: * @return Returns the user input.
193: */
194: public String valueDialog(String title, String initialValue) {
195: return JOptionPane.showInputDialog(title, initialValue);
196: }
197:
198: /**
199: * Shortcut method to {@link #valueDialog(String, String)} that returns the
200: * user input as an int.
201: *
202: * @param title
203: * The title of the dialog to be displayed.
204: * @param initialValue
205: * The initial value to be displayed.
206: * @param allowNegative
207: * Specifies whether negative values are allowed as input.
208: * @param allowZero
209: * Specifies whether zero is a valid input.
210: * @return Returns the user input as an int.
211: * @throws IllegalArgumentException
212: * If a value <= 0 is entered.
213: * @throws CancelException
214: * if the user clicks cancel
215: */
216: public int intDialog(String title, int initialValue,
217: boolean allowNegative, boolean allowZero) {
218: String value = valueDialog(title, String.valueOf(initialValue));
219: if (value != null && value.length() > 0) {
220: int tmp = Integer.parseInt(value);
221: if ((!allowNegative && tmp < 0) || (!allowZero && tmp == 0))
222: throw new IllegalArgumentException(
223: JGraphEditorResources.getString("InvalidValue"));
224: initialValue = tmp;
225: } else if (value == null)
226: throw new CancelException();
227: return initialValue;
228: }
229:
230: /**
231: * Shortcut method to {@link #valueDialog(String, String)} that returns the
232: * user input as a float.
233: *
234: * @param title
235: * The title of the dialog to be displayed.
236: * @param initialValue
237: * The initial value to be displayed.
238: * @param allowNegative
239: * Specifies whether negative values are allowed as input.
240: * @param allowZero
241: * Specifies whether zero is a valid input.
242: * @return Returns the user input as a double.
243: * @throws IllegalArgumentException
244: * If a value <= 0 is entered.
245: * @throws CancelException
246: * if the user clicks cancel
247: */
248: public float floatDialog(String title, float initialValue,
249: boolean allowNegative, boolean allowZero) {
250: String value = valueDialog(title, String.valueOf(initialValue));
251: if (value != null && value.length() > 0) {
252: float tmp = Float.parseFloat(value);
253: if ((!allowNegative && tmp < 0) || (!allowZero && tmp == 0))
254: throw new IllegalArgumentException(
255: JGraphEditorResources.getString("InvalidValue"));
256: initialValue = tmp;
257: } else if (value == null)
258: throw new CancelException();
259: return initialValue;
260: }
261:
262: /**
263: * Shortcut method to {@link #valueDialog(String, String)} that returns the
264: * user input as a double.
265: *
266: * @param title
267: * The title of the dialog to be displayed.
268: * @param initialValue
269: * The initial value to be displayed.
270: * @return Returns the user input as a double.
271: * @throws IllegalArgumentException
272: * If a value <= 0 is entered.
273: * @throws CancelException
274: * if the user clicks cancel
275: */
276: public double doubleDialog(String title, double initialValue,
277: boolean allowNegative, boolean allowZero) {
278: String value = valueDialog(title, String.valueOf(initialValue));
279: if (value != null && value.length() > 0) {
280: double tmp = Double.parseDouble(value);
281: if ((!allowNegative && tmp < 0) || (!allowZero && tmp == 0))
282: throw new IllegalArgumentException(
283: JGraphEditorResources.getString("InvalidValue"));
284: initialValue = tmp;
285: } else if (value == null)
286: throw new CancelException();
287: return initialValue;
288: }
289:
290: /**
291: * Displays a confirmation dialog using
292: * {@link JOptionPane#showConfirmDialog(java.awt.Component, java.lang.Object, java.lang.String, int)}
293: * and {@link JGraphpad#APPTITLE} for the title.
294: *
295: * @param component
296: * The parent component for the dialog to be displayed.
297: * @param message
298: * The message to be confirmed.
299: * @param yesNo
300: * Whether to display yes/no or ok/cancel options.
301: * @param cancel
302: * Whether to display a cancel option for yes/no dialogs.
303: * @return Returns true if the message is confirmed.
304: * @throws CancelException
305: * If the user clicks cancel.
306: */
307: public boolean confirmDialog(Component component, String message,
308: boolean yesNo, boolean cancel) throws CancelException {
309: int optionType = (yesNo) ? (cancel) ? JOptionPane.YES_NO_CANCEL_OPTION
310: : JOptionPane.YES_NO_OPTION
311: : JOptionPane.OK_CANCEL_OPTION;
312: int confirm = (yesNo) ? JOptionPane.YES_OPTION
313: : JOptionPane.OK_OPTION;
314: int result = JOptionPane.showConfirmDialog(component, message,
315: JGraphpad.APPTITLE, optionType);
316: if (result == JOptionPane.CANCEL_OPTION)
317: throw new CancelException();
318: return result == confirm;
319: }
320:
321: /**
322: * Shortcut method to {@link #messageDialog(Component, String, int)} that
323: * display a dialog of type {@link JOptionPane#INFORMATION_MESSAGE}.
324: *
325: * @param component
326: * The parent component for the dialog to be displayed.
327: * @param message
328: * The message to be displayed.
329: */
330: public void informationDialog(Component component, String message) {
331: messageDialog(component, message,
332: JOptionPane.INFORMATION_MESSAGE);
333: }
334:
335: /**
336: * Shortcut method to {@link #messageDialog(Component, String, int)} that
337: * display a dialog of type {@link JOptionPane#ERROR_MESSAGE}.
338: *
339: * @param component
340: * The parent component for the dialog to be displayed.
341: * @param message
342: * The message to be displayed.
343: */
344: public void errorDialog(Component component, String message) {
345: messageDialog(component, message, JOptionPane.ERROR_MESSAGE);
346: }
347:
348: /**
349: * Displays a message dialog using
350: * {@link JOptionPane#showMessageDialog(java.awt.Component, java.lang.Object, java.lang.String, int)}
351: * and {@link JGraphpad#APPTITLE} for the title.
352: *
353: * @param component
354: * The parent component for the dialog to be displayed.
355: * @param message
356: * The message to be confirmed.
357: * @param type
358: * The type of message dialog to be displayed.
359: */
360: public void messageDialog(Component component, String message,
361: int type) {
362: JOptionPane.showMessageDialog(component, message,
363: JGraphpad.APPTITLE, type);
364: }
365:
366: /**
367: * Displays a {@link JFileChooser} using
368: * {@link #showFileChooser(Component, JFileChooser, boolean)} for files with
369: * the specified extension. The dialog will show <code>description</code>
370: * for file of this type. The full extension including the dot must be
371: * specified. If the selected filename does not end with
372: * <code>extension</code> then the extension is appended to the filename.
373: *
374: * @param component
375: * The parent component for the dialog to be displayed.
376: * @param title
377: * The title of the dialog to be displayed.
378: * @param open
379: * Whether to display an open or save dialog.
380: * @param extension
381: * The extension to be used for filtering files.
382: * @param desc
383: * The description of the file format.
384: * @param directory
385: * The default directory to use for the dialog.
386: * @return Returns the selected filename.
387: */
388: public String fileDialog(Component component, String title,
389: boolean open, String extension, String desc, File directory) {
390: JFileChooser fc = new JFileChooser(directory);
391: fc.setDialogTitle(title);
392: if (extension != null)
393: fc.setFileFilter(new JGraphpadFileFilter(extension
394: .toLowerCase(), desc));
395: return showFileChooser(component, fc, open);
396: }
397:
398: /**
399: * Displays a {@link JFileChooser} using
400: * {@link #showFileChooser(Component, JFileChooser, boolean)}. This
401: * implementation adds two file filters to the chooser, one for .xml files
402: * and the other for .xml.gz files.
403: *
404: * @param component
405: * The parent component for the dialog to be displayed.
406: * @param title
407: * The title of the dialog to be displayed.
408: * @param open
409: * Whether to display an open or save dialog.
410: * @param directory
411: * The default directory to use for the dialog.
412: * @return Returns the selected filename.
413: */
414: public String editorFileDialog(Component component, String title,
415: String filename, boolean open, File directory) {
416: JFileChooser chooser = (open) ? openEditorChooser
417: : saveEditorChooser;
418: if (chooser != null) {
419: chooser.setDialogTitle(title);
420: // Uses the passed-in directory or filename to set current dir
421: if (filename != null && !JGraphEditor.isURL(filename)) {
422: File file = new File(filename);
423: directory = file.getParentFile();
424: chooser.setSelectedFile(file);
425: }
426: chooser.setCurrentDirectory(directory);
427: return showFileChooser(component, chooser, open);
428: }
429: return null;
430: }
431:
432: /**
433: * Displays a {@link JFileChooser} using
434: * {@link #showFileChooser(Component, JFileChooser, boolean)}. This
435: * implementation adds two file filters to the chooser, one for .jpg files
436: * and the other for .png files.
437: *
438: * @param component
439: * The parent component for the dialog to be displayed.
440: * @param title
441: * The title of the dialog to be displayed.
442: * @param open
443: * Whether to display an open or save dialog.
444: * @param directory
445: * The default directory to use for the dialog.
446: * @return Returns the selected filename.
447: */
448: public String imageFileDialog(Component component, String title,
449: boolean open, File directory) {
450: JFileChooser chooser = (open) ? openImageChooser
451: : saveImageChooser;
452: if (chooser != null) {
453: chooser.setDialogTitle(title);
454: if (directory != null)
455: chooser.setCurrentDirectory(directory);
456: return showFileChooser(component, chooser, open);
457: }
458: return null;
459: }
460:
461: /**
462: * Helper method to display the specified chooser using
463: * {@link JFileChooser#showOpenDialog(java.awt.Component)} or
464: * {@link JFileChooser#showSaveDialog(java.awt.Component)} making sure that
465: * the returned file has the extension of the selected filter. This
466: * implementation displays a confirmation dialog if a file will be
467: * overwritten and returns null if the user chooses not to overwrite it.
468: *
469: * @param component
470: * The parent component for the dialog to be displayed.
471: * @param chooser
472: * The dialog to be displayed. Whether to display an open or save
473: * dialog.
474: * @param open
475: * Whether to display an open or save dialog.
476: * @return Returns the selected filename.
477: */
478: protected String showFileChooser(Component component,
479: JFileChooser chooser, boolean open) {
480: int returnValue = JFileChooser.CANCEL_OPTION;
481: if (open)
482: returnValue = chooser.showOpenDialog(component);
483: else
484: returnValue = chooser.showSaveDialog(component);
485: if (returnValue == JFileChooser.APPROVE_OPTION
486: && chooser.getSelectedFile() != null) {
487: String filename = chooser.getSelectedFile()
488: .getAbsolutePath();
489: FileFilter tmp = chooser.getFileFilter();
490: if (tmp instanceof JGraphpadFileFilter) {
491: JGraphpadFileFilter filter = (JGraphpadFileFilter) tmp;
492: String ext = filter.getExtension().toLowerCase();
493: if (!open && !filename.toLowerCase().endsWith(ext))
494: filename += ext;
495: }
496: if (open
497: || !new File(filename).exists()
498: || confirmDialog(component, JGraphEditorResources
499: .getString("OverwriteExistingFile"), true,
500: false))
501: return filename;
502: }
503: return null;
504: }
505:
506: public static class CancelException extends RuntimeException {
507: }
508:
509: /**
510: * A simple font dialog.
511: */
512: public static class FontDialog extends JGraphpadDialog {
513:
514: /**
515: * Holds the selection font.
516: */
517: protected Font font;
518:
519: /**
520: * Constructs a new font panel.
521: */
522: public FontDialog() {
523: super (JGraphEditorResources.getString("SelectFont"));
524: setModal(true);
525: pack();
526: JGraphpad.center(this );
527: }
528:
529: /**
530: * Creates the content panel.
531: */
532: protected JComponent createContent() {
533: JPanel panel = new JPanel(new FlowLayout());
534: GraphicsEnvironment gEnv = GraphicsEnvironment
535: .getLocalGraphicsEnvironment();
536: String[] fontNames = gEnv.getAvailableFontFamilyNames();
537:
538: final JTextField sizeField = new JTextField("12");
539: Dimension dim = sizeField.getPreferredSize();
540: dim.width = 30;
541: sizeField.setMinimumSize(dim);
542: sizeField.setPreferredSize(dim);
543: final JComboBox combo = new JComboBox(fontNames);
544:
545: final ActionListener listener = new ActionListener() {
546:
547: /**
548: * Updates the font field on selection.
549: */
550: public void actionPerformed(ActionEvent e) {
551: if (sizeField.getText().length() > 0) {
552: try {
553: setFont(new Font(String.valueOf(combo
554: .getSelectedItem()), 0, Integer
555: .parseInt(sizeField.getText())));
556: } catch (Exception ex) {
557: sizeField.setText("");
558: }
559: }
560: }
561: };
562:
563: // Keeps font variable up-to-date
564: combo.addActionListener(listener);
565: sizeField.addActionListener(listener);
566:
567: // Adds components to panel
568: panel.add(combo);
569: panel.add(sizeField);
570:
571: // Adds OK button to close window
572: JButton okButton = new JButton(JGraphEditorResources
573: .getString("OK"));
574: getRootPane().setDefaultButton(okButton);
575:
576: addButtons(new JButton[] { okButton });
577: okButton.addActionListener(new ActionListener() {
578: public void actionPerformed(ActionEvent e) {
579: listener.actionPerformed(e);
580: setVisible(false);
581: }
582: });
583:
584: return panel;
585: }
586:
587: /**
588: * @return Returns the font.
589: */
590: public Font getFont() {
591: return font;
592: }
593:
594: /**
595: * @param font
596: * The font to set.
597: */
598: public void setFont(Font font) {
599: this.font = font;
600: }
601:
602: }
603:
604: }
|