001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.openide;
042:
043: import org.openide.util.HelpCtx;
044: import org.openide.util.NbBundle;
045:
046: import java.awt.event.ActionListener;
047:
048: /** A description of a standard dialog.
049: * It may be built later using {@link DialogDisplayer#createDialog} or shown with {@link DialogDisplayer#notify}.
050: * It extends <code>NotifyDescriptor</code>'s capabilities by allowing specification of the
051: * modal/nonmodal state of the dialog, button behavior and alignment, help, and
052: * a listener on button presses.
053: * Anyone who wants to display some kind of dialog with standard
054: * behavior should use this class to describe it and
055: * use <code>createDialog(d)</code> to build it.
056: * When the dialog is closed you may use {@link #getValue} to determine which button
057: * closed it.
058: * <p>The property <code>message</code> (inherited from <code>NotifyDescriptor</code>) is primarily used here
059: * to specify the inner GUI component of the dialog, in contrast to <code>NotifyDescriptor</code>
060: * which generally uses a <code>String</code> message.
061: * <P>
062: * If you want to set one of the custom Options to be the default Option, it
063: * is possible to call <code>DialogDescriptor.setValue(<i>the button you want to
064: * have default...</i>)</code>
065: *
066: * @author Dafe Simonek
067: */
068: public class DialogDescriptor extends NotifyDescriptor implements
069: HelpCtx.Provider {
070: // Property constants
071:
072: /** Name of property for alignment of options. */
073: public static final String PROP_OPTIONS_ALIGN = "optionsAlign"; // NOI18N
074:
075: /** Name of property for modality of dialog. */
076: public static final String PROP_MODAL = "modal"; // NOI18N
077:
078: /** Name of property whether the dialg is leaf or can be the owner of other one dialog. */
079: public static final String PROP_LEAF = "leaf"; // NOI18N
080:
081: /** Name of property for the help context. */
082: public static final String PROP_HELP_CTX = "helpCtx"; // NOI18N
083:
084: /** Name of property for the button listener. */
085: public static final String PROP_BUTTON_LISTENER = "buttonListener"; // NOI18N
086:
087: /** Name of property for list of closing options. */
088: public static final String PROP_CLOSING_OPTIONS = "closingOptions"; // NOI18N
089: public static final int BOTTOM_ALIGN = 0;
090:
091: /** Alignment to place options vertically
092: * in the right part. */
093: public static final int RIGHT_ALIGN = 1;
094:
095: /** Alignment to place options in the default manner. */
096: public static final int DEFAULT_ALIGN = BOTTOM_ALIGN;
097:
098: /** default closing options */
099: private static final Object[] DEFAULT_CLOSING_OPTIONS = new Object[] {
100: YES_OPTION, NO_OPTION, CANCEL_OPTION, OK_OPTION };
101:
102: // Properties
103:
104: /** RW property specifies if the dialog can be owner of other dialogs */
105: private boolean leaf = false;
106:
107: /** RW property specifying modal status of the dialog */
108: private boolean modal;
109:
110: /** RW property specifying options alignment,
111: * possible values today are BOTTOM_ALIGN, RIGHT_ALIGN, DEFAULT_ALIGN */
112: private int optionsAlign;
113:
114: /** RW property which specifies help context for the dialog */
115: private HelpCtx helpCtx;
116:
117: /** RW property which specifies button listener for notifying
118: * clients about button presses */
119: private ActionListener buttonListener;
120:
121: /** array of options that close the dialog when pressed */
122: private Object[] closingOptions = DEFAULT_CLOSING_OPTIONS;
123:
124: /** Create modal dialog descriptor with given title and inner part,
125: * with OK/Cancel buttons with default alignment,
126: * no help available. All buttons will close the dialog and the getValue ()
127: * will provide the pressed option.
128: * @param innerPane inner component of the dialog, or String message
129: * @param title title of the dialog
130: */
131: public DialogDescriptor(final Object innerPane, final String title) {
132: this (innerPane, title, true, OK_CANCEL_OPTION, OK_OPTION,
133: DEFAULT_ALIGN, null, null);
134: }
135:
136: /** Create dialog descriptor with given title, inner part and modal status,
137: * with OK/Cancel buttons displayed with default alignment, no help available.
138: * If <code>bl</code> is not <code>null</code>, then it will receive notifications when the user
139: * presses the buttons. (If no listener is specified, it's still possible
140: * to retrieve the user-selected button using {@link NotifyDescriptor#getValue}.)
141: *
142: * @param innerPane inner component of the dialog, or String message
143: * @param title title of the dialog
144: * @param isModal modal status
145: * @param bl listener for user's button presses
146: */
147: public DialogDescriptor(final Object innerPane, final String title,
148: final boolean isModal, final ActionListener bl) {
149: this (innerPane, title, isModal, OK_CANCEL_OPTION, OK_OPTION,
150: DEFAULT_ALIGN, null, bl);
151: }
152:
153: /** Create dialog descriptor with given title, inner part, modal status,
154: * option type and default option. Options have default alignment, no help available.
155: * If the action listener is null, all option buttons will close the dialog and the
156: * getValue () will provide the pressed option.
157: * @param innerPane inner component of the dialog, or String message
158: * @param title title of the dialog
159: * @param isModal modal status
160: * @param optionType one of the standard options (<code>OK_CANCEL_OPTION</code>, ...)
161: * @param initialValue default option (default button)
162: * @param bl listener for the user's button presses or null for default close action on all options
163: */
164: public DialogDescriptor(final Object innerPane, final String title,
165: final boolean isModal, final int optionType,
166: final Object initialValue, final ActionListener bl) {
167: this (innerPane, title, isModal, optionType, initialValue,
168: DEFAULT_ALIGN, null, bl);
169: }
170:
171: /** Create dialog descriptor; possibility of specifying custom
172: * array of options and their alignment. If the action listener is null,
173: * all option buttons will close the dialog and the getValue ()
174: * will provide the pressed option.
175: * When a custom option set is provided, if any of the standard options
176: * (OK_OPTION, CLOSE_OPTION or CANCEL_OPTION) are used, the dialog will close when
177: * a button for a standard option is pressed; otherwise for custom options, closing the dialog is left
178: * to the <code>ActionListener</code> or <code>setClosingOptions</code>.
179: * @param innerPane inner component of the dialog, or String message
180: * @param title title of the dialog
181: * @param modal modal status
182: * @param options array of custom options (<code>null</code> means no options at all);
183: * may include strings (for button labels; such buttons then do nothing by default)
184: * or components (such as buttons,
185: * in which case you are responsible for listening to the buttons yourself)
186: * @param initialValue default option from custom option array
187: * @param optionsAlign specifies where to place
188: * options in the dialog
189: * @param helpCtx help context specifying help page
190: * @param bl listener for the user's button presses or <code>null</code> for default close action on all options
191: * (unless you specified the options yourself)
192: *
193: * @see #setClosingOptions
194: */
195: public DialogDescriptor(final Object innerPane, final String title,
196: final boolean modal, final Object[] options,
197: final Object initialValue, final int optionsAlign,
198: final HelpCtx helpCtx, final ActionListener bl) {
199: super (innerPane, title, DEFAULT_OPTION, PLAIN_MESSAGE, options,
200: initialValue);
201: this .modal = modal;
202: this .optionsAlign = optionsAlign;
203: this .helpCtx = (helpCtx == null) ? HelpCtx.DEFAULT_HELP
204: : helpCtx;
205: this .buttonListener = bl;
206:
207: if (bl == null) {
208: setClosingOptions(options);
209: }
210: }
211:
212: /** Create dialog descriptor; possibility of specifying custom
213: * array of options and their alignment. If the action listener is null,
214: * all option buttons will close the dialog and the getValue ()
215: * will provide the pressed option.
216: * When a custom option set is provided, if any of the standard options
217: * (OK_OPTION, CLOSE_OPTION or CANCEL_OPTION) are used, the dialog will close when
218: * a button for a standard option is pressed; otherwise for custom options, closing the dialog is left
219: * to the <code>ActionListener</code> or <code>setClosingOptions</code>.
220: * @param innerPane inner component of the dialog, or String message
221: * @param title title of the dialog
222: * @param modal modal status
223: * @param options array of custom options (<code>null</code> means no options at all);
224: * may include strings (for button labels; such buttons then do nothing by default)
225: * or components (such as buttons,
226: * in which case you are responsible for listening to the buttons yourself)
227: * @param initialValue default option from custom option array
228: * @param optionsAlign specifies where to place
229: * options in the dialog
230: * @param helpCtx help context specifying help page
231: * @param bl listener for the user's button presses or <code>null</code> for default close action on all options
232: * (unless you specified the options yourself)
233: * @param leaf property specifies whether the dialog can be owner of other dialogs
234: *
235: * @see #setClosingOptions
236: * @since 5.5
237: */
238: public DialogDescriptor(final Object innerPane, final String title,
239: final boolean modal, final Object[] options,
240: final Object initialValue, final int optionsAlign,
241: final HelpCtx helpCtx, final ActionListener bl,
242: final boolean leaf) {
243: super (innerPane, title, DEFAULT_OPTION, PLAIN_MESSAGE, options,
244: initialValue);
245: this .modal = modal;
246: this .optionsAlign = optionsAlign;
247: this .helpCtx = (helpCtx == null) ? HelpCtx.DEFAULT_HELP
248: : helpCtx;
249: this .buttonListener = bl;
250: this .leaf = leaf;
251:
252: if (bl == null) {
253: setClosingOptions(options);
254: }
255: }
256:
257: /** Create dialog descriptor.
258: * If the action listener is null, all option buttons will close the dialog and the
259: * getValue () will provide the pressed option.
260: *
261: * @param innerPane inner component of the dialog, or String message
262: * @param title title of the dialog
263: * @param isModal modal status
264: * @param optionType one of the standard options (<code>OK_CANCEL_OPTION</code>, ...)
265: * @param initialValue default option (default button)
266: * @param optionsAlign specifies where to place
267: * options in the dialog
268: * @param helpCtx help context specifying help page
269: * @param bl listener for the user's button presses or <code>null</code> for default close action on all options
270: * (unless you specified the options yourself)
271: */
272: public DialogDescriptor(final Object innerPane, final String title,
273: final boolean isModal, final int optionType,
274: final Object initialValue, final int optionsAlign,
275: final HelpCtx helpCtx, final ActionListener bl) {
276: super (innerPane, title, optionType, PLAIN_MESSAGE, null,
277: initialValue);
278: this .modal = isModal;
279: this .optionsAlign = optionsAlign;
280: this .helpCtx = (helpCtx == null) ? HelpCtx.DEFAULT_HELP
281: : helpCtx;
282: this .buttonListener = bl;
283:
284: if (bl == null) {
285: // if the listener is null all options are closing
286: setClosingOptions(null);
287: }
288: }
289:
290: /** Get current option alignment.
291: * @return current option alignment
292: * @see #setOptionsAlign
293: */
294: public int getOptionsAlign() {
295: getterCalled();
296:
297: return optionsAlign;
298: }
299:
300: /** Set new option alignment. See aligment constants for
301: * possible values.
302: * Fires property change event if successful.
303: *
304: * @param optionsAlign new options alignment
305: * @throws IllegalArgumentException when unknown alignment is given
306: * @see #DEFAULT_ALIGN
307: */
308: public void setOptionsAlign(final int optionsAlign) {
309: if ((optionsAlign != BOTTOM_ALIGN)
310: && (optionsAlign != RIGHT_ALIGN)) {
311: throw new IllegalArgumentException(NbBundle.getBundle(
312: DialogDescriptor.class).getString(
313: "EXC_OptionsAlign"));
314: }
315:
316: if (this .optionsAlign == optionsAlign) {
317: return;
318: }
319:
320: int oldValue = this .optionsAlign;
321: this .optionsAlign = optionsAlign;
322: firePropertyChange(PROP_OPTIONS_ALIGN, new Integer(oldValue),
323: new Integer(optionsAlign));
324: }
325:
326: /** Get modal status.
327: * @return modal status
328: * @see #setModal
329: */
330: public boolean isModal() {
331: getterCalled();
332:
333: return modal;
334: }
335:
336: /** Set new modal status.
337: * Fires property change event if successful.
338: *
339: * @param modal new modal status
340: * @see #isModal
341: */
342: public void setModal(final boolean modal) {
343: if (this .modal == modal) {
344: return;
345: }
346:
347: boolean oldModal = this .modal;
348: this .modal = modal;
349: firePropertyChange(PROP_MODAL, Boolean.valueOf(oldModal),
350: Boolean.valueOf(modal));
351: }
352:
353: /** Get leaf status. If is leaf then cannot be the owner to other one dialog.
354: * @return leaf status
355: * @see #setLeaf
356: * @since 5.5
357: */
358: public boolean isLeaf() {
359: getterCalled();
360:
361: return leaf;
362: }
363:
364: /** Set new leaf status.
365: * Fires property change event if successful.
366: *
367: * @param leaf new leaf status
368: * @see #isLeaf
369: * @since 5.5
370: */
371: public void setLeaf(final boolean leaf) {
372: if (this .leaf == leaf) {
373: return;
374: }
375:
376: boolean oldLeaf = this .leaf;
377: this .leaf = leaf;
378: firePropertyChange(PROP_MODAL, Boolean.valueOf(oldLeaf),
379: Boolean.valueOf(leaf));
380: }
381:
382: /** Setter for list of options that close the dialog.
383: * Special values are:
384: * <UL>
385: * <LI>null - all options will close the dialog
386: * <LI>empty array - no option will close the dialog
387: * </UL>
388: * @param arr array of options that should close the dialog when pressed
389: * if null then all options close the dialog
390: */
391: public void setClosingOptions(Object[] arr) {
392: Object[] old = closingOptions;
393: closingOptions = arr;
394:
395: firePropertyChange(PROP_CLOSING_OPTIONS, old, arr);
396: }
397:
398: /** Getter for list of closing options.
399: * @return array of options or null
400: */
401: public Object[] getClosingOptions() {
402: getterCalled();
403:
404: return closingOptions;
405: }
406:
407: /** Get current help context asociated with this dialog
408: * descriptor.
409: * @return current help context
410: * @see #setHelpCtx
411: */
412: public HelpCtx getHelpCtx() {
413: getterCalled();
414:
415: return helpCtx;
416: }
417:
418: /** Set new help context for this dialog descriptor.
419: * Fires property change event if successful.
420: * <p>The implementation should automatically display a help
421: * button among the secondary options, without your needing to
422: * specify it, if the help context on the descriptor is neither
423: * <code>null</code> nor {@link HelpCtx#DEFAULT_HELP}. If the
424: * descriptor is <code>null</code>, this feature will be disabled
425: * (you can still add your own help button manually if you wish,
426: * of course). If <code>DEFAULT_HELP</code> (the default), normally the button
427: * will also be disabled, however if the inner pane is a component
428: * and this component has an {@link HelpCtx#findHelp associated}
429: * help ID, that will be used automatically. So most users should never
430: * need to manually add a help button: call this method with the correct
431: * context, or associate an ID with the displayed component. Note that to
432: * set it to <code>null</code> you must explicitly call this method; passing
433: * <code>null</code> in the constructor actually sets it to <code>DEFAULT_HELP</code>.
434: *
435: * @param helpCtx new help context, can be <code>null</code> (no help)
436: * @see #getHelpCtx
437: */
438: public void setHelpCtx(final HelpCtx helpCtx) {
439: if ((this .helpCtx != null) && (this .helpCtx.equals(helpCtx))) {
440: return;
441: }
442:
443: HelpCtx oldHelpCtx = this .helpCtx;
444: this .helpCtx = helpCtx;
445: firePropertyChange(PROP_HELP_CTX, oldHelpCtx, helpCtx);
446: }
447:
448: /** Get button listener which listens for the user's button presses.
449: * @return current button listener instance or null
450: * @see #setButtonListener
451: */
452: public ActionListener getButtonListener() {
453: getterCalled();
454:
455: return buttonListener;
456: }
457:
458: /** Set new button listener instance for this dialog descriptor.
459: * Fires property change event if successful.
460: *
461: * @param l new button listener. It may be <code>null</code>, in which case listening is cancelled.
462: * @see #getButtonListener
463: */
464: public void setButtonListener(final ActionListener l) {
465: if (this .buttonListener == l) {
466: return;
467: }
468:
469: ActionListener oldButtonListener = this.buttonListener;
470: this.buttonListener = l;
471: firePropertyChange(PROP_BUTTON_LISTENER, oldButtonListener, l);
472: }
473: }
|