Source Code Cross Referenced for WizardDescriptor.java in  » IDE-Netbeans » openide » org » openide » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » openide » org.openide 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.openide;
0043:
0044:        import java.awt.BorderLayout;
0045:        import java.awt.Color;
0046:        import java.awt.Component;
0047:        import java.awt.Container;
0048:        import java.awt.Cursor;
0049:        import java.awt.Dimension;
0050:        import java.awt.FocusTraversalPolicy;
0051:        import java.awt.Font;
0052:        import java.awt.Graphics;
0053:        import java.awt.Image;
0054:        import java.awt.Insets;
0055:        import java.awt.KeyboardFocusManager;
0056:        import java.awt.MediaTracker;
0057:        import java.awt.Rectangle;
0058:        import java.awt.Window;
0059:        import java.awt.event.ActionEvent;
0060:        import java.awt.event.ActionListener;
0061:        import java.awt.event.KeyEvent;
0062:        import java.awt.event.WindowEvent;
0063:        import java.awt.event.WindowListener;
0064:        import java.beans.PropertyChangeEvent;
0065:        import java.beans.PropertyChangeListener;
0066:        import java.io.IOException;
0067:        import java.net.URL;
0068:        import java.text.MessageFormat;
0069:        import java.util.Arrays;
0070:        import java.util.Collections;
0071:        import java.util.HashMap;
0072:        import java.util.List;
0073:        import java.util.Map;
0074:        import java.util.ResourceBundle;
0075:        import java.util.Set;
0076:        import java.util.logging.Level;
0077:        import java.util.logging.Logger;
0078:        import javax.accessibility.Accessible;
0079:        import javax.swing.BorderFactory;
0080:        import javax.swing.ImageIcon;
0081:        import javax.swing.JButton;
0082:        import javax.swing.JComponent;
0083:        import javax.swing.JLabel;
0084:        import javax.swing.JList;
0085:        import javax.swing.JPanel;
0086:        import javax.swing.JProgressBar;
0087:        import javax.swing.JScrollPane;
0088:        import javax.swing.JSeparator;
0089:        import javax.swing.JTabbedPane;
0090:        import javax.swing.JTextArea;
0091:        import javax.swing.KeyStroke;
0092:        import javax.swing.ListCellRenderer;
0093:        import javax.swing.SwingConstants;
0094:        import javax.swing.SwingUtilities;
0095:        import javax.swing.UIManager;
0096:        import javax.swing.event.ChangeEvent;
0097:        import javax.swing.event.ChangeListener;
0098:        import org.openide.awt.HtmlBrowser;
0099:        import org.openide.awt.Mnemonics;
0100:        import org.openide.util.Exceptions;
0101:        import org.openide.util.HelpCtx;
0102:        import org.openide.util.Mutex;
0103:        import org.openide.util.NbBundle;
0104:        import org.openide.util.RequestProcessor;
0105:        import org.openide.util.Utilities;
0106:        import org.openide.util.WeakListeners;
0107:        import org.netbeans.api.progress.ProgressHandle;
0108:        import org.netbeans.api.progress.ProgressHandleFactory;
0109:
0110:        /**
0111:         * Implements a basic "wizard" GUI system.
0112:         * A list of <em>wizard panels</em> may be specified and these
0113:         * may be traversed at the proper times using the "Previous"
0114:         * and "Next" buttons (or "Finish" on the last one).
0115:         * @see DialogDisplayer#createDialog
0116:         * @see <a href="doc-files/wizard-guidebook.html">Wizard Guidebook
0117:         * (describes the set of properties controlling the display of wizard panels)</a>
0118:         */
0119:        public class WizardDescriptor extends DialogDescriptor {
0120:            /** "Next" button option.
0121:             * @see #setOptions */
0122:            public static final Object NEXT_OPTION = new String("NEXT_OPTION"); // NOI18N
0123:
0124:            /** "Finish" button option.
0125:             * @see #setOptions */
0126:            public static final Object FINISH_OPTION = OK_OPTION;
0127:
0128:            /** "Previous" button option.
0129:             * @see #setOptions */
0130:            public static final Object PREVIOUS_OPTION = new String(
0131:                    "PREVIOUS_OPTION"); // NOI18N
0132:            private static final ActionListener CLOSE_PREVENTER = new ActionListener() {
0133:                public void actionPerformed(ActionEvent evt) {
0134:                }
0135:
0136:                @Override
0137:                public String toString() {
0138:                    return "CLOSE_PREVENTER"; // NOI18N
0139:                }
0140:            };
0141:
0142:            /** <CODE>Boolean</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0143:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0144:             * Set to <CODE>true</CODE> for enabling other properties. It is relevant only on
0145:             * initialization (client property in first panel).
0146:             * When false or not present in JComponent.getClientProperty(), then supplied panel is
0147:             * used directly without content, help or panel name auto layout.
0148:             */
0149:            private static final String PROP_AUTO_WIZARD_STYLE = "WizardPanel_autoWizardStyle"; // NOI18N
0150:
0151:            /** <CODE>Boolean</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0152:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0153:             * Set to <CODE>true</CODE> for showing help pane in the left pane. It is relevant only on
0154:             * initialization (client property in first panel).
0155:             */
0156:            private static final String PROP_HELP_DISPLAYED = "WizardPanel_helpDisplayed"; // NOI18N
0157:
0158:            /** <CODE>Boolean</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0159:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0160:             * Set to <CODE>true</CODE> for showing content pane in the left pane. It is relevant only on
0161:             * initialization (client property in first panel).
0162:             */
0163:            private static final String PROP_CONTENT_DISPLAYED = "WizardPanel_contentDisplayed"; // NOI18N
0164:
0165:            /** <CODE>Boolean</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0166:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0167:             * Set to <CODE>true</CODE> for displaying numbers in the content. It is relevant only on
0168:             * initialization (client property in first panel).
0169:             */
0170:            private static final String PROP_CONTENT_NUMBERED = "WizardPanel_contentNumbered"; // NOI18N
0171:
0172:            /** <CODE>Integer</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0173:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0174:             * Represents index of content item which will be highlited.
0175:             */
0176:            private static final String PROP_CONTENT_SELECTED_INDEX = "WizardPanel_contentSelectedIndex"; // NOI18N
0177:
0178:            /** <CODE>String[]</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0179:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0180:             * Represents array of content items.
0181:             */
0182:            private static final String PROP_CONTENT_DATA = "WizardPanel_contentData"; // NOI18N
0183:
0184:            /** <CODE>Color</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0185:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0186:             * Set to background color of content pane.
0187:             */
0188:            private static final String PROP_CONTENT_BACK_COLOR = "WizardPanel_contentBackColor"; // NOI18N
0189:
0190:            /** <CODE>Color</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0191:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0192:             * Set to foreground color of content pane.
0193:             */
0194:            private static final String PROP_CONTENT_FOREGROUND_COLOR = "WizardPanel_contentForegroundColor"; // NOI18N
0195:
0196:            /** <CODE>Image</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0197:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0198:             * Set to image which should be displayed in the left pane (behind the content).
0199:             */
0200:            private static final String PROP_IMAGE = "WizardPanel_image"; // NOI18N
0201:
0202:            /** <CODE>String</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0203:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0204:             * Set to side where the image should be drawn.
0205:             */
0206:            private static final String PROP_IMAGE_ALIGNMENT = "WizardPanel_imageAlignment"; // NOI18N
0207:
0208:            /** <CODE>Dimension</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0209:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0210:             * Dimension of left pane, should be same as dimension of <CODE>PROP_IMAGE</CODE>.
0211:             * It is relevant only on initialization (client property in first panel).
0212:             */
0213:            private static final String PROP_LEFT_DIMENSION = "WizardPanel_leftDimension"; // NOI18N
0214:
0215:            /** <CODE>URL</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE> or
0216:             * <CODE>((JComponent)Panel.getComponent()).getClientProperty()</CODE> in this order.
0217:             * Represents URL of help displayed in left pane.
0218:             */
0219:            private static final String PROP_HELP_URL = "WizardPanel_helpURL"; // NOI18N
0220:
0221:            /** <CODE>String</CODE> property. The value is taken from <CODE>WizardDescriptor.getProperty()</CODE>.
0222:             * If it contains non-null value the String is displayed the bottom of the wizard
0223:             * and should inform user why the panel is invalid and why the Next/Finish
0224:             * buttons were disabled.
0225:             * @since 3.39
0226:             */
0227:            private static final String PROP_ERROR_MESSAGE = "WizardPanel_errorMessage"; // NOI18N
0228:
0229:            private static Logger err = Logger.getLogger(WizardDescriptor.class
0230:                    .getName());
0231:
0232:            /** real buttons to be placed instead of the options */
0233:            private final JButton nextButton = new JButton();
0234:            private final JButton finishButton = new JButton();
0235:            private final JButton cancelButton = new JButton();
0236:            private final JButton previousButton = new JButton();
0237:            private FinishAction finishOption;
0238:            private Set /*<Object>*/newObjects = Collections.EMPTY_SET;
0239:
0240:            /** a component with wait cursor */
0241:            private Component waitingComponent;
0242:            private boolean changeStateInProgress = false;
0243:
0244:            /** Whether wizard panel will be constructed from <CODE>WizardDescriptor.getProperty()</CODE>/
0245:             * <CODE>(JComponent)Panel.getComponent()</CODE> client properties or returned
0246:             * <CODE>Component</CODE> will be inserted to wizard dialog directly.
0247:             */
0248:            private boolean autoWizardStyle = false;
0249:
0250:            /** Whether properties from first <CODE>(JComponent)Panel.getComponent()</CODE>
0251:             * have been initialized.
0252:             */
0253:            private boolean init = false;
0254:
0255:            /** Panel which is used when in <CODE>AUTO_WIZARD_STYLE</CODE> mode.*/
0256:            private WizardPanel wizardPanel;
0257:
0258:            /** Image */
0259:            private Image image;
0260:
0261:            /** Content data */
0262:            private String[] contentData = new String[] {};
0263:
0264:            /** Selected content index */
0265:            private int contentSelectedIndex = -1;
0266:
0267:            /** Background color*/
0268:            private Color contentBackColor;
0269:
0270:            /** Foreground color*/
0271:            private Color contentForegroundColor;
0272:
0273:            /** Help URL displayed in the left pane */
0274:            private URL helpURL;
0275:
0276:            /** Listener on a user component client property changes*/
0277:            private PropL propListener;
0278:
0279:            /** 'North' or 'South' */
0280:            private String imageAlignment = "North"; // NOI18N
0281:
0282:            /** Iterator between panels in the wizard and its settings */
0283:            private SettingsAndIterator<?> data;
0284:
0285:            /** Change listener that invokes method update state */
0286:            private ChangeListener weakChangeListener;
0287:            private PropertyChangeListener weakPropertyChangeListener;
0288:            private ActionListener weakNextButtonListener;
0289:            private ActionListener weakPreviousButtonListener;
0290:            private ActionListener weakFinishButtonListener;
0291:            private ActionListener weakCancelButtonListener;
0292:
0293:            // base listener which won't be directly attached, will only wrapped by WeakListener
0294:            private Listener baseListener;
0295:
0296:            /** message format to create title of the document */
0297:            private MessageFormat titleFormat;
0298:
0299:            /** hashtable with additional settings that is usually used
0300:             * by Panels to store their data
0301:             */
0302:            private Map<String, Object> properties;
0303:            ResourceBundle bundle = NbBundle.getBundle(WizardDescriptor.class);
0304:
0305:            /** Request processor that is used for asynchronous jobs (background validation, 
0306:             * asynchronous instantiation i.e.) and supports Thread.interrupted().
0307:             * It's package-private to accessible for unit tests.
0308:             */
0309:            static final RequestProcessor ASYNCHRONOUS_JOBS_RP = new RequestProcessor(
0310:                    "wizard-descriptor-asynchronous-jobs", 1, true); // NOI18N
0311:
0312:            private RequestProcessor.Task backgroundValidationTask;
0313:
0314:            private boolean validationRuns;
0315:
0316:            private ProgressHandle handle;
0317:
0318:            private static final String PROGRESS_BAR_DISPLAY_NAME = NbBundle
0319:                    .getMessage(WizardDescriptor.class,
0320:                            "CTL_InstantiateProgress_Title"); // NOI18N
0321:
0322:            private ActionListener escapeActionListener;
0323:
0324:            {
0325:                // button init
0326:                ResourceBundle b = NbBundle.getBundle("org.openide.Bundle"); // NOI18N
0327:                Mnemonics.setLocalizedText(nextButton, b.getString("CTL_NEXT"));
0328:                Mnemonics.setLocalizedText(previousButton, b
0329:                        .getString("CTL_PREVIOUS"));
0330:                Mnemonics.setLocalizedText(finishButton, b
0331:                        .getString("CTL_FINISH"));
0332:                finishButton.getAccessibleContext().setAccessibleDescription(
0333:                        b.getString("ACSD_FINISH"));
0334:                Mnemonics.setLocalizedText(cancelButton, b
0335:                        .getString("CTL_CANCEL"));
0336:                cancelButton.getAccessibleContext().setAccessibleDescription(
0337:                        b.getString("ACSD_CANCEL"));
0338:
0339:                finishButton.setDefaultCapable(true);
0340:                nextButton.setDefaultCapable(true);
0341:                previousButton.setDefaultCapable(false);
0342:                cancelButton.setDefaultCapable(false);
0343:            }
0344:
0345:            /** Create a new wizard from a fixed list of panels, passing some settings to the panels.
0346:             * @param wizardPanels the panels to use
0347:             * @param settings the settings to pass to panels, or <code>null</code>
0348:             * @see #WizardDescriptor(WizardDescriptor.Iterator, Object)
0349:             */
0350:            public <Data> WizardDescriptor(Panel<Data>[] wizardPanels,
0351:                    Data settings) {
0352:                this (new SettingsAndIterator<Data>(new ArrayIterator<Data>(
0353:                        wizardPanels), settings));
0354:            }
0355:
0356:            /** Create a new wizard from a fixed list of panels with settings
0357:             * defaulted to <CODE>this</CODE>.
0358:             *
0359:             * @param wizardPanels the panels to use
0360:             * @see #WizardDescriptor(WizardDescriptor.Iterator, Object)
0361:             */
0362:            public WizardDescriptor(Panel<WizardDescriptor>[] wizardPanels) {
0363:                this (SettingsAndIterator
0364:                        .create(new ArrayIterator<WizardDescriptor>(
0365:                                wizardPanels)));
0366:            }
0367:
0368:            /** Create wizard for a sequence of panels, passing some settings to the panels.
0369:             * @param panels iterator over all {@link WizardDescriptor.Panel}s that can appear in the wizard
0370:             * @param settings the settings to provide to the panels (may be any data understood by them)
0371:             * @see WizardDescriptor.Panel#readSettings
0372:             * @see WizardDescriptor.Panel#storeSettings
0373:             */
0374:            public <Data> WizardDescriptor(Iterator<Data> panels, Data settings) {
0375:                this (new SettingsAndIterator<Data>(panels, settings));
0376:            }
0377:
0378:            /** Constructor for subclasses. The expected use is to call this
0379:             * constructor and then call {@link #setPanelsAndSettings} to provide
0380:             * the right iterator, panels and data the wizard should use. This 
0381:             * allows to eliminate unchecked warnings as described in 
0382:             * <a href="http://www.netbeans.org/issues/show_bug.cgi?id=102261">issue 102261</a>.
0383:             * @since 7.4
0384:             */
0385:            protected WizardDescriptor() {
0386:                this (SettingsAndIterator.empty());
0387:            }
0388:
0389:            private <Data> WizardDescriptor(SettingsAndIterator<Data> data) {
0390:                super ("", "", true, DEFAULT_OPTION, null, CLOSE_PREVENTER); // NOI18N
0391:
0392:                this .data = data;
0393:
0394:                baseListener = new Listener();
0395:
0396:                weakNextButtonListener = WeakListeners.create(
0397:                        ActionListener.class, baseListener, nextButton); // NOI18N
0398:                weakPreviousButtonListener = WeakListeners.create(
0399:                        ActionListener.class, baseListener, previousButton); // NOI18N
0400:                weakFinishButtonListener = WeakListeners.create(
0401:                        ActionListener.class, baseListener, finishButton); // NOI18N
0402:                weakCancelButtonListener = WeakListeners.create(
0403:                        ActionListener.class, baseListener, cancelButton); // NOI18N
0404:
0405:                nextButton.addActionListener(weakNextButtonListener);
0406:                previousButton.addActionListener(weakPreviousButtonListener);
0407:                finishButton.addActionListener(weakFinishButtonListener);
0408:                cancelButton.addActionListener(weakCancelButtonListener);
0409:
0410:                finishOption = new WizardDescriptor.FinishAction();
0411:
0412:                super .setOptions(new Object[] { previousButton, nextButton,
0413:                        finishButton, cancelButton });
0414:                super .setClosingOptions(new Object[] { finishOption,
0415:                        cancelButton });
0416:
0417:                // attach the change listener to iterator
0418:                weakChangeListener = WeakListeners.change(baseListener, data
0419:                        .getIterator(this ));
0420:                data.getIterator(this ).addChangeListener(weakChangeListener);
0421:
0422:                callInitialize();
0423:            }
0424:
0425:            /** Create wizard for a sequence of panels, with settings
0426:             * defaulted to <CODE>this</CODE>.
0427:             *
0428:             * @param panels iterator over all {@link WizardDescriptor.Panel}s that can appear in the wizard
0429:             */
0430:            public WizardDescriptor(Iterator<WizardDescriptor> panels) {
0431:                this (SettingsAndIterator.create(panels));
0432:            }
0433:
0434:            /** Initializes settings.
0435:             */
0436:            @Override
0437:            protected void initialize() {
0438:                super .initialize();
0439:
0440:                updateState();
0441:
0442:                // #81938: special handling WizardDescriptor to avoid close wizard during instantiate
0443:                SwingUtilities.invokeLater(new Runnable() {
0444:                    public void run() {
0445:                        final Window w = SwingUtilities
0446:                                .getWindowAncestor((Component) getMessage());
0447:                        if (w != null) {
0448:                            w.addWindowListener(new WindowListener() {
0449:                                public void windowActivated(WindowEvent e) {
0450:                                }
0451:
0452:                                public void windowClosed(WindowEvent e) {
0453:                                }
0454:
0455:                                public void windowClosing(WindowEvent e) {
0456:                                    if (!changeStateInProgress) {
0457:                                        if (WizardDescriptor.this .getValue() == null) {
0458:                                            WizardDescriptor.this 
0459:                                                    .setValueWithoutPCH(NotifyDescriptor.CLOSED_OPTION);
0460:                                        }
0461:                                        w.setVisible(false);
0462:                                        w.dispose();
0463:                                    }
0464:                                }
0465:
0466:                                public void windowDeactivated(WindowEvent e) {
0467:                                }
0468:
0469:                                public void windowDeiconified(WindowEvent e) {
0470:                                }
0471:
0472:                                public void windowIconified(WindowEvent e) {
0473:                                }
0474:
0475:                                public void windowOpened(WindowEvent e) {
0476:                                }
0477:                            });
0478:                        }
0479:                    }
0480:                });
0481:            }
0482:
0483:            /** Set a different list of panels.
0484:             * Correctly updates the buttons.
0485:             * @param panels the new list of {@link WizardDescriptor.Panel}s
0486:             * @deprecated use setPanelsAndSettings if needed.
0487:             */
0488:            @Deprecated
0489:            @SuppressWarnings("unchecked")
0490:            public final synchronized void setPanels(Iterator panels) {
0491:                if (data.getIterator(this ) != null) {
0492:                    data.getIterator(this ).removeChangeListener(
0493:                            weakChangeListener);
0494:                }
0495:
0496:                data = data.clone(panels);
0497:                weakChangeListener = WeakListeners.change(baseListener, data
0498:                        .getIterator(this ));
0499:                data.getIterator(this ).addChangeListener(weakChangeListener);
0500:                init = false;
0501:
0502:                updateState();
0503:            }
0504:
0505:            /** Set a different list of panels.
0506:             * Correctly updates the buttons.
0507:             * @param panels the new list of {@link WizardDescriptor.Panel}s
0508:             * @param settings the new settings that will be passed to the panels
0509:             * @since 7.2
0510:             */
0511:            public final synchronized <Data> void setPanelsAndSettings(
0512:                    Iterator<Data> panels, Data settings) {
0513:                if (data.getIterator(this ) != null) {
0514:                    data.getIterator(this ).removeChangeListener(
0515:                            weakChangeListener);
0516:                }
0517:
0518:                data = new SettingsAndIterator<Data>(panels, settings);
0519:                weakChangeListener = WeakListeners.change(baseListener, data
0520:                        .getIterator(this ));
0521:                data.getIterator(this ).addChangeListener(weakChangeListener);
0522:                init = false;
0523:
0524:                updateState();
0525:            }
0526:
0527:            /** Set options permitted by the wizard considered as a <code>DialogDescriptor</code>.
0528:             * Substitutes tokens such as {@link #NEXT_OPTION} with the actual button.
0529:             *
0530:             * @param options the options to set
0531:             */
0532:            @Override
0533:            public void setOptions(Object[] options) {
0534:                super .setOptions(convertOptions(options));
0535:            }
0536:
0537:            /**
0538:             * @param options the options to set
0539:             */
0540:            @Override
0541:            public void setAdditionalOptions(Object[] options) {
0542:                super .setAdditionalOptions(convertOptions(options));
0543:            }
0544:
0545:            /**
0546:             * @param options the options to set
0547:             */
0548:            @Override
0549:            public void setClosingOptions(Object[] options) {
0550:                super .setClosingOptions(convertOptions(options));
0551:            }
0552:
0553:            /** Converts some options.
0554:             */
0555:            private Object[] convertOptions(Object[] options) {
0556:                Object[] clonedOptions = options.clone();
0557:
0558:                for (int i = clonedOptions.length - 1; i >= 0; i--) {
0559:                    if (clonedOptions[i] == NEXT_OPTION) {
0560:                        clonedOptions[i] = nextButton;
0561:                    }
0562:
0563:                    if (clonedOptions[i] == PREVIOUS_OPTION) {
0564:                        clonedOptions[i] = previousButton;
0565:                    }
0566:
0567:                    if (clonedOptions[i] == FINISH_OPTION) {
0568:                        clonedOptions[i] = finishButton;
0569:                    }
0570:
0571:                    if (clonedOptions[i] == CANCEL_OPTION) {
0572:                        clonedOptions[i] = cancelButton;
0573:                    }
0574:                }
0575:
0576:                return clonedOptions;
0577:            }
0578:
0579:            /** Overriden to ensure that returned value is one of
0580:             * the XXX_OPTION constants.
0581:             */
0582:            @Override
0583:            public Object getValue() {
0584:                return backConvertOption(super .getValue());
0585:            }
0586:
0587:            /** Converts the option back to one of the constants.
0588:             * It is called from getValue().
0589:             */
0590:            private Object backConvertOption(Object op) {
0591:                if (op == nextButton) {
0592:                    return NEXT_OPTION;
0593:                }
0594:
0595:                if (op == previousButton) {
0596:                    return PREVIOUS_OPTION;
0597:                }
0598:
0599:                if (op == finishButton) {
0600:                    return FINISH_OPTION;
0601:                }
0602:
0603:                if (op == cancelButton) {
0604:                    return CANCEL_OPTION;
0605:                }
0606:
0607:                // if we don't know just return the original value
0608:                return op;
0609:            }
0610:
0611:            /** Sets the message format to create title of the wizard.
0612:             * The format can take two parameters. The name of the
0613:             * current component and the name returned by the iterator that
0614:             * defines the order of panels. The default value is something
0615:             * like
0616:             * <PRE>
0617:             *   {0} wizard {1}
0618:             * </PRE>
0619:             * That can be expanded to something like this
0620:             * <PRE>
0621:             *   EJB wizard (1 of 8)
0622:             * </PRE>
0623:             * This method allows anybody to provide own title format.
0624:             *
0625:             * @param format message format to the title
0626:             */
0627:            public void setTitleFormat(MessageFormat format) {
0628:                titleFormat = format;
0629:
0630:                if (init) {
0631:                    updateState();
0632:                }
0633:            }
0634:
0635:            /** Getter for current format to be used to format title.
0636:             * @return the format
0637:             * @see #setTitleFormat
0638:             */
0639:            public synchronized MessageFormat getTitleFormat() {
0640:                if (titleFormat == null) {
0641:                    // ok, initialize the default one
0642:                    titleFormat = new MessageFormat(NbBundle.getMessage(
0643:                            WizardDescriptor.class, "CTL_WizardName"));
0644:                }
0645:
0646:                return titleFormat;
0647:            }
0648:
0649:            /** Allows Panels that use WizardDescriptor as settings object to
0650:             * store additional settings into it.
0651:             *
0652:             * @param name name of the property
0653:             * @param value value of property
0654:             */
0655:            public void putProperty(final String name, final Object value) {
0656:                Object oldValue;
0657:
0658:                synchronized (this ) {
0659:                    if (properties == null) {
0660:                        properties = new HashMap<String, Object>(7);
0661:                    }
0662:
0663:                    oldValue = properties.get(name);
0664:                    properties.put(name, value);
0665:                }
0666:
0667:                // bugfix #27738, firing changes in a value of the property
0668:                firePropertyChange(name, oldValue, value);
0669:
0670:                if (propListener != null) {
0671:                    Mutex.EVENT.readAccess(new Runnable() {
0672:                        public void run() {
0673:                            propListener
0674:                                    .propertyChange(new PropertyChangeEvent(
0675:                                            this , name, null, null));
0676:                        }
0677:                    });
0678:                }
0679:
0680:                if (PROP_ERROR_MESSAGE.equals(name)) {
0681:                    // #76318: New Entity wizard shows unreadable red error
0682:                    if (init && OK_OPTION.equals(getValue()))
0683:                        return; // call getValue() only on initialized WD
0684:                    if (wizardPanel != null) {
0685:                        SwingUtilities.invokeLater(new Runnable() {
0686:                            public void run() {
0687:                                wizardPanel
0688:                                        .setErrorMessage(
0689:                                                (String) ((value == null) ? " "
0690:                                                        : value),
0691:                                                (nextButton.isEnabled() || finishButton
0692:                                                        .isEnabled()) ? Boolean.TRUE
0693:                                                        : Boolean.FALSE); //NOI18N
0694:                            }
0695:                        });
0696:                    }
0697:                }
0698:            }
0699:
0700:            /** Getter for stored property.
0701:             * @param name name of the property
0702:             * @return the value
0703:             */
0704:            public synchronized Object getProperty(String name) {
0705:                return (properties == null) ? null : properties.get(name);
0706:            }
0707:
0708:            /** Read only map with stored properties.
0709:             * @return read only map of properties stored using {@link #putProperty} method
0710:             * @since 7.2
0711:             */
0712:            public synchronized Map<String, Object> getProperties() {
0713:                return properties == null ? Collections
0714:                        .<String, Object> emptyMap()
0715:                        : new HashMap<String, Object>(properties);
0716:            }
0717:
0718:            @Override
0719:            public void setHelpCtx(final HelpCtx helpCtx) {
0720:                if ((wizardPanel != null) && (helpCtx != null)) {
0721:                    HelpCtx.setHelpIDString(wizardPanel, helpCtx.getHelpID());
0722:                }
0723:
0724:                // we call the inherited method after setting the ID
0725:                // on the panel becuase super.setHelpCtx fires the change
0726:                super .setHelpCtx(helpCtx);
0727:            }
0728:
0729:            /** Returns set of newly instantiated objects if the wizard has been correctly finished.
0730:             * Returns the empty set as default. If the wizard uses the InstantiatingIterator
0731:             * then WizardDescriptor returns a set of Object as same as InstantiatingIterator.instantiate().
0732:             *
0733:             * @exception IllegalStateException if this method is called on the unfinished wizard
0734:             * @return a set of Objects created
0735:             * @since 4.41
0736:             */
0737:            public Set /*<Object>*/getInstantiatedObjects() {
0738:                // 
0739:                if (!(FINISH_OPTION.equals(getValue()))) {
0740:                    throw new IllegalStateException();
0741:                }
0742:
0743:                return newObjects;
0744:            }
0745:
0746:            /** Updates buttons to reflect the current state of the panels.
0747:             * Can be overridden by subclasses
0748:             * to change the options to special values. In such a case use:
0749:             * <p><code><PRE>
0750:             *   super.updateState ();
0751:             *   setOptions (...);
0752:             * </PRE></code>
0753:             */
0754:            protected synchronized void updateState() {
0755:                updateStateOpen(data);
0756:            }
0757:
0758:            private <A> void updateStateOpen(SettingsAndIterator<A> data) {
0759:                Panel<A> p = data.getIterator(this ).current();
0760:
0761:                // listeners on the panel
0762:                if (data.current != p) {
0763:                    if (data.current != null) {
0764:                        // remove
0765:                        data.current.removeChangeListener(weakChangeListener);
0766:                        data.current.storeSettings(data.getSettings(this ));
0767:                    }
0768:
0769:                    // Hack - obtain current panel again
0770:                    // It's here to allow dynamic change of panels in wizard
0771:                    // (which can be done in storeSettings method)
0772:                    p = data.getIterator(this ).current();
0773:
0774:                    // add to new, detach old change listener and attach new one
0775:                    data.getIterator(this ).removeChangeListener(
0776:                            weakChangeListener);
0777:                    weakChangeListener = WeakListeners.change(baseListener, p);
0778:                    data.getIterator(this )
0779:                            .addChangeListener(weakChangeListener);
0780:                    p.addChangeListener(weakChangeListener);
0781:
0782:                    data.current = p;
0783:                    p.readSettings(data.getSettings(this ));
0784:                }
0785:
0786:                boolean next = data.getIterator(this ).hasNext();
0787:                boolean prev = data.getIterator(this ).hasPrevious();
0788:                boolean valid = p.isValid();
0789:
0790:                // AWT sensitive code
0791:                if (SwingUtilities.isEventDispatchThread()) {
0792:                    updateStateInAWT();
0793:                } else {
0794:                    SwingUtilities.invokeLater(new Runnable() {
0795:                        public void run() {
0796:                            updateStateInAWT();
0797:                        }
0798:                    });
0799:                }
0800:                // end of AWT sensitive code
0801:
0802:                //    nextButton.setVisible (next);
0803:                //    finishButton.setVisible (!next || (current instanceof FinishPanel));
0804:                // XXX Why setValue on Next ?
0805:                //        if (next) {
0806:                //            setValue (nextButton);
0807:                //        } else {
0808:                ////            setValue (finishButton); 
0809:                //        }
0810:                setHelpCtx(p.getHelp());
0811:
0812:                java.awt.Component c = p.getComponent();
0813:
0814:                if ((c == null) || c instanceof  java.awt.Window) {
0815:                    throw new IllegalStateException("Wizard panel " + p
0816:                            + " gave a strange component " + c); // NOI18N
0817:                }
0818:
0819:                if (!init) {
0820:                    if (c instanceof  JComponent) {
0821:                        autoWizardStyle = getBooleanProperty((JComponent) c,
0822:                                PROP_AUTO_WIZARD_STYLE);
0823:
0824:                        if (autoWizardStyle) {
0825:                            wizardPanel = new WizardPanel(getBooleanProperty(
0826:                                    (JComponent) c, PROP_CONTENT_DISPLAYED),
0827:                                    getBooleanProperty((JComponent) c,
0828:                                            PROP_HELP_DISPLAYED),
0829:                                    getBooleanProperty((JComponent) c,
0830:                                            PROP_CONTENT_NUMBERED),
0831:                                    getLeftDimension((JComponent) c));
0832:                            initBundleProperties();
0833:                        }
0834:                    }
0835:
0836:                    if (propListener == null) {
0837:                        propListener = new PropL();
0838:                    }
0839:
0840:                    init = true;
0841:                }
0842:
0843:                //update wizardPanel
0844:                if (wizardPanel != null) {
0845:                    Component oldComp = wizardPanel.getRightComponent();
0846:
0847:                    if (oldComp != null) {
0848:                        oldComp
0849:                                .removePropertyChangeListener(weakPropertyChangeListener);
0850:                    }
0851:
0852:                    if (c instanceof  JComponent) {
0853:                        setPanelProperties((JComponent) c);
0854:                        wizardPanel.setContent(contentData);
0855:                        wizardPanel.setSelectedIndex(contentSelectedIndex);
0856:                        wizardPanel.setContentBackColor(contentBackColor);
0857:                        wizardPanel
0858:                                .setContentForegroundColor(contentForegroundColor);
0859:                        wizardPanel.setImage(image);
0860:                        wizardPanel.setImageAlignment(imageAlignment);
0861:                        wizardPanel.setHelpURL(helpURL);
0862:                        updateButtonAccessibleDescription();
0863:                        weakPropertyChangeListener = WeakListeners
0864:                                .propertyChange(propListener, c);
0865:                        c.addPropertyChangeListener(weakPropertyChangeListener);
0866:                    }
0867:
0868:                    if (wizardPanel.getRightComponent() != c) {
0869:                        wizardPanel.setRightComponent(c);
0870:
0871:                        if (wizardPanel != getMessage()) {
0872:                            setMessage(wizardPanel);
0873:                        } else {
0874:                            // force revalidate and repaint because the contents of
0875:                            // wizardPanel has changed.  See NbPresenter code
0876:                            firePropertyChange(DialogDescriptor.PROP_MESSAGE,
0877:                                    null, wizardPanel);
0878:                        }
0879:                    }
0880:                } else if (c != getMessage()) {
0881:                    setMessage(c);
0882:                }
0883:
0884:                String panelName = c.getName();
0885:
0886:                if (panelName == null) {
0887:                    panelName = ""; // NOI18N
0888:                }
0889:
0890:                Object[] args = { panelName, data.getIterator(this ).name() };
0891:                MessageFormat mf = getTitleFormat();
0892:
0893:                if (autoWizardStyle) {
0894:                    wizardPanel.setPanelName(mf.format(args));
0895:                } else {
0896:                    setTitle(mf.format(args));
0897:                }
0898:
0899:                Component fo = KeyboardFocusManager
0900:                        .getCurrentKeyboardFocusManager().getFocusOwner();
0901:
0902:                if ((fo != null) && (!fo.isEnabled()) && (wizardPanel != null)) {
0903:                    wizardPanel.requestFocus();
0904:                }
0905:            }
0906:
0907:            // for xtesting usage only
0908:            boolean isForwardEnabled() {
0909:                return data.getIterator(this ).current().isValid()
0910:                        && !validationRuns;
0911:            }
0912:
0913:            private void updateStateInAWT() {
0914:                Panel<?> p = data.getIterator(this ).current();
0915:                boolean next = data.getIterator(this ).hasNext();
0916:                boolean prev = data.getIterator(this ).hasPrevious();
0917:                boolean valid = p.isValid() && !validationRuns;
0918:
0919:                nextButton.setEnabled(next && valid);
0920:                previousButton.setEnabled(prev);
0921:                cancelButton.setEnabled(true);
0922:
0923:                if (data.current instanceof  FinishablePanel) {
0924:                    // check if isFinishPanel
0925:                    if (((FinishablePanel) data.current).isFinishPanel()) {
0926:                        finishButton.setEnabled(valid);
0927:                    } else {
0928:                        // XXX What if the last panel is not FinishPanel ??? enable ?
0929:                        finishButton.setEnabled(valid && !next);
0930:                    }
0931:                } else {
0932:                    // original way
0933:                    finishButton
0934:                            .setEnabled(valid
0935:                                    && (!next || (data.current instanceof  FinishPanel)));
0936:                }
0937:            }
0938:
0939:            /** Shows blocking wait cursor during updateState run */
0940:            private void updateStateWithFeedback() {
0941:                try {
0942:                    showWaitCursor();
0943:                    updateState();
0944:                } finally {
0945:                    showNormalCursor();
0946:                }
0947:            }
0948:
0949:            /** Shows next step in UI of wizards, displays wait cursot during the change.
0950:             */
0951:            private void goToNextStep(Dimension previousSize) {
0952:                try {
0953:                    showWaitCursor();
0954:
0955:                    boolean alreadyUpdated = false;
0956:                    Font controlFont = (Font) UIManager.getDefaults().get(
0957:                            "controlFont"); //NOI18N
0958:                    Integer defaultSize = (Integer) UIManager
0959:                            .get("nbDefaultFontSize");
0960:
0961:                    if (defaultSize == null) {
0962:                        //Plastic look and feel...
0963:                        defaultSize = new Integer(11);
0964:                    }
0965:
0966:                    // enable auto-resizing policy only for fonts bigger thne default
0967:                    if ((controlFont != null)
0968:                            && (controlFont.getSize() > defaultSize.intValue())) { //NOI18N
0969:
0970:                        Window parentWindow = SwingUtilities
0971:                                .getWindowAncestor((Component) getMessage());
0972:
0973:                        if (parentWindow != null) {
0974:                            updateState();
0975:                            alreadyUpdated = true;
0976:                            resizeWizard(parentWindow, previousSize);
0977:                        }
0978:                    }
0979:
0980:                    if (!alreadyUpdated) {
0981:                        updateState();
0982:                    }
0983:
0984:                    if (wizardPanel != null) {
0985:                        wizardPanel.requestFocus();
0986:                    }
0987:                } finally {
0988:                    showNormalCursor();
0989:                }
0990:            }
0991:
0992:            /** Tries to resize wizard wisely if needed. Keeps "display inertia" so that
0993:             * wizard is only enlarged, not shrinked, and location is changed only when
0994:             * wizard window exceeds screen bounds after resize.
0995:             */
0996:            private void resizeWizard(Window parentWindow, Dimension prevSize) {
0997:                Dimension curSize = data.getIterator(this ).current()
0998:                        .getComponent().getPreferredSize();
0999:
1000:                // only enlarge if needed, don't shrink
1001:                if ((curSize.width > prevSize.width)
1002:                        || (curSize.height > prevSize.height)) {
1003:                    Rectangle origBounds = parentWindow.getBounds();
1004:                    int newWidth = Math.max(origBounds.width
1005:                            + (curSize.width - prevSize.width),
1006:                            origBounds.width);
1007:                    int newHeight = Math.max(origBounds.height
1008:                            + (curSize.height - prevSize.height),
1009:                            origBounds.height);
1010:                    Rectangle screenBounds = Utilities.getUsableScreenBounds();
1011:                    Rectangle newBounds;
1012:
1013:                    // don't allow to exceed screen size, center if needed
1014:                    if (((origBounds.x + newWidth) > screenBounds.width)
1015:                            || ((origBounds.y + newHeight) > screenBounds.height)) {
1016:                        newWidth = Math.min(screenBounds.width, newWidth);
1017:                        newHeight = Math.min(screenBounds.height, newHeight);
1018:                        newBounds = Utilities.findCenterBounds(new Dimension(
1019:                                newWidth, newHeight));
1020:                    } else {
1021:                        newBounds = new Rectangle(origBounds.x, origBounds.y,
1022:                                newWidth, newHeight);
1023:                    }
1024:
1025:                    parentWindow.setBounds(newBounds);
1026:                    parentWindow.invalidate();
1027:                    parentWindow.validate();
1028:                    parentWindow.repaint();
1029:                }
1030:            }
1031:
1032:            private void showWaitCursor() {
1033:                if ((wizardPanel == null)
1034:                        || (wizardPanel.getRootPane() == null)) {
1035:                    // if none root pane --> don't set wait cursor
1036:                    return;
1037:                }
1038:
1039:                // bugfix #92539: JR: I don't see the reason this code, I have tried comment out
1040:                //        Window parentWindow = SwingUtilities.getWindowAncestor((Component) getMessage());
1041:                //        if (parentWindow != null) {
1042:                //            parentWindow.setEnabled (false);
1043:                //        }
1044:                //        
1045:                if (wizardPanel != null) {
1046:                    // save escapeActionListener for normal state
1047:                    KeyStroke ks = KeyStroke
1048:                            .getKeyStroke(KeyEvent.VK_ESCAPE, 0);
1049:                    escapeActionListener = wizardPanel.getRootPane()
1050:                            .getActionForKeyStroke(ks);
1051:                    wizardPanel.getRootPane().unregisterKeyboardAction(ks);
1052:                }
1053:
1054:                waitingComponent = wizardPanel.getRootPane().getContentPane();
1055:                waitingComponent.setCursor(Cursor
1056:                        .getPredefinedCursor(Cursor.WAIT_CURSOR));
1057:                changeStateInProgress = true;
1058:            }
1059:
1060:            private void showNormalCursor() {
1061:                if (waitingComponent == null) {
1062:                    // none waitingComponent --> don't change cursor to normal
1063:                    return;
1064:                }
1065:
1066:                Window parentWindow = SwingUtilities
1067:                        .getWindowAncestor((Component) getMessage());
1068:                if (parentWindow != null) {
1069:                    parentWindow.setEnabled(true);
1070:                }
1071:
1072:                if (wizardPanel != null) {
1073:                    // set back escapeActionListener as same as NbPresenter does
1074:                    if (escapeActionListener != null) {
1075:                        wizardPanel.getRootPane().registerKeyboardAction(
1076:                                escapeActionListener, "Escape",
1077:                                KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
1078:                                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
1079:                    }
1080:                }
1081:
1082:                waitingComponent.setCursor(null);
1083:                waitingComponent = null;
1084:                changeStateInProgress = false;
1085:            }
1086:
1087:            /* commented out - issue #32927. Replaced by javadoc info in WizardDescriptor.Panel
1088:            private static final Set warnedPanelIsComponent = new WeakSet(); // Set<Class>
1089:            private static synchronized void warnPanelIsComponent(Class c) {
1090:                if (warnedPanelIsComponent.add(c)) {
1091:                    StringBuffer buffer = new StringBuffer(150);
1092:                    buffer.append("WARNING - the WizardDescriptor.Panel implementation "); // NOI18N
1093:                    buffer.append(c.getName());
1094:                    buffer.append(" provides itself as the result of getComponent().\n"); // NOI18N
1095:                    buffer.append("This hurts performance and can cause a clash when Component.isValid() is overridden.\n"); // NOI18N
1096:                    buffer.append("Please use a separate component class, see details at http://performance.netbeans.org/howto/dialogs/wizard-panels.html."); // NOI18N
1097:                    err.log(ErrorManager.WARNING, buffer.toString());
1098:                }
1099:            }
1100:             */
1101:
1102:            /** Tryes to get property from getProperty() if doesn't succeed then tryes at
1103:             * supplied <CODE>JComponent</CODE>s client property.
1104:             * @param c origin of property
1105:             * @param s name of property
1106:             * @return boolean property
1107:             */
1108:            private boolean getBooleanProperty(JComponent c, String s) {
1109:                Object property = getProperty(s);
1110:
1111:                if (property instanceof  Boolean) {
1112:                    return ((Boolean) property).booleanValue();
1113:                }
1114:
1115:                property = c.getClientProperty(s);
1116:
1117:                if (property instanceof  Boolean) {
1118:                    return ((Boolean) property).booleanValue();
1119:                }
1120:
1121:                return false;
1122:            }
1123:
1124:            /** Tryes to get dimension of wizard panel's left pane from getProperty()
1125:             * if doesn't succeed then tryes at
1126:             * supplied <CODE>JComponent</CODE>s client property.
1127:             * @return <CODE>Dimension</CODE> dimension of wizard panel's left pane
1128:             */
1129:            private Dimension getLeftDimension(JComponent c) {
1130:                Dimension leftDimension;
1131:                Object property = c.getClientProperty(PROP_LEFT_DIMENSION);
1132:
1133:                if (property instanceof  Dimension) {
1134:                    leftDimension = (Dimension) property;
1135:                } else {
1136:                    leftDimension = new Dimension(198, 233);
1137:                }
1138:
1139:                return leftDimension;
1140:            }
1141:
1142:            /** Tryes to get properties from getProperty() if doesn't succeed then tryes at
1143:             * supplied <CODE>JComponent</CODE>s client properties and store them
1144:             * to appropriate fields.
1145:             * @param c origin of property
1146:             * @param s name of property
1147:             * @return boolean property
1148:             */
1149:            private void setPanelProperties(JComponent c) {
1150:                // TODO: Method should be devided into individual setter/getter methods !?
1151:                Object property = getProperty(PROP_CONTENT_SELECTED_INDEX);
1152:
1153:                if (property instanceof  Integer) {
1154:                    contentSelectedIndex = ((Integer) property).intValue();
1155:                } else {
1156:                    property = c.getClientProperty(PROP_CONTENT_SELECTED_INDEX);
1157:
1158:                    if (property instanceof  Integer) {
1159:                        contentSelectedIndex = ((Integer) property).intValue();
1160:                    }
1161:                }
1162:
1163:                property = getProperty(PROP_CONTENT_DATA);
1164:
1165:                if (property instanceof  String[]) {
1166:                    contentData = (String[]) property;
1167:                } else {
1168:                    property = c.getClientProperty(PROP_CONTENT_DATA);
1169:
1170:                    if (property instanceof  String[]) {
1171:                        contentData = (String[]) property;
1172:                    }
1173:                }
1174:
1175:                property = getProperty(PROP_IMAGE);
1176:
1177:                if (property instanceof  Image) {
1178:                    image = (Image) property;
1179:                } else if ((properties == null)
1180:                        || (!properties.containsKey(PROP_IMAGE))) {
1181:                    property = c.getClientProperty(PROP_IMAGE);
1182:
1183:                    if (property instanceof  Image) {
1184:                        image = (Image) property;
1185:                    }
1186:                }
1187:
1188:                property = getProperty(PROP_IMAGE_ALIGNMENT);
1189:
1190:                if (property instanceof  String) {
1191:                    imageAlignment = (String) property;
1192:                } else {
1193:                    property = c.getClientProperty(PROP_IMAGE_ALIGNMENT);
1194:
1195:                    if (property instanceof  String) {
1196:                        imageAlignment = (String) property;
1197:                    }
1198:                }
1199:
1200:                property = getProperty(PROP_CONTENT_BACK_COLOR);
1201:
1202:                if (property instanceof  Color) {
1203:                    contentBackColor = (Color) property;
1204:                } else {
1205:                    property = c.getClientProperty(PROP_CONTENT_BACK_COLOR);
1206:
1207:                    if (property instanceof  Color) {
1208:                        contentBackColor = (Color) property;
1209:                    }
1210:                }
1211:
1212:                property = getProperty(PROP_CONTENT_FOREGROUND_COLOR);
1213:
1214:                if (property instanceof  Color) {
1215:                    contentForegroundColor = (Color) property;
1216:                } else {
1217:                    property = c
1218:                            .getClientProperty(PROP_CONTENT_FOREGROUND_COLOR);
1219:
1220:                    if (property instanceof  Color) {
1221:                        contentForegroundColor = (Color) property;
1222:                    }
1223:                }
1224:
1225:                property = c.getClientProperty(PROP_HELP_URL);
1226:
1227:                if (property instanceof  URL) {
1228:                    helpURL = (URL) property;
1229:                } else if (property == null) {
1230:                    helpURL = null;
1231:                }
1232:            }
1233:
1234:            private void initBundleProperties() {
1235:                contentBackColor = new Color(
1236:                        getIntFromBundle("INT_WizardBackRed"), // NOI18N
1237:                        getIntFromBundle("INT_WizardBackGreen"), // NOI18N
1238:                        getIntFromBundle("INT_WizardBackBlue") // NOI18N
1239:                ); // NOI18N
1240:
1241:                contentForegroundColor = new Color(
1242:                        getIntFromBundle("INT_WizardForegroundRed"), // NOI18N
1243:                        getIntFromBundle("INT_WizardForegroundGreen"), // NOI18N
1244:                        getIntFromBundle("INT_WizardForegroundBlue") // NOI18N
1245:                ); // NOI18N
1246:                imageAlignment = bundle
1247:                        .getString("STRING_WizardImageAlignment"); //NOI18N
1248:            }
1249:
1250:            /** Overrides superclass method. Adds reseting of wizard
1251:             * for <code>CLOSED_OPTION</code>. */
1252:            @Override
1253:            public void setValue(Object value) {
1254:                setValueOpen(value, data);
1255:            }
1256:
1257:            private <A> void setValueOpen(Object value,
1258:                    SettingsAndIterator<A> data) {
1259:                Object convertedValue = backConvertOption(value);
1260:                // set new value w/o fire PROP_VALUE change
1261:                Object oldValue = getValue();
1262:                setValueWithoutPCH(convertedValue);
1263:
1264:                // #17360: Reset wizard on CLOSED_OPTION too.
1265:                if (CLOSED_OPTION.equals(convertedValue)) {
1266:                    try {
1267:                        resetWizard();
1268:                    } catch (RuntimeException x) {
1269:                        // notify to log
1270:                        err.log(Level.INFO, null, x);
1271:                    }
1272:                } else if (FINISH_OPTION.equals(convertedValue)
1273:                        || NEXT_OPTION.equals(convertedValue)) {
1274:                    //Bugfix #25820: make sure that storeSettings
1275:                    //is called before propertyChange.
1276:                    if (data.current != null) {
1277:                        data.current.storeSettings(data.getSettings(this ));
1278:                    }
1279:                }
1280:
1281:                // notify listeners about PROP_VALUE change
1282:                firePropertyChange(PROP_VALUE, oldValue, convertedValue);
1283:            }
1284:
1285:            /** Resets wizard when after closed/cancelled/finished the wizard dialog. */
1286:            private void resetWizard() {
1287:                resetWizardOpen(data);
1288:            }
1289:
1290:            private <A> void resetWizardOpen(SettingsAndIterator<A> data) {
1291:                if (data.current != null) {
1292:                    data.current.storeSettings(data.getSettings(this ));
1293:                    data.current.removeChangeListener(weakChangeListener);
1294:                    data.current = null;
1295:
1296:                    if (wizardPanel != null) {
1297:                        wizardPanel.resetPreferredSize();
1298:                    }
1299:                }
1300:
1301:                callUninitialize();
1302:
1303:                // detach the change listener at the end of wizard
1304:                data.getIterator(this ).removeChangeListener(weakChangeListener);
1305:            }
1306:
1307:            private int getIntFromBundle(String key) {
1308:                return Integer.parseInt(bundle.getString(key));
1309:            }
1310:
1311:            private static Image getDefaultImage() {
1312:                return Utilities.loadImage(
1313:                        "org/netbeans/modules/dialogs/defaultWizard.gif", true);
1314:            }
1315:
1316:            private void updateButtonAccessibleDescription() {
1317:                String stepName = ((contentData != null)
1318:                        && (contentSelectedIndex > 0) && ((contentSelectedIndex - 1) < contentData.length)) ? contentData[contentSelectedIndex - 1]
1319:                        : ""; // NOI18N
1320:                previousButton.getAccessibleContext().setAccessibleDescription(
1321:                        NbBundle.getMessage(WizardDescriptor.class,
1322:                                "ACSD_PREVIOUS", new Integer(
1323:                                        contentSelectedIndex), stepName));
1324:
1325:                stepName = ((contentData != null)
1326:                        && (contentSelectedIndex < (contentData.length - 1)) && ((contentSelectedIndex + 1) >= 0)) ? contentData[contentSelectedIndex + 1]
1327:                        : ""; // NOI18N
1328:                nextButton.getAccessibleContext().setAccessibleDescription(
1329:                        NbBundle.getMessage(WizardDescriptor.class,
1330:                                "ACSD_NEXT", new Integer(
1331:                                        contentSelectedIndex + 2), stepName));
1332:            }
1333:
1334:            private void lazyValidate(final WizardDescriptor.Panel panel,
1335:                    final Runnable onValidPerformer) {
1336:
1337:                Runnable validationPeformer = new Runnable() {
1338:                    public void run() {
1339:
1340:                        err.log(Level.FINE, "validationPeformer entry."); // NOI18N
1341:                        ValidatingPanel v = (ValidatingPanel) panel;
1342:
1343:                        try {
1344:                            // try validation current panel
1345:                            v.validate();
1346:                            validationRuns = false;
1347:
1348:                            // validation succesfull
1349:                            if (SwingUtilities.isEventDispatchThread()) {
1350:                                err
1351:                                        .log(Level.FINE,
1352:                                                "Runs onValidPerformer directly in EDT."); // NOI18N
1353:                                onValidPerformer.run();
1354:                            } else {
1355:                                err.log(Level.FINE,
1356:                                        "invokeLater onValidPerformer."); // NOI18N
1357:                                SwingUtilities.invokeLater(new Runnable() {
1358:                                    public void run() {
1359:                                        err
1360:                                                .log(Level.FINE,
1361:                                                        "Runs onValidPerformer from invokeLater."); // NOI18N
1362:                                        onValidPerformer.run();
1363:                                    }
1364:                                });
1365:                            }
1366:                        } catch (WizardValidationException wve) {
1367:                            validationRuns = false;
1368:                            updateState();
1369:
1370:                            // cannot continue, notify user
1371:                            if (wizardPanel != null) {
1372:                                wizardPanel.setErrorMessage(wve
1373:                                        .getLocalizedMessage(), Boolean.FALSE);
1374:                            }
1375:
1376:                            // focus source of this problem
1377:                            final JComponent comp = wve.getSource();
1378:                            if (comp != null && comp.isFocusable()) {
1379:                                comp.requestFocus();
1380:                            }
1381:                        }
1382:
1383:                    }
1384:                };
1385:
1386:                if (panel instanceof  AsynchronousValidatingPanel) {
1387:                    AsynchronousValidatingPanel p = (AsynchronousValidatingPanel) panel;
1388:                    validationRuns = true; // disable Next> Finish buttons
1389:                    p.prepareValidation();
1390:                    err
1391:                            .log(Level.FINE,
1392:                                    "Do ASYNCHRONOUS_JOBS_RP.post(validationPeformer)."); // NOI18N
1393:                    updateStateWithFeedback();
1394:                    backgroundValidationTask = ASYNCHRONOUS_JOBS_RP
1395:                            .post(validationPeformer);
1396:                } else if (panel instanceof  ValidatingPanel) {
1397:                    validationRuns = true;
1398:                    err.log(Level.FINE, "Runs validationPeformer."); // NOI18N
1399:                    validationPeformer.run();
1400:                } else {
1401:                    err.log(Level.FINE, "Runs onValidPerformer."); // NOI18N
1402:                    onValidPerformer.run();
1403:                }
1404:
1405:            }
1406:
1407:            // helper methods which call to InstantiatingIterator
1408:            private void callInitialize() {
1409:                assert data.getIterator(this ) != null;
1410:
1411:                if (data.getIterator(this ) instanceof  InstantiatingIterator) {
1412:                    ((InstantiatingIterator) data.getIterator(this ))
1413:                            .initialize(this );
1414:                }
1415:
1416:                newObjects = Collections.EMPTY_SET;
1417:            }
1418:
1419:            private void callUninitialize() {
1420:                assert data.getIterator(this ) != null;
1421:
1422:                if (data.getIterator(this ) instanceof  InstantiatingIterator) {
1423:                    ((InstantiatingIterator) data.getIterator(this ))
1424:                            .uninitialize(this );
1425:                }
1426:            }
1427:
1428:            private void callInstantiate() throws IOException {
1429:                callInstantiateOpen(data);
1430:            }
1431:
1432:            private <A> void callInstantiateOpen(SettingsAndIterator<A> data)
1433:                    throws IOException {
1434:                Iterator<A> panels = data.getIterator(this );
1435:
1436:                assert panels != null;
1437:
1438:                err
1439:                        .log(
1440:                                Level.FINE,
1441:                                "Is AsynchronousInstantiatingIterator? "
1442:                                        + (panels instanceof  AsynchronousInstantiatingIterator));
1443:                err.log(Level.FINE, "Is ProgressInstantiatingIterator? "
1444:                        + (panels instanceof  ProgressInstantiatingIterator));
1445:                if (panels instanceof  ProgressInstantiatingIterator) {
1446:                    handle = ProgressHandleFactory
1447:                            .createHandle(PROGRESS_BAR_DISPLAY_NAME);
1448:
1449:                    JComponent progressComp = ProgressHandleFactory
1450:                            .createProgressComponent(handle);
1451:                    if (wizardPanel != null) {
1452:                        wizardPanel.setProgressComponent(progressComp,
1453:                                ProgressHandleFactory
1454:                                        .createDetailLabelComponent(handle));
1455:                    }
1456:
1457:                    err.log(Level.FINE,
1458:                            "Show progressPanel controlled by iterator later.");
1459:                } else if (panels instanceof  AsynchronousInstantiatingIterator) {
1460:                    handle = ProgressHandleFactory
1461:                            .createHandle(PROGRESS_BAR_DISPLAY_NAME);
1462:
1463:                    JComponent progressComp = ProgressHandleFactory
1464:                            .createProgressComponent(handle);
1465:                    if (wizardPanel != null) {
1466:                        wizardPanel.setProgressComponent(progressComp,
1467:                                ProgressHandleFactory
1468:                                        .createMainLabelComponent(handle));
1469:                    }
1470:
1471:                    handle.start();
1472:                    err.log(Level.FINE, "Show progressPanel later.");
1473:                }
1474:
1475:                // bugfix #44444, force store settings before do instantiate new objects
1476:                panels.current().storeSettings(data.getSettings(this ));
1477:
1478:                if (panels instanceof  InstantiatingIterator) {
1479:                    showWaitCursor();
1480:
1481:                    try {
1482:                        assert !(panels instanceof  AsynchronousInstantiatingIterator)
1483:                                || !SwingUtilities.isEventDispatchThread() : "Cannot invoked within EDT if AsynchronousInstantiatingIterator!";
1484:
1485:                        if (panels instanceof  ProgressInstantiatingIterator) {
1486:                            assert handle != null : "ProgressHandle must be not null.";
1487:                            err.log(Level.FINE,
1488:                                    "Calls instantiate(ProgressHandle) on iterator: "
1489:                                            + panels.getClass().getName());
1490:                            newObjects = ((ProgressInstantiatingIterator) panels)
1491:                                    .instantiate(handle);
1492:                        } else {
1493:                            err.log(Level.FINE,
1494:                                    "Calls instantiate() on iterator: "
1495:                                            + panels.getClass().getName());
1496:                            newObjects = ((InstantiatingIterator) panels)
1497:                                    .instantiate();
1498:                        }
1499:                    } finally {
1500:
1501:                        // set cursor back to normal
1502:                        showNormalCursor();
1503:
1504:                    }
1505:                }
1506:            }
1507:
1508:            private static Font doDeriveFont(Font original, int style) {
1509:                if (Utilities.isMac()) {
1510:                    // don't use deriveFont() - see #49973 for details
1511:                    return new Font(original.getName(), style, original
1512:                            .getSize());
1513:                }
1514:
1515:                return original.deriveFont(style);
1516:            }
1517:
1518:            // support methods for xtesting
1519:            final void doNextClick() {
1520:                if (nextButton.isEnabled()) {
1521:                    nextButton.doClick();
1522:                }
1523:            }
1524:
1525:            final void doPreviousClick() {
1526:                if (previousButton.isEnabled()) {
1527:                    previousButton.doClick();
1528:                }
1529:            }
1530:
1531:            final void doFinishClick() {
1532:                if (finishButton.isEnabled()) {
1533:                    finishButton.doClick();
1534:                }
1535:            }
1536:
1537:            final void doCancelClick() {
1538:                if (cancelButton.isEnabled()) {
1539:                    cancelButton.doClick();
1540:                }
1541:            }
1542:
1543:            // helper method, might be removed from code
1544:            // returns false if Next button is disabled
1545:            final boolean isNextEnabled() {
1546:                return nextButton.isEnabled();
1547:            }
1548:
1549:            // helper method, might be removed from code
1550:            // returns false if Finish button is disabled
1551:            final boolean isFinishEnabled() {
1552:                return finishButton.isEnabled();
1553:            }
1554:
1555:            /** Iterator on the sequence of panels.
1556:             * @see WizardDescriptor.Panel
1557:             */
1558:            public interface Iterator<Data> {
1559:                /** Get the current panel.
1560:                 * @return the panel
1561:                 */
1562:                public Panel<Data> current();
1563:
1564:                /** Get the name of the current panel.
1565:                 * @return the name
1566:                 */
1567:                public String name();
1568:
1569:                /** Test whether there is a next panel.
1570:                 * @return <code>true</code> if so
1571:                 */
1572:                public boolean hasNext();
1573:
1574:                /** Test whether there is a previous panel.
1575:                 * @return <code>true</code> if so
1576:                 */
1577:                public boolean hasPrevious();
1578:
1579:                /** Move to the next panel.
1580:                 * I.e. increment its index, need not actually change any GUI itself.
1581:                 * @exception NoSuchElementException if the panel does not exist
1582:                 */
1583:                public void nextPanel();
1584:
1585:                /** Move to the previous panel.
1586:                 * I.e. decrement its index, need not actually change any GUI itself.
1587:                 * @exception NoSuchElementException if the panel does not exist
1588:                 */
1589:                public void previousPanel();
1590:
1591:                /** Add a listener to changes of the current panel.
1592:                 * The listener is notified when the possibility to move forward/backward changes.
1593:                 * @param l the listener to add
1594:                 */
1595:                public void addChangeListener(ChangeListener l);
1596:
1597:                /** Remove a listener to changes of the current panel.
1598:                 * @param l the listener to remove
1599:                 */
1600:                public void removeChangeListener(ChangeListener l);
1601:            }
1602:
1603:            /** One wizard panel with a component on it.
1604:             *
1605:             * For good performance, implementation of this interface should be as
1606:             * lightweight as possible. Defer creation and initialization of
1607:             * UI component of wizard panel into {@link #getComponent} method.
1608:             *
1609:             * Please see complete guide at http://performance.netbeans.org/howto/dialogs/wizard-panels.html
1610:             */
1611:            public interface Panel<Data> {
1612:                /** Get the component displayed in this panel.
1613:                 *
1614:                 * Note; method can be called from any thread, but not concurrently
1615:                 * with other methods of this interface. Please see complete guide at
1616:                 * http://performance.netbeans.org/howto/dialogs/wizard-panels.html for
1617:                 * correct implementation.
1618:                 *
1619:                 * @return the UI component of this wizard panel
1620:                 */
1621:                public java.awt.Component getComponent();
1622:
1623:                /** Help for this panel.
1624:                 * When the panel is active, this is used as the help for the wizard dialog.
1625:                 * @return the help or <code>null</code> if no help is supplied
1626:                 */
1627:                public HelpCtx getHelp();
1628:
1629:                /** Provides the wizard panel with the current data--either
1630:                 * the default data or already-modified settings, if the user used the previous and/or next buttons.
1631:                 * This method can be called multiple times on one instance of <code>WizardDescriptor.Panel</code>.
1632:                 * <p>The settings object is originally supplied to {@link WizardDescriptor#WizardDescriptor(WizardDescriptor.Iterator,Object)}.
1633:                 * In the case of a <code>TemplateWizard.Iterator</code> panel, the object is
1634:                 * in fact the <code>TemplateWizard</code>.
1635:                 * @param settings the object representing wizard panel state
1636:                 * @exception IllegalStateException if the the data provided
1637:                 * by the wizard are not valid.
1638:                 */
1639:                public void readSettings(Data settings);
1640:
1641:                /** Provides the wizard panel with the opportunity to update the
1642:                 * settings with its current customized state.
1643:                 * Rather than updating its settings with every change in the GUI, it should collect them,
1644:                 * and then only save them when requested to by this method.
1645:                 * Also, the original settings passed to {@link #readSettings} should not be modified (mutated);
1646:                 * rather, the object passed in here should be mutated according to the collected changes,
1647:                 * in case it is a copy.
1648:                 * This method can be called multiple times on one instance of <code>WizardDescriptor.Panel</code>.
1649:                 * <p>The settings object is originally supplied to {@link WizardDescriptor#WizardDescriptor(WizardDescriptor.Iterator,Object)}.
1650:                 * In the case of a <code>TemplateWizard.Iterator</code> panel, the object is
1651:                 * in fact the <code>TemplateWizard</code>.
1652:                 * @param settings the object representing wizard panel state
1653:                 */
1654:                public void storeSettings(Data settings);
1655:
1656:                /** Test whether the panel is finished and it is safe to proceed to the next one.
1657:                 * If the panel is valid, the "Next" (or "Finish") button will be enabled.
1658:                 * <p><strong>Tip:</strong> if your panel is actually the component itself
1659:                 * (so {@link #getComponent} returns <code>this</code>), be sure to specifically
1660:                 * override this method, as the unrelated implementation in {@link java.awt.Component#isValid}
1661:                 * if not overridden could cause your wizard to behave erratically.
1662:                 * @return <code>true</code> if the user has entered satisfactory information
1663:                 */
1664:                public boolean isValid();
1665:
1666:                /** Add a listener to changes of the panel's validity.
1667:                 * @param l the listener to add
1668:                 * @see #isValid
1669:                 */
1670:                public void addChangeListener(ChangeListener l);
1671:
1672:                /** Remove a listener to changes of the panel's validity.
1673:                 * @param l the listener to remove
1674:                 */
1675:                public void removeChangeListener(ChangeListener l);
1676:            }
1677:
1678:            /** A special interface for panels in middle of the
1679:             * iterators path that would like to have the finish button
1680:             * enabled. So both Next and Finish are enabled on panel
1681:             * implementing this interface.
1682:             * @deprecated 4.28 Use FinishablePanel instead.
1683:             */
1684:            @Deprecated
1685:            public interface FinishPanel<Data> extends Panel<Data> {
1686:            }
1687:
1688:            /** A special interface for panels that need to do additional
1689:             * validation when Next or Finish button is clicked.
1690:             * @since 4.28
1691:             */
1692:            public interface ValidatingPanel<Data> extends Panel<Data> {
1693:                /**
1694:                 * Is called when Next of Finish buttons are clicked and
1695:                 * allows deeper check to find out that panel is in valid
1696:                 * state and it is ok to leave it.
1697:                 *
1698:                 * @throws WizardValidationException when validation fails
1699:                 * @since 4.28
1700:                 */
1701:                public void validate() throws WizardValidationException;
1702:            }
1703:
1704:            /**
1705:             * A special interface for panels that need to do additional
1706:             * asynchronous validation when Next or Finish button is clicked.
1707:             *
1708:             * <p>During backround validation is Next or Finish button
1709:             * disabled. On validation success wizard automatically
1710:             * progress to next panel or finishes.
1711:             *
1712:             * <p>During backround validation Cancel button is hooked
1713:             * to signal the validation thread using interrupt().
1714:             *
1715:             * @since 6.2 (16 May 2005)
1716:             */
1717:            public interface AsynchronousValidatingPanel<Data> extends
1718:                    ValidatingPanel<Data> {
1719:
1720:                /**
1721:                 * Called synchronously from UI thread when Next
1722:                 * of Finish buttons clicked. It allows to lock user
1723:                 * input to assure official data for background validation.
1724:                 */
1725:                public void prepareValidation();
1726:
1727:                /**
1728:                 * Is called in separate thread when Next of Finish buttons
1729:                 * are clicked and allows deeper check to find out that panel
1730:                 * is in valid state and it is ok to leave it.
1731:                 *
1732:                 * @throws WizardValidationException when validation fails
1733:                 */
1734:                public void validate() throws WizardValidationException;
1735:            }
1736:
1737:            /** A special interface for panel that needs to dynamically enabled
1738:             * Finish button.
1739:             * @since 4.28
1740:             */
1741:            public interface FinishablePanel<Data> extends Panel<Data> {
1742:                /** Specify if this panel would enable Finish button. Finish button is
1743:                 * enabled if and only if isValid() returns true and isFinishPanel()
1744:                 * returns true.
1745:                 *
1746:                 * @return Finish button could be enabled
1747:                 * @since 4.28
1748:                 */
1749:                boolean isFinishPanel();
1750:            }
1751:
1752:            /**
1753:             * Iterator for a wizard that needs to somehow instantiate new objects.
1754:             * (This interface can replace
1755:             * <a href="@OPENIDE/LOADERS@/org/openide/loaders/TemplateWizard.Iterator.html"><code>TemplateWizard.Iterator</code></a>
1756:             * in a template's declaration.)
1757:             * @since org.openide/1 4.33
1758:             */
1759:            public interface InstantiatingIterator<Data> extends Iterator<Data> {
1760:                /** Returns set of instantiated objects. If instantiation fails then wizard remains open to enable correct values.
1761:                 *
1762:                 * @throws IOException
1763:                 * @return a set of objects created (the exact type is at the discretion of the caller)
1764:                 */
1765:                public Set/*<?>*/instantiate() throws IOException;
1766:
1767:                /** Initializes this iterator, called from WizardDescriptor's constructor.
1768:                 *
1769:                 * @param wizard wizard's descriptor
1770:                 */
1771:                public void initialize(WizardDescriptor wizard);
1772:
1773:                /** Uninitializes this iterator, called when the wizard is being
1774:                 * closed, no matter what closing option invoked.
1775:                 *
1776:                 * @param wizard wizard's descriptor
1777:                 */
1778:                public void uninitialize(WizardDescriptor wizard);
1779:            }
1780:
1781:            /**
1782:             * Iterator for a wizard that needs to somehow instantiate new objects outside ATW queue.
1783:             * (This interface can replace
1784:             * <a href="@OPENIDE/LOADERS@/org/openide/loaders/TemplateWizard.Iterator.html"><code>TemplateWizard.Iterator</code></a>
1785:             * in a template's declaration.)
1786:             * @since org.openide/1 6.5
1787:             */
1788:            public interface AsynchronousInstantiatingIterator<Data> extends
1789:                    InstantiatingIterator<Data> {
1790:
1791:                /**
1792:                 * Is called in separate thread when the Finish button
1793:                 * are clicked and allows implement asynchronous
1794:                 * instantating of newly created objects.
1795:                 *
1796:                 * @throws IOException when instantiate fails
1797:                 * @return a set of objects created (the exact type is at the discretion of the caller)
1798:                 */
1799:                public Set/*<?>*/instantiate() throws IOException;
1800:
1801:            }
1802:
1803:            /**
1804:             * Iterator for a wizard that wants to notify users while instantiate is running by a progress bar.
1805:             * The method <code>instantiate</code> is called outside ATW queue.
1806:             * (This interface can replace
1807:             * <a href="@OPENIDE/LOADERS@/org/openide/loaders/TemplateWizard.Iterator.html"><code>TemplateWizard.Iterator</code></a>
1808:             * in a template's declaration.)
1809:             * @since org.openide.dialogs 7.1
1810:             */
1811:            public interface ProgressInstantiatingIterator<Data> extends
1812:                    AsynchronousInstantiatingIterator<Data> {
1813:
1814:                /**
1815:                 * Is called in separate thread when the Finish button
1816:                 * are clicked and allows implement asynchronous instantating of newly created objects.
1817:                 * While instantiating users are notified by progress bar in wizard's panel. Notfication will
1818:                 * be visualized by a progress bar.
1819:                 * Note: The <code>ProgressHandle</code> is not started, need to start it and report progress by
1820:                 * messages in the <code>progress()</code> method.
1821:                 * 
1822:                 * @param handle progress bar handle
1823:                 * @throws IOException when instantiate fails
1824:                 * @return a set of objects created (the exact type is at the discretion of the caller)
1825:                 */
1826:                public Set/*<?>*/instantiate(ProgressHandle handle)
1827:                        throws IOException;
1828:
1829:            }
1830:
1831:            /** Special iterator that works on an array of <code>Panel</code>s.
1832:             */
1833:            public static class ArrayIterator<Data> extends Object implements 
1834:                    Iterator<Data> {
1835:                /** Array of items.
1836:                 */
1837:                private Panel<Data>[] panels;
1838:
1839:                /** Index into the array
1840:                 */
1841:                private int index;
1842:
1843:                /* Default constructor. It's here to allow subclasses to
1844:                 * be serializable easily. Panel initialization is done
1845:                 * through initializePanels() protected method. */
1846:                public ArrayIterator() {
1847:                    panels = initializePanels();
1848:                    index = 0;
1849:                }
1850:
1851:                /** Construct an iterator.
1852:                 * @param array the list of panels to use
1853:                 */
1854:                public ArrayIterator(Panel<Data>[] array) {
1855:                    panels = array;
1856:                    index = 0;
1857:                }
1858:
1859:                /**
1860:                 * Construct an iterator.
1861:                 * @param panels the list of panels to use
1862:                 * @since org.openide.dialogs 7.5
1863:                 */
1864:                @SuppressWarnings("unchecked")
1865:                // exists so that other code does not have to do it
1866:                public ArrayIterator(List<Panel<Data>> panels) {
1867:                    this .panels = panels.toArray(new Panel[panels.size()]);
1868:                    index = 0;
1869:                }
1870:
1871:                /** Allows subclasses to initialize their arrays of panels when
1872:                 * constructed using default constructor.
1873:                 * (for example during deserialization.
1874:                 * Default implementation returns empty array. */
1875:                @SuppressWarnings("unchecked")
1876:                protected Panel<Data>[] initializePanels() {
1877:                    return new Panel[0];
1878:                }
1879:
1880:                /* The current panel.
1881:                 */
1882:                public Panel<Data> current() {
1883:                    return panels[index];
1884:                }
1885:
1886:                /* Current name of the panel */
1887:                public String name() {
1888:                    return NbBundle.getMessage(WizardDescriptor.class,
1889:                            "CTL_ArrayIteratorName", index + 1, panels.length);
1890:                }
1891:
1892:                /* Is there a next panel?
1893:                 * @return true if so
1894:                 */
1895:                public boolean hasNext() {
1896:                    return index < (panels.length - 1);
1897:                }
1898:
1899:                /* Is there a previous panel?
1900:                 * @return true if so
1901:                 */
1902:                public boolean hasPrevious() {
1903:                    return index > 0;
1904:                }
1905:
1906:                /* Moves to the next panel.
1907:                 * @exception NoSuchElementException if the panel does not exist
1908:                 */
1909:                public synchronized void nextPanel() {
1910:                    if ((index + 1) == panels.length) {
1911:                        throw new java.util.NoSuchElementException();
1912:                    }
1913:
1914:                    index++;
1915:                }
1916:
1917:                /* Moves to previous panel.
1918:                 * @exception NoSuchElementException if the panel does not exist
1919:                 */
1920:                public synchronized void previousPanel() {
1921:                    if (index == 0) {
1922:                        throw new java.util.NoSuchElementException();
1923:                    }
1924:
1925:                    index--;
1926:                }
1927:
1928:                /* Ignores the listener, there are no changes in order of panels.
1929:                 */
1930:                public void addChangeListener(ChangeListener l) {
1931:                }
1932:
1933:                /* Ignored.
1934:                 */
1935:                public void removeChangeListener(ChangeListener l) {
1936:                }
1937:
1938:                /** Resets this iterator to initial state.
1939:                 * Called by subclasses when they need re-initialization of the iterator.
1940:                 */
1941:                protected void reset() {
1942:                    index = 0;
1943:                }
1944:            }
1945:
1946:            /** Listener to changes in the iterator and panels.
1947:             */
1948:            private final class Listener implements  ChangeListener,
1949:                    ActionListener {
1950:                Listener() {
1951:                }
1952:
1953:                /** Change in the observed objects */
1954:                public void stateChanged(ChangeEvent ev) {
1955:                    updateState();
1956:                }
1957:
1958:                /** Action listener */
1959:                public void actionPerformed(ActionEvent ev) {
1960:                    final Iterator<?> panels = data
1961:                            .getIterator(WizardDescriptor.this );
1962:                    if (wizardPanel != null) {
1963:                        wizardPanel.setErrorMessage(" ", null); //NOI18N
1964:                    }
1965:
1966:                    Object src = ev.getSource();
1967:                    err
1968:                            .log(Level.FINE, "actionPerformed entry. Source: "
1969:                                    + src); // NOI18N
1970:                    if (src == nextButton) {
1971:                        final Dimension previousSize = panels.current()
1972:                                .getComponent().getSize();
1973:                        Runnable onValidPerformer = new Runnable() {
1974:
1975:                            public void run() {
1976:                                err
1977:                                        .log(Level.FINE,
1978:                                                "onValidPerformer on next button entry.");
1979:                                panels.nextPanel();
1980:                                try {
1981:                                    // change UI to show next step, show wait cursor during
1982:                                    // the change
1983:                                    goToNextStep(previousSize);
1984:                                } catch (IllegalStateException ise) {
1985:                                    panels.previousPanel();
1986:                                    String msg = ise.getMessage();
1987:                                    if (msg != null) {
1988:                                        // this is only for backward compatitility
1989:                                        DialogDisplayer.getDefault().notify(
1990:                                                new NotifyDescriptor.Message(
1991:                                                        msg));
1992:                                    } else {
1993:                                        // this should be used (it checks for exception
1994:                                        // annotations and severity)
1995:                                        Exceptions.printStackTrace(ise);
1996:                                    }
1997:                                    updateState();
1998:                                }
1999:                                err
2000:                                        .log(Level.FINE,
2001:                                                "onValidPerformer on next button exit.");
2002:                            }
2003:                        };
2004:                        lazyValidate(panels.current(), onValidPerformer);
2005:                    }
2006:
2007:                    if (ev.getSource() == previousButton) {
2008:                        panels.previousPanel();
2009:
2010:                        // show wait cursor when updating previous button
2011:                        updateStateWithFeedback();
2012:                    }
2013:
2014:                    if (ev.getSource() == finishButton) {
2015:                        Runnable onValidPerformer = new Runnable() {
2016:                            public void run() {
2017:                                err
2018:                                        .log(Level.FINE,
2019:                                                "onValidPerformer on finish button entry."); // NOI18N
2020:
2021:                                // disable all buttons to indicate that instantiate runs
2022:                                previousButton.setEnabled(false);
2023:                                nextButton.setEnabled(false);
2024:                                finishButton.setEnabled(false);
2025:                                cancelButton.setEnabled(false);
2026:
2027:                                Runnable performFinish = new Runnable() {
2028:                                    public void run() {
2029:                                        err.log(Level.FINE,
2030:                                                "performFinish entry."); // NOI18N
2031:                                        Object oldValue = getValue();
2032:
2033:                                        // do instantiate
2034:                                        try {
2035:                                            callInstantiate();
2036:                                            setValueWithoutPCH(OK_OPTION);
2037:                                            resetWizard();
2038:                                        } catch (IOException ioe) {
2039:                                            // notify to log
2040:                                            err.log(Level.INFO, null, ioe);
2041:
2042:                                            setValueWithoutPCH(NEXT_OPTION);
2043:                                            updateStateWithFeedback();
2044:
2045:                                            // notify user by the wizard's status line
2046:                                            putProperty(PROP_ERROR_MESSAGE, ioe
2047:                                                    .getLocalizedMessage());
2048:
2049:                                            // if validation failed => cannot move to next panel
2050:                                            return;
2051:                                        } catch (RuntimeException x) {
2052:                                            // notify to log
2053:                                            err.log(Level.WARNING, null, x);
2054:
2055:                                            setValueWithoutPCH(NEXT_OPTION);
2056:                                            updateStateWithFeedback();
2057:
2058:                                            // notify user by the wizard's status line
2059:                                            putProperty(PROP_ERROR_MESSAGE, x
2060:                                                    .getLocalizedMessage());
2061:
2062:                                            // if validation failed => cannot move to next panel
2063:                                            return;
2064:                                        }
2065:                                        firePropertyChange(PROP_VALUE,
2066:                                                oldValue, OK_OPTION);
2067:
2068:                                        SwingUtilities
2069:                                                .invokeLater(new Runnable() {
2070:                                                    public void run() {
2071:                                                        // all is OK
2072:                                                        // close wizrad
2073:                                                        err
2074:                                                                .log(
2075:                                                                        Level.FINE,
2076:                                                                        "WD.finishOption.fireActionPerformed()");
2077:                                                        finishOption
2078:                                                                .fireActionPerformed();
2079:                                                        err
2080:                                                                .log(
2081:                                                                        Level.FINE,
2082:                                                                        "Set value to OK_OPTION.");
2083:                                                        setValue(OK_OPTION);
2084:                                                    }
2085:                                                });
2086:                                        err.log(Level.FINE,
2087:                                                "performFinish exit."); // NOI18N
2088:                                    }
2089:                                };
2090:
2091:                                if (panels instanceof  AsynchronousInstantiatingIterator) {
2092:                                    err
2093:                                            .log(Level.FINE,
2094:                                                    "Do ASYNCHRONOUS_JOBS_RP.post(performFinish)."); // NOI18N
2095:                                    ASYNCHRONOUS_JOBS_RP.post(performFinish);
2096:                                } else {
2097:                                    err.log(Level.FINE, "Run performFinish."); // NOI18N
2098:                                    performFinish.run();
2099:                                }
2100:
2101:                                err
2102:                                        .log(Level.FINE,
2103:                                                "onValidPerformer on finish button exit."); // NOI18N
2104:
2105:                            }
2106:                        };
2107:                        lazyValidate(panels.current(), onValidPerformer);
2108:                    }
2109:
2110:                    if (ev.getSource() == cancelButton) {
2111:                        if (backgroundValidationTask != null) {
2112:                            backgroundValidationTask.cancel();
2113:                        }
2114:                        Object oldValue = getValue();
2115:                        setValueWithoutPCH(CANCEL_OPTION);
2116:
2117:                        if (Arrays.asList(getClosingOptions()).contains(
2118:                                cancelButton)) {
2119:                            try {
2120:                                resetWizard();
2121:                            } catch (RuntimeException x) {
2122:                                // notify to log
2123:                                err.log(Level.INFO, null, x);
2124:                            }
2125:
2126:                        }
2127:
2128:                        firePropertyChange(PROP_VALUE, oldValue, CANCEL_OPTION);
2129:                    }
2130:                }
2131:            }
2132:
2133:            /** Listenes on a users client property changes
2134:             */
2135:            private class PropL implements  PropertyChangeListener {
2136:                PropL() {
2137:                }
2138:
2139:                /** Accepts client property changes of user component */
2140:                public void propertyChange(PropertyChangeEvent e) {
2141:                    if (wizardPanel == null) {
2142:                        return;
2143:                    }
2144:
2145:                    String propName = e.getPropertyName();
2146:                    setPanelProperties((JComponent) wizardPanel
2147:                            .getRightComponent());
2148:
2149:                    if (PROP_CONTENT_DATA.equals(propName)) {
2150:                        wizardPanel.setContent(contentData);
2151:                        updateButtonAccessibleDescription();
2152:                    } else if (PROP_CONTENT_SELECTED_INDEX.equals(propName)) {
2153:                        wizardPanel.setSelectedIndex(contentSelectedIndex);
2154:                        updateButtonAccessibleDescription();
2155:                    } else if (PROP_CONTENT_BACK_COLOR.equals(propName)) {
2156:                        wizardPanel.setContentBackColor(contentBackColor);
2157:                    } else if (PROP_CONTENT_FOREGROUND_COLOR.equals(propName)) {
2158:                        wizardPanel
2159:                                .setContentForegroundColor(contentForegroundColor);
2160:                    } else if (PROP_IMAGE.equals(propName)) {
2161:                        wizardPanel.setImage(image);
2162:                    } else if (PROP_IMAGE_ALIGNMENT.equals(propName)) {
2163:                        wizardPanel.setImageAlignment(imageAlignment);
2164:                    } else if (PROP_HELP_URL.equals(propName)) {
2165:                        wizardPanel.setHelpURL(helpURL);
2166:                    }
2167:                }
2168:            }
2169:
2170:            // end of calling to InstantiatingIterator
2171:
2172:            /** Panel which paints image as its background.
2173:             */
2174:            private static class ImagedPanel extends JComponent implements 
2175:                    Accessible, Runnable {
2176:                /** background image */
2177:                Image image;
2178:
2179:                /** helper variables for passing image between threads and painting
2180:                 * methods */
2181:                Image tempImage;
2182:
2183:                /** helper variables for passing image between threads and painting
2184:                 * methods */
2185:                Image image2Load;
2186:
2187:                /** true if default image is used */
2188:                boolean isDefault = false;
2189:
2190:                /** true if loading of image is in progress, false otherwise */
2191:                boolean loadPending = false;
2192:                boolean north = true;
2193:
2194:                /** sync lock for image variables access */
2195:                private final Object IMAGE_LOCK = new Object();
2196:
2197:                /** Constrcuts panel with given image on background.
2198:                 * @param im background image, null means default image
2199:                 */
2200:                public ImagedPanel(Image im) {
2201:                    setImage(im);
2202:                    setLayout(new BorderLayout());
2203:                    setOpaque(true);
2204:                }
2205:
2206:                /** Overriden to paint backround image */
2207:                @Override
2208:                protected void paintComponent(Graphics graphics) {
2209:                    graphics.setColor(getBackground());
2210:                    graphics.fillRect(0, 0, getWidth(), getHeight());
2211:
2212:                    if (image != null) {
2213:                        graphics.drawImage(image, 0, north ? 0
2214:                                : (getHeight() - image.getHeight(null)), this );
2215:                    } else if (image2Load != null) {
2216:                        loadImageInBackground(image2Load);
2217:                        image2Load = null;
2218:                    }
2219:                }
2220:
2221:                public void setImageAlignment(String align) {
2222:                    north = "North".equals(align); // NOI18N
2223:                }
2224:
2225:                /** Sets background image for this component. Image will be loaded
2226:                 * asynchronously if not loaded yet. Null means default image.
2227:                 */
2228:                public void setImage(Image im) {
2229:                    if (im != null) {
2230:                        loadImage(im);
2231:                        isDefault = false;
2232:
2233:                        return;
2234:                    }
2235:
2236:                    if (!isDefault) {
2237:                        loadImage(getDefaultImage());
2238:                        isDefault = true;
2239:                    }
2240:                }
2241:
2242:                private void loadImage(Image im) {
2243:                    // check image and just set variable if fully loaded already
2244:                    MediaTracker mt = new MediaTracker(this );
2245:                    mt.addImage(im, 0);
2246:
2247:                    if (mt.checkID(0)) {
2248:                        image = im;
2249:
2250:                        if (isShowing()) {
2251:                            repaint();
2252:                        }
2253:
2254:                        return;
2255:                    }
2256:
2257:                    // start loading in background or just mark that loading should
2258:                    // start when paint is invoked
2259:                    if (isShowing()) {
2260:                        loadImageInBackground(im);
2261:                    } else {
2262:                        synchronized (IMAGE_LOCK) {
2263:                            image = null;
2264:                        }
2265:
2266:                        image2Load = im;
2267:                    }
2268:                }
2269:
2270:                private void loadImageInBackground(Image image) {
2271:                    synchronized (IMAGE_LOCK) {
2272:                        tempImage = image;
2273:
2274:                        // coalesce with previous task if hasn't really started yet
2275:                        if (loadPending) {
2276:                            return;
2277:                        }
2278:
2279:                        loadPending = true;
2280:                    }
2281:
2282:                    // 30ms is safety time to ensure code will run asynchronously
2283:                    RequestProcessor.getDefault().post(this , 30);
2284:                }
2285:
2286:                /** Loads image stored in image2Load variable.
2287:                 * Then invokes repaint when image is fully loaded.
2288:                 */
2289:                public void run() {
2290:                    Image localImage;
2291:
2292:                    // grab value 
2293:                    synchronized (IMAGE_LOCK) {
2294:                        localImage = tempImage;
2295:                        tempImage = null;
2296:                        loadPending = false;
2297:                    }
2298:
2299:                    // actually loads image
2300:                    ImageIcon localImageIcon = new ImageIcon(localImage);
2301:                    boolean shouldRepaint = false;
2302:
2303:                    synchronized (IMAGE_LOCK) {
2304:                        // don't commit results if another loading was started after us 
2305:                        if (!loadPending) {
2306:                            image = localImageIcon.getImage();
2307:
2308:                            // keep repaint call out of sync section
2309:                            shouldRepaint = true;
2310:                        }
2311:                    }
2312:
2313:                    if (shouldRepaint) {
2314:                        repaint();
2315:                    }
2316:                }
2317:            }
2318:
2319:            /** Text list cell renderer. Wraps text of items at specified width. Allows numbering
2320:             * of items.
2321:             */
2322:            private static class WrappedCellRenderer extends JPanel implements 
2323:                    ListCellRenderer {
2324:                JTextArea ta = new JTextArea();
2325:                JLabel numberLabel;
2326:                int selected = -1;
2327:                boolean contentNumbered;
2328:                int taWidth;
2329:
2330:                /**
2331:                 * @param contentNumbered Whether content will be numbered
2332:                 * @param wrappingWidth Width of list item.
2333:                 */
2334:                private WrappedCellRenderer(boolean contentNumbered,
2335:                        int wrappingWidth) {
2336:                    super (new BorderLayout());
2337:                    this .contentNumbered = contentNumbered;
2338:
2339:                    ta.setOpaque(false);
2340:                    ta.setEditable(false);
2341:                    ta.setLineWrap(true);
2342:                    ta.setWrapStyleWord(true);
2343:                    ta.setFont(UIManager.getFont("Label.font")); // NOI18N
2344:                    ta.getAccessibleContext().setAccessibleDescription(""); // NOI18N
2345:
2346:                    taWidth = wrappingWidth - 12 - 12;
2347:
2348:                    numberLabel = new JLabel() {
2349:                        @Override
2350:                        protected void paintComponent(Graphics g) {
2351:                            super .paintComponent(g);
2352:
2353:                            // #9804. Draw bullet if the content is not numbered.
2354:                            if (!WrappedCellRenderer.this .contentNumbered) {
2355:                                java.awt.Rectangle rect = g.getClipBounds();
2356:                                g.fillOval(rect.x, rect.y, 7, 7);
2357:                            }
2358:                        }
2359:                    };
2360:                    numberLabel.setLabelFor(ta); // a11y
2361:                    numberLabel.setHorizontalAlignment(SwingConstants.LEFT);
2362:                    numberLabel.setVerticalAlignment(SwingConstants.TOP);
2363:                    numberLabel.setFont(ta.getFont());
2364:                    numberLabel.setOpaque(false);
2365:                    numberLabel.setPreferredSize(new Dimension(25, 0));
2366:                    add(numberLabel, BorderLayout.WEST);
2367:                    taWidth -= 25;
2368:
2369:                    Insets taInsets = ta.getInsets();
2370:                    ta.setSize(taWidth, taInsets.top + taInsets.bottom + 1);
2371:
2372:                    add(ta, BorderLayout.CENTER);
2373:                    setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 12));
2374:                    setOpaque(false);
2375:                }
2376:
2377:                public Component getListCellRendererComponent(JList list,
2378:                        Object value, int index, boolean isSelected,
2379:                        boolean cellHasFocus) {
2380:                    if (index == selected) {
2381:                        numberLabel.setFont(doDeriveFont(numberLabel.getFont(),
2382:                                Font.BOLD));
2383:                        ta.setFont(doDeriveFont(ta.getFont(), Font.BOLD));
2384:                    } else {
2385:                        numberLabel.setFont(doDeriveFont(numberLabel.getFont(),
2386:                                Font.PLAIN));
2387:                        ta.setFont(doDeriveFont(ta.getFont(), Font.PLAIN));
2388:                    }
2389:
2390:                    if (contentNumbered) {
2391:                        numberLabel.setText(Integer.toString(index + 1) + "."); // NOI18N
2392:                    }
2393:
2394:                    // #21322: on JDK1.4 wrapping width is cleared between two rendering runs
2395:                    Insets taInsets = ta.getInsets();
2396:                    ta.setSize(taWidth, taInsets.top + taInsets.bottom + 1);
2397:                    ta.setText((String) value);
2398:
2399:                    return this ;
2400:                }
2401:
2402:                private void setSelectedIndex(int i) {
2403:                    selected = i;
2404:                }
2405:
2406:                private void setForegroundColor(Color color) {
2407:                    if (numberLabel != null) {
2408:                        numberLabel.setForeground(color);
2409:                        numberLabel.setBackground(color);
2410:                    }
2411:
2412:                    ta.setForeground(color);
2413:                }
2414:            }
2415:
2416:            /** Wizard panel. Allows auto layout of content, wizard panel name and input panel.
2417:             */
2418:            private static class WizardPanel extends JPanel {
2419:                /** Users panel is inserted into this panel. */
2420:                private JPanel rightPanel = new JPanel(new BorderLayout());
2421:
2422:                /** Name of the users panel. */
2423:                private JLabel panelName = new JLabel("Step"); //NOI18N
2424:
2425:                /** List of content. */
2426:                private JList contentList;
2427:
2428:                /** Users component. Should be held for removing from rightPanel */
2429:                private Component rightComponent;
2430:
2431:                /** Panel which paints image */
2432:                private ImagedPanel contentPanel;
2433:
2434:                /** Name of content. Can be switched off.  */
2435:                private JPanel contentLabelPanel;
2436:
2437:                /** Wrapped list cell renderer */
2438:                private WrappedCellRenderer cellRenderer;
2439:
2440:                /** Tabbed pane is used only when both content and help are displayed */
2441:                private JTabbedPane tabbedPane;
2442:
2443:                /** HTML Browser is used only when help is displayed in the left pane */
2444:                private HtmlBrowser htmlBrowser;
2445:
2446:                /** Each wizard panel have to be larger or same as this */
2447:                private Dimension cachedDimension;
2448:
2449:                /** Label of steps pane */
2450:                private JLabel label;
2451:
2452:                private JPanel progressBarPanel;
2453:
2454:                /** Selected index of content */
2455:                private int selectedIndex;
2456:                private javax.swing.JLabel m_lblMessage;
2457:                private Color nbErrorForeground;
2458:                private Color nbWarningForeground;
2459:
2460:                /** Creates new <CODE>WizardPanel<CODE>.
2461:                 * @param contentDisplayed whether content will be displayed in the left pane
2462:                 * @param helpDisplayed whether help will be displayed in the left pane
2463:                 * @param contentNumbered whether content will be numbered
2464:                 * @param leftDimension dimension of content or help pane
2465:                 */
2466:                public WizardPanel(boolean contentDisplayed,
2467:                        boolean helpDispalyed, boolean contentNumbered,
2468:                        Dimension leftDimension) {
2469:                    super (new BorderLayout());
2470:                    initComponents(contentDisplayed, helpDispalyed,
2471:                            contentNumbered, leftDimension);
2472:                    setOpaque(false);
2473:                    resetPreferredSize();
2474:                }
2475:
2476:                private void initComponents(boolean contentDisplayed,
2477:                        boolean helpDisplayed, boolean contentNumbered,
2478:                        Dimension leftDimension) {
2479:                    if (contentDisplayed) {
2480:                        createContentPanel(contentNumbered, leftDimension);
2481:
2482:                        if (!helpDisplayed) {
2483:                            add(contentPanel, BorderLayout.WEST);
2484:                        }
2485:                    }
2486:
2487:                    if (helpDisplayed) {
2488:                        htmlBrowser = new BoundedHtmlBrowser(leftDimension);
2489:                        htmlBrowser.setPreferredSize(leftDimension);
2490:
2491:                        if (!contentDisplayed) {
2492:                            add(htmlBrowser, BorderLayout.WEST);
2493:                        }
2494:                    }
2495:
2496:                    if (helpDisplayed && contentDisplayed) {
2497:                        tabbedPane = new JTabbedPane(JTabbedPane.BOTTOM);
2498:                        tabbedPane.addTab(NbBundle.getMessage(
2499:                                WizardDescriptor.class, "CTL_ContentName"),
2500:                                contentPanel);
2501:                        tabbedPane.addTab(NbBundle.getMessage(
2502:                                WizardDescriptor.class, "CTL_HelpName"),
2503:                                htmlBrowser);
2504:                        tabbedPane.setEnabledAt(1, false);
2505:                        tabbedPane.setOpaque(false);
2506:
2507:                        //                tabbedPane.setPreferredSize(leftDimension);
2508:                        add(tabbedPane, BorderLayout.WEST);
2509:                    }
2510:
2511:                    panelName.setBorder(BorderFactory.createMatteBorder(0, 0,
2512:                            1, 0, panelName.getForeground()));
2513:                    panelName.setFont(doDeriveFont(panelName.getFont(),
2514:                            Font.BOLD));
2515:
2516:                    JPanel labelPanel = new JPanel(new BorderLayout());
2517:                    labelPanel.add(panelName, BorderLayout.NORTH);
2518:                    labelPanel.setBorder(BorderFactory.createEmptyBorder(12,
2519:                            12, 12, 11));
2520:                    rightPanel.setBorder(BorderFactory.createEmptyBorder(0, 12,
2521:                            11, 11));
2522:                    panelName.setLabelFor(labelPanel);
2523:
2524:                    nbErrorForeground = UIManager
2525:                            .getColor("nb.errorForeground"); //NOI18N
2526:                    if (nbErrorForeground == null) {
2527:                        //nbErrorForeground = new Color(89, 79, 191); // RGB suggested by Bruce in #28466
2528:                        nbErrorForeground = new Color(255, 0, 0); // RGB suggested by jdinga in #65358
2529:                    }
2530:
2531:                    nbWarningForeground = UIManager
2532:                            .getColor("nb.warningForeground"); //NOI18N
2533:                    if (nbWarningForeground == null) {
2534:                        nbWarningForeground = new Color(51, 51, 51); // Label.foreground
2535:                    }
2536:
2537:                    JPanel errorPanel = new JPanel(new BorderLayout());
2538:                    errorPanel.setBorder(BorderFactory.createEmptyBorder(0, 12,
2539:                            12, 11));
2540:                    m_lblMessage = new FixedHeightLabel();
2541:                    m_lblMessage.setForeground(nbErrorForeground);
2542:                    errorPanel.add(m_lblMessage, BorderLayout.CENTER);
2543:
2544:                    progressBarPanel = new JPanel(new BorderLayout());
2545:                    progressBarPanel.setVisible(false);
2546:
2547:                    if (contentDisplayed) {
2548:                        // place for visualize progress bar in content panel (if contentDisplayed)
2549:                        progressBarPanel.setOpaque(false);
2550:                        progressBarPanel.setBorder(BorderFactory
2551:                                .createEmptyBorder(0, 4, 7, 4));
2552:                        contentPanel.add(progressBarPanel, BorderLayout.SOUTH);
2553:                    } else {
2554:                        // placeholder for progress bar components in WizardPanel (if no contentDisplayed set)
2555:                        progressBarPanel.add(new JLabel(), BorderLayout.NORTH);
2556:                        JProgressBar pb = new JProgressBar();
2557:                        pb.setOrientation(JProgressBar.HORIZONTAL);
2558:                        pb.setAlignmentX(0.5f);
2559:                        pb.setAlignmentY(0.5f);
2560:                        pb.setString("0"); // NOI18N
2561:                        progressBarPanel.add(pb, BorderLayout.CENTER);
2562:
2563:                        progressBarPanel.setBorder(BorderFactory
2564:                                .createEmptyBorder(4, 0, 0, 0));
2565:                        errorPanel.add(progressBarPanel, BorderLayout.SOUTH);
2566:                    }
2567:
2568:                    JPanel fullRightPanel = new JPanel(new BorderLayout());
2569:                    fullRightPanel.add(labelPanel, BorderLayout.NORTH);
2570:                    fullRightPanel.add(rightPanel, BorderLayout.CENTER);
2571:                    fullRightPanel.add(errorPanel, BorderLayout.SOUTH);
2572:
2573:                    // #65506: the wizard panel should fit into window w/o scrollbar
2574:                    add(fullRightPanel, BorderLayout.CENTER);
2575:
2576:                    if ((getBorder() == null)
2577:                            || "GTK".equals(UIManager.getLookAndFeel().getID())) {
2578:                        // Look & Feel has not set the border already
2579:                        JSeparator sep = new JSeparator();
2580:                        sep.setForeground(Color.darkGray);
2581:                        add(sep, BorderLayout.SOUTH);
2582:                    }
2583:                }
2584:
2585:                public void setErrorMessage(String msg, Boolean canContinue) {
2586:                    m_lblMessage.setForeground(nbErrorForeground);
2587:                    if (msg != null && msg.trim().length() > 0
2588:                            && canContinue != null) {
2589:                        if (canContinue.booleanValue()) {
2590:                            m_lblMessage
2591:                                    .setIcon(new ImageIcon(
2592:                                            Utilities
2593:                                                    .loadImage("org/netbeans/modules/dialogs/warning.gif"))); // NOI18N
2594:                            m_lblMessage.setForeground(nbWarningForeground);
2595:                        } else {
2596:                            m_lblMessage
2597:                                    .setIcon(new ImageIcon(
2598:                                            Utilities
2599:                                                    .loadImage("org/netbeans/modules/dialogs/error.gif"))); // NOI18N
2600:                        }
2601:                        m_lblMessage.setToolTipText(msg);
2602:                    } else {
2603:                        m_lblMessage.setIcon(null);
2604:                        m_lblMessage.setToolTipText(null);
2605:                    }
2606:
2607:                    m_lblMessage.setText(msg);
2608:                }
2609:
2610:                private void setProgressComponent(JComponent progressComp,
2611:                        JLabel progressLabel) {
2612:                    if (progressLabel != null) {
2613:                        progressLabel.setText(PROGRESS_BAR_DISPLAY_NAME);
2614:                        progressBarPanel.add(progressLabel, BorderLayout.NORTH);
2615:                    }
2616:                    progressBarPanel.add(progressComp, BorderLayout.CENTER);
2617:                    progressBarPanel.setVisible(true);
2618:                }
2619:
2620:                /** Creates content panel.
2621:                 * @param contentNumbered <CODE>boolean</CODE> whether content will be numbered
2622:                 * @param leftDimension <CODE>Dimension</CODE> dimension of content pane
2623:                 */
2624:                private void createContentPanel(boolean contentNumbered,
2625:                        Dimension leftDimension) {
2626:                    contentList = new JList();
2627:                    cellRenderer = new WrappedCellRenderer(contentNumbered,
2628:                            leftDimension.width);
2629:                    cellRenderer.setOpaque(false);
2630:                    contentList.setCellRenderer(cellRenderer);
2631:                    contentList.setOpaque(false);
2632:                    contentList.setEnabled(false);
2633:                    contentList.getAccessibleContext()
2634:                            .setAccessibleDescription(""); // NOI18N
2635:
2636:                    JScrollPane scroll = new JScrollPane(contentList);
2637:                    scroll
2638:                            .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
2639:                    scroll.getViewport().setOpaque(false);
2640:                    scroll.setBorder(null);
2641:                    scroll.setOpaque(false);
2642:                    // #89392: remove GTK's viewport border
2643:                    scroll.setViewportBorder(null);
2644:
2645:                    label = new JLabel(NbBundle.getMessage(
2646:                            WizardDescriptor.class, "CTL_ContentName"));
2647:                    label.setForeground(Color.white);
2648:                    label.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0,
2649:                            label.getForeground()));
2650:                    label.setFont(doDeriveFont(label.getFont(), Font.BOLD));
2651:                    contentLabelPanel = new JPanel(new BorderLayout());
2652:                    contentLabelPanel.setBorder(BorderFactory
2653:                            .createEmptyBorder(12, 12, 11, 11));
2654:                    contentLabelPanel.setOpaque(false);
2655:                    contentLabelPanel.add(label, BorderLayout.NORTH);
2656:
2657:                    contentPanel = new ImagedPanel(null);
2658:                    contentPanel.add(contentLabelPanel, BorderLayout.NORTH);
2659:                    contentPanel.add(scroll, BorderLayout.CENTER);
2660:
2661:                    contentPanel.setPreferredSize(leftDimension);
2662:                    label.setLabelFor(contentList);
2663:                }
2664:
2665:                /** Setter for lists items.
2666:                 * @param content Array of list items.
2667:                 */
2668:                public void setContent(final String[] content) {
2669:                    final JList list = contentList;
2670:
2671:                    if (list == null) {
2672:                        return;
2673:                    }
2674:
2675:                    // #18055: Ensure it runs in AWT thread.
2676:                    // Remove this when component handling will be assured
2677:                    // by other means that runs always in AWT.
2678:                    Mutex.EVENT.writeAccess(new Runnable() {
2679:                        public void run() {
2680:                            list.setListData(content);
2681:                            list.revalidate();
2682:                            list.repaint();
2683:                            contentLabelPanel.setVisible(content.length > 0);
2684:                        }
2685:                    });
2686:                }
2687:
2688:                /** Setter for selected list item.
2689:                 * @param index Index of selected item in the list.
2690:                 */
2691:                public void setSelectedIndex(final int index) {
2692:                    selectedIndex = index;
2693:
2694:                    if (cellRenderer != null) {
2695:                        cellRenderer.setSelectedIndex(index);
2696:
2697:                        final JList list = contentList;
2698:
2699:                        if (list == null) {
2700:                            return;
2701:                        }
2702:
2703:                        // #18055. See previous #18055 comment.
2704:                        Mutex.EVENT.readAccess(new Runnable() {
2705:                            public void run() {
2706:                                list.ensureIndexIsVisible(index);
2707:
2708:                                // Fix of #10787.
2709:                                // This is workaround for swing bug - BasicListUI doesn't ask for preferred
2710:                                // size of rendered list cell as a result of property selectedIndex change. 
2711:                                // It does only on certain JList property changes (e.g. fixedCellWidth).
2712:                                // Maybe subclassing BasicListUI could be better fix.
2713:                                list.setFixedCellWidth(0);
2714:                                list.setFixedCellWidth(-1);
2715:                            }
2716:                        });
2717:                    }
2718:                }
2719:
2720:                /** Setter for content background color.
2721:                 * @param color content background color.
2722:                 */
2723:                public void setContentBackColor(Color color) {
2724:                    if (contentPanel != null) {
2725:                        contentPanel.setBackground(color);
2726:                    }
2727:                }
2728:
2729:                /** Setter for content foreground color.
2730:                 * @param color content foreground color.
2731:                 */
2732:                public void setContentForegroundColor(Color color) {
2733:                    if (cellRenderer == null) {
2734:                        return;
2735:                    }
2736:
2737:                    cellRenderer.setForegroundColor(color);
2738:                    label.setForeground(color);
2739:                    label.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0,
2740:                            label.getForeground()));
2741:                }
2742:
2743:                /** Setter for content background image.
2744:                 * @param image content background image
2745:                 */
2746:                public void setImage(Image image) {
2747:                    if (contentPanel != null) {
2748:                        contentPanel.setImage(image);
2749:                    }
2750:                }
2751:
2752:                /** Setter for image alignment.
2753:                 * @param align image alignment - 'North', 'South'
2754:                 */
2755:                public void setImageAlignment(String align) {
2756:                    if (contentPanel != null) {
2757:                        contentPanel.setImageAlignment(align);
2758:                    }
2759:                }
2760:
2761:                /** Setter for user's component.
2762:                 * @param c user's component
2763:                 */
2764:                public void setRightComponent(Component c) {
2765:                    if (rightComponent != null) {
2766:                        rightPanel.remove(rightComponent);
2767:                    }
2768:
2769:                    rightComponent = c;
2770:                    rightPanel.add(rightComponent, BorderLayout.CENTER);
2771:
2772:                    //            validate();
2773:                }
2774:
2775:                /** Getter for user's component.
2776:                 * @return <CODE>Component</CODE> user's component
2777:                 */
2778:                public Component getRightComponent() {
2779:                    return rightComponent;
2780:                }
2781:
2782:                /** Setter for wizard panel name.
2783:                 * @param name panel name
2784:                 */
2785:                public void setPanelName(String name) {
2786:                    panelName.setText(name);
2787:                }
2788:
2789:                /** Setter for help URL.
2790:                 * @param helpURL help URL
2791:                 */
2792:                public void setHelpURL(URL helpURL) {
2793:                    if (htmlBrowser == null) {
2794:                        return;
2795:                    }
2796:
2797:                    if (helpURL != null) {
2798:                        if (!helpURL.equals(htmlBrowser.getDocumentURL())) {
2799:                            htmlBrowser.setURL(helpURL);
2800:                        }
2801:
2802:                        if (tabbedPane != null) {
2803:                            tabbedPane.setEnabledAt(tabbedPane
2804:                                    .indexOfComponent(htmlBrowser), true);
2805:                        }
2806:                    } else if (tabbedPane != null) {
2807:                        tabbedPane.setSelectedComponent(contentPanel);
2808:                        tabbedPane.setEnabledAt(tabbedPane
2809:                                .indexOfComponent(htmlBrowser), false);
2810:                    }
2811:                }
2812:
2813:                public void resetPreferredSize() {
2814:                    cachedDimension = new Dimension(600, 365);
2815:                }
2816:
2817:                @Override
2818:                public Dimension getPreferredSize() {
2819:                    Dimension dim = super .getPreferredSize();
2820:
2821:                    if (dim.height > cachedDimension.height) {
2822:                        cachedDimension.height = dim.height;
2823:                    }
2824:
2825:                    if (dim.width > cachedDimension.width) {
2826:                        cachedDimension.width = dim.width;
2827:                    }
2828:
2829:                    return cachedDimension;
2830:                }
2831:
2832:                /** Overriden to delegate call to user component.
2833:                 */
2834:                @Override
2835:                public void requestFocus() {
2836:                    if ((rightComponent != null)
2837:                            && rightComponent.isDisplayable()) {
2838:                        JComponent comp = (JComponent) rightComponent;
2839:                        Container rootAnc = comp.getFocusCycleRootAncestor();
2840:                        FocusTraversalPolicy policy = rootAnc
2841:                                .getFocusTraversalPolicy();
2842:                        Component focus = policy.getComponentAfter(rootAnc,
2843:                                comp);
2844:
2845:                        if (focus != null) {
2846:                            focus.requestFocus();
2847:                        } else {
2848:                            comp.requestFocus();
2849:                        }
2850:                    } else {
2851:                        super .requestFocus();
2852:                    }
2853:                }
2854:
2855:                /** Overriden to delegate call to user component.
2856:                 */
2857:                @Deprecated
2858:                @Override
2859:                public boolean requestDefaultFocus() {
2860:                    if (rightComponent instanceof  JComponent) {
2861:                        return ((JComponent) rightComponent)
2862:                                .requestDefaultFocus();
2863:                    }
2864:
2865:                    return super .requestDefaultFocus();
2866:                }
2867:
2868:                @Override
2869:                public javax.accessibility.AccessibleContext getAccessibleContext() {
2870:                    if (accessibleContext == null) {
2871:                        accessibleContext = new AccessibleWizardPanel();
2872:                    }
2873:
2874:                    return accessibleContext;
2875:                }
2876:
2877:                private class AccessibleWizardPanel extends AccessibleJPanel {
2878:                    AccessibleWizardPanel() {
2879:                    }
2880:
2881:                    @Override
2882:                    public String getAccessibleDescription() {
2883:                        if (accessibleDescription != null) {
2884:                            return accessibleDescription;
2885:                        }
2886:
2887:                        if (rightComponent instanceof  Accessible) {
2888:                            if (rightComponent.getAccessibleContext()
2889:                                    .getAccessibleDescription() == null) {
2890:                                return null;
2891:                            }
2892:
2893:                            return NbBundle.getMessage(WizardDescriptor.class,
2894:                                    "ACSD_WizardPanel", new Integer(
2895:                                            selectedIndex + 1), panelName
2896:                                            .getText(), rightComponent
2897:                                            .getAccessibleContext()
2898:                                            .getAccessibleDescription());
2899:                        }
2900:
2901:                        return super .getAccessibleDescription();
2902:                    }
2903:                }
2904:            }
2905:
2906:            /** Overriden to return wished preferred size */
2907:            private static class BoundedHtmlBrowser extends HtmlBrowser {
2908:                Dimension dim;
2909:
2910:                public BoundedHtmlBrowser(Dimension d) {
2911:                    super (false, false);
2912:                    dim = d;
2913:                }
2914:
2915:                @Override
2916:                public Dimension getPreferredSize() {
2917:                    return dim;
2918:                }
2919:            }
2920:
2921:            // helper, make possible close wizard as finish
2922:            static class FinishAction extends Object {
2923:                ActionListener listner;
2924:
2925:                public void addActionListener(ActionListener ac) {
2926:                    listner = ac;
2927:                }
2928:
2929:                public void removeActionListener(ActionListener ac) {
2930:                    listner = null;
2931:                }
2932:
2933:                public void fireActionPerformed() {
2934:                    if (listner != null) {
2935:                        listner.actionPerformed(new ActionEvent(this , 0, ""));
2936:                    }
2937:                }
2938:            }
2939:
2940:            private static final class FixedHeightLabel extends JLabel {
2941:
2942:                private static final int ESTIMATED_HEIGHT = 16;
2943:
2944:                public FixedHeightLabel() {
2945:                    super ();
2946:                }
2947:
2948:                @Override
2949:                public Dimension getPreferredSize() {
2950:                    Dimension preferredSize = super .getPreferredSize();
2951:                    assert ESTIMATED_HEIGHT == Utilities.loadImage(
2952:                            "org/netbeans/modules/dialogs/warning.gif")
2953:                            .getHeight(null) : "Use only 16px icon.";
2954:                    preferredSize.height = Math.max(ESTIMATED_HEIGHT,
2955:                            preferredSize.height);
2956:                    return preferredSize;
2957:                }
2958:            }
2959:
2960:            private static final class SettingsAndIterator<Data> {
2961:                private final Iterator<Data> panels;
2962:                private final Data settings;
2963:                private final boolean useThis;
2964:                /** current panel */
2965:                private Panel<Data> current;
2966:
2967:                public SettingsAndIterator(Iterator<Data> iterator,
2968:                        Data settings) {
2969:                    this (iterator, settings, false);
2970:                }
2971:
2972:                public SettingsAndIterator(Iterator<Data> iterator,
2973:                        Data settings, boolean useThis) {
2974:                    this .panels = iterator;
2975:                    this .settings = settings;
2976:                    this .useThis = useThis;
2977:                }
2978:
2979:                public static SettingsAndIterator<WizardDescriptor> create(
2980:                        Iterator<WizardDescriptor> iterator) {
2981:                    return new SettingsAndIterator<WizardDescriptor>(iterator,
2982:                            null, true);
2983:                }
2984:
2985:                public static SettingsAndIterator<Void> empty() {
2986:                    return new SettingsAndIterator<Void>(new EmptyPanel(),
2987:                            (Void) null);
2988:                }
2989:
2990:                public Iterator<Data> getIterator(WizardDescriptor caller) {
2991:                    return panels;
2992:                }
2993:
2994:                @SuppressWarnings("unchecked")
2995:                public Data getSettings(WizardDescriptor caller) {
2996:                    return useThis ? (Data) caller : settings;
2997:                }
2998:
2999:                public SettingsAndIterator<Data> clone(Iterator<Data> it) {
3000:                    SettingsAndIterator<Data> s = new SettingsAndIterator<Data>(
3001:                            it, settings, useThis);
3002:                    return s;
3003:                }
3004:            }
3005:
3006:            private static final class EmptyPanel implements  Panel<Void>,
3007:                    Iterator<Void> {
3008:                public Component getComponent() {
3009:                    return new JPanel();
3010:                }
3011:
3012:                public HelpCtx getHelp() {
3013:                    return HelpCtx.DEFAULT_HELP;
3014:                }
3015:
3016:                public void readSettings(Void settings) {
3017:                }
3018:
3019:                public void storeSettings(Void settings) {
3020:                }
3021:
3022:                public boolean isValid() {
3023:                    return true;
3024:                }
3025:
3026:                public void addChangeListener(ChangeListener l) {
3027:                }
3028:
3029:                public void removeChangeListener(ChangeListener l) {
3030:                }
3031:
3032:                public Panel<Void> current() {
3033:                    return this ;
3034:                }
3035:
3036:                public String name() {
3037:                    return ""; // NORTH
3038:                }
3039:
3040:                public boolean hasNext() {
3041:                    return false;
3042:                }
3043:
3044:                public boolean hasPrevious() {
3045:                    return false;
3046:                }
3047:
3048:                public void nextPanel() {
3049:                }
3050:
3051:                public void previousPanel() {
3052:                }
3053:            } // end of EmptyPanel
3054:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.