001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.compapp.projects.wizard;
021:
022: import java.awt.Component;
023: import java.awt.Dialog;
024: import java.awt.event.ActionEvent;
025: import java.awt.event.ActionListener;
026: import java.beans.PropertyChangeEvent;
027: import java.beans.PropertyChangeListener;
028: import javax.swing.JButton;
029: import javax.swing.JComponent;
030: import javax.swing.JLabel;
031: import org.netbeans.api.progress.ProgressHandle;
032: import org.netbeans.api.progress.ProgressHandleFactory;
033: import org.openide.DialogDescriptor;
034: import org.openide.DialogDisplayer;
035: import org.openide.util.NbBundle;
036:
037: /**
038: * A Factory to create dialog components for the NetBeans environment, that
039: * display the progress of some work. It uses the NetBeans Progress and
040: * DialogDescriptor APIs for visualizing the tracking of the progress. It also
041: * supports cancellable work.
042: *
043: * @see org.netbeans.api.progress
044: * @see org.openide.util.Cancellable
045: *
046: * @author Tientien Li
047: */
048: public final class ProgressDialogFactory {
049:
050: private ProgressDialogFactory() {
051: }
052:
053: /**
054: * Creates a progress dialog.
055: *
056: * @param title Descriptive title for the dialog.
057: * @param cancelable Whether or not the progress is cancelable.
058: *
059: * @return A ProgressDescriptor object for the requested progress indicator.
060: */
061: public static ProgressDescriptor createProgressDialog(
062: final String title, final boolean cancelable) {
063:
064: // Create progress bar
065: ProgressHandle pDesc = ProgressHandleFactory
066: .createHandle(title);
067: JComponent progressBar = ProgressHandleFactory
068: .createProgressComponent(pDesc);
069: ProgressPanel panel = new ProgressPanel(progressBar);
070:
071: // Disable cancel button if this is not a cancelable task.
072: Component buttonCancel = new JButton(CANCEL_OPTION);
073: buttonCancel.setEnabled(cancelable);
074:
075: ProgressDialogCancellationListener progressListener = new ProgressDialogCancellationListener(
076: panel, buttonCancel);
077:
078: // Create dialog for progress bar
079: DialogDescriptor dDesc = new DialogDescriptor(panel,
080: makeDialogTitle(title), true,
081: new Object[] { buttonCancel }, buttonCancel,
082: DialogDescriptor.DEFAULT_ALIGN, null, progressListener,
083: false);
084: Dialog dialog = DialogDisplayer.getDefault()
085: .createDialog(dDesc);
086:
087: // Create ProgressDescriptor
088: ProgressDescriptor descriptor = new ProgressDescriptorImpl(
089: dialog, pDesc);
090:
091: if (progressListener != null) {
092: // Reference to controller, to update model state on cancelation.
093: progressListener.setController(descriptor.getController());
094:
095: // Listener interested in Controller (not GUI)-actioned
096: // cancelation and finalization; e.g., hook for interface
097: // embellishments.
098: dialog.addPropertyChangeListener(progressListener);
099: }
100:
101: dialog.pack();
102: dialog.setResizable(false);
103: return descriptor;
104: }
105:
106: private static String makeDialogTitle(String title) {
107: String titlePrefix = NbBundle.getMessage(
108: ProgressDialogFactory.class,
109: "ProgressDialogFactory.dialog_title_prefix");
110: return (titlePrefix != null ? titlePrefix : "").concat(title);
111: }
112:
113: static class ProgressDescriptorImpl implements ProgressDescriptor {
114:
115: public ProgressDescriptorImpl(Dialog dialog,
116: ProgressHandle progress) {
117:
118: if (dialog == null) {
119: throw new NullPointerException("dialog");
120: }
121:
122: if (progress == null) {
123: throw new NullPointerException("progress");
124: }
125:
126: this .dialog = dialog;
127: controller = new ProgressController(progress, dialog);
128: }
129:
130: public Component getGUIComponent() {
131: return dialog;
132: }
133:
134: public ProgressController getController() {
135: return controller;
136: }
137:
138: private final Dialog dialog;
139: private final ProgressController controller;
140: }
141:
142: static class ProgressDialogCancellationListener implements
143: ActionListener, PropertyChangeListener {
144:
145: public ProgressDialogCancellationListener(ProgressPanel panel,
146: Component component) {
147: if (component == null) {
148: throw new NullPointerException("component");
149: }
150: if (panel == null) {
151: throw new NullPointerException("panel");
152: }
153: this .component = component;
154: this .panel = panel;
155: }
156:
157: public void actionPerformed(ActionEvent e) {
158: if (e.getID() == ActionEvent.ACTION_PERFORMED) {
159: if (component.equals(e.getSource())) {
160: component.setEnabled(false);
161: controller.setCanceled();
162: panel
163: .getMessageComponent()
164: .setText(
165: NbBundle
166: .getMessage(getClass(),
167: "ProgressDialogFactory.progress_msg_canceled"));
168: }
169: }
170: }
171:
172: public void propertyChange(PropertyChangeEvent evt) {
173: String propertyName = evt.getPropertyName();
174:
175: // The task is finished (or canceled):
176: if (FINISH_OPTION.equals(propertyName)) {
177: component.setEnabled(false);
178: panel
179: .getMessageComponent()
180: .setText(
181: NbBundle
182: .getMessage(getClass(),
183: "ProgressDialogFactory.progress_msg_done"));
184: }
185:
186: else if (CANCEL_OPTION.equals(propertyName)) {
187: component.setEnabled(false);
188: panel
189: .getMessageComponent()
190: .setText(
191: NbBundle
192: .getMessage(getClass(),
193: "ProgressDialogFactory.progress_msg_canceled"));
194: }
195:
196: else if (UPDATE_OPTION.equals(propertyName)) {
197: JLabel label = panel.getMessageComponent();
198: label.setText(String.valueOf(evt.getNewValue()));
199: }
200:
201: else if (CANCEL_LOCKOUT_OPTION.equals(propertyName)) {
202: component.setEnabled(false);
203: }
204: }
205:
206: public void setController(ProgressController controller) {
207: this .controller = controller;
208: }
209:
210: private final Component component;
211: private final ProgressPanel panel;
212: private ProgressController controller;
213: }
214:
215: static final String CANCEL_OPTION = NbBundle.getMessage(
216: ProgressDialogFactory.class,
217: "ProgressDialogFactory.dialog_cancel_text");
218:
219: static final String FINISH_OPTION = "finish";
220: static final String UPDATE_OPTION = "update";
221: static final String CANCEL_LOCKOUT_OPTION = "lockout";
222: }
|