Source Code Cross Referenced for SimpleTestStepLocation.java in  » IDE-Netbeans » junit » org » netbeans » modules » junit » wizards » 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 » junit » org.netbeans.modules.junit.wizards 
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 2004-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.netbeans.modules.junit.wizards;
0043:
0044:        import java.awt.BorderLayout;
0045:        import java.awt.Component;
0046:        import java.awt.Container;
0047:        import java.awt.GridBagConstraints;
0048:        import java.awt.GridBagLayout;
0049:        import java.awt.GridLayout;
0050:        import java.awt.Insets;
0051:        import java.awt.Point;
0052:        import java.awt.event.ActionEvent;
0053:        import java.awt.event.ActionListener;
0054:        import java.awt.event.FocusEvent;
0055:        import java.awt.event.FocusListener;
0056:        import java.awt.event.HierarchyEvent;
0057:        import java.awt.event.HierarchyListener;
0058:        import java.awt.event.ItemEvent;
0059:        import java.awt.event.ItemListener;
0060:        import java.awt.event.MouseEvent;
0061:        import java.io.File;
0062:        import java.util.ArrayList;
0063:        import java.util.Arrays;
0064:        import java.util.Collection;
0065:        import java.util.Iterator;
0066:        import java.util.List;
0067:        import java.util.Map;
0068:        import java.util.ResourceBundle;
0069:        import java.util.Set;
0070:        import javax.swing.AbstractAction;
0071:        import javax.swing.AbstractButton;
0072:        import javax.swing.Action;
0073:        import javax.swing.ActionMap;
0074:        import javax.swing.BorderFactory;
0075:        import javax.swing.Box;
0076:        import javax.swing.BoxLayout;
0077:        import javax.swing.DefaultComboBoxModel;
0078:        import javax.swing.JButton;
0079:        import javax.swing.JCheckBox;
0080:        import javax.swing.JComboBox;
0081:        import javax.swing.JComponent;
0082:        import javax.swing.JLabel;
0083:        import javax.swing.JList;
0084:        import javax.swing.JPanel;
0085:        import javax.swing.JRootPane;
0086:        import javax.swing.JSeparator;
0087:        import javax.swing.JTextField;
0088:        import javax.swing.ListSelectionModel;
0089:        import javax.swing.SwingUtilities;
0090:        import javax.swing.border.BevelBorder;
0091:        import javax.swing.event.ChangeEvent;
0092:        import javax.swing.event.ChangeListener;
0093:        import javax.swing.event.DocumentEvent;
0094:        import javax.swing.event.DocumentListener;
0095:        import javax.swing.event.ListSelectionEvent;
0096:        import javax.swing.event.ListSelectionListener;
0097:        import javax.swing.event.MouseInputListener;
0098:        import javax.swing.text.AbstractDocument;
0099:        import javax.swing.text.AttributeSet;
0100:        import javax.swing.text.BadLocationException;
0101:        import javax.swing.text.DocumentFilter;
0102:        import javax.swing.text.NavigationFilter;
0103:        import javax.swing.text.Position;
0104:        import org.netbeans.api.java.classpath.ClassPath;
0105:        import org.netbeans.api.project.Project;
0106:        import org.netbeans.api.project.ProjectUtils;
0107:        import org.netbeans.api.project.SourceGroup;
0108:        import org.netbeans.modules.junit.GuiUtils;
0109:        import org.netbeans.modules.junit.JUnitCfgOfCreate;
0110:        import org.netbeans.modules.junit.MessageStack;
0111:        import org.netbeans.modules.junit.NamedObject;
0112:        import org.netbeans.modules.junit.SizeRestrictedPanel;
0113:        import org.netbeans.modules.junit.TestCreator;
0114:        import org.netbeans.spi.java.project.support.ui.PackageView;
0115:        import org.openide.DialogDescriptor;
0116:        import org.openide.DialogDisplayer;
0117:        import org.openide.ErrorManager;
0118:        import org.openide.NotifyDescriptor;
0119:        import org.openide.WizardDescriptor;
0120:        import org.openide.awt.Mnemonics;
0121:        import org.openide.filesystems.FileObject;
0122:        import org.openide.filesystems.FileUtil;
0123:        import org.openide.loaders.DataObject;
0124:        import org.openide.nodes.AbstractNode;
0125:        import org.openide.nodes.Children;
0126:        import org.openide.nodes.FilterNode;
0127:        import org.openide.nodes.Node;
0128:        import org.openide.nodes.NodeAcceptor;
0129:        import org.openide.nodes.NodeOperation;
0130:        import org.openide.util.HelpCtx;
0131:        import org.openide.util.NbBundle;
0132:        import org.openide.util.UserCancelException;
0133:
0134:        /**
0135:         *
0136:         * @author  Marian Petras
0137:         */
0138:        public final class SimpleTestStepLocation implements 
0139:                WizardDescriptor.Panel<WizardDescriptor> {
0140:
0141:            /**
0142:             * message layer for displaying messages about problems with checkbox
0143:             * selection
0144:             *
0145:             * @see  MessageStack
0146:             */
0147:            private static final int MSG_LAYER_CHECKBOXES = 0;
0148:            /**
0149:             * message layer for displaying messages about problems with classname
0150:             *
0151:             * @see  MessageStack
0152:             */
0153:            private static final int MSG_LAYER_CLASSNAME = 1;
0154:
0155:            private final String testClassNameSuffix = NbBundle.getMessage(
0156:                    TestCreator.class, "PROP_test_classname_suffix"); //NOI18N
0157:
0158:            private Component visualComp;
0159:            private List<ChangeListener> changeListeners;
0160:            private JTextField tfClassToTest;
0161:            private JButton btnBrowse;
0162:            private JTextField tfTestClass;
0163:            private JTextField tfProjectName;
0164:            private JComboBox cboxLocation;
0165:            private JTextField tfCreatedFile;
0166:
0167:            private JCheckBox chkPublic;
0168:            private JCheckBox chkProtected;
0169:            private JCheckBox chkPackagePrivate;
0170:            private JCheckBox chkSetUp;
0171:            private JCheckBox chkTearDown;
0172:            private JCheckBox chkMethodBodies;
0173:            private JCheckBox chkJavadoc;
0174:            private JCheckBox chkHints;
0175:
0176:            /** message stack for displaying error messages */
0177:            private final MessageStack msgStack = new MessageStack(2);
0178:            private String msgClassNameInvalid;
0179:            private String msgClassToTestDoesNotExist;
0180:            private String msgChkBoxesInvalid;
0181:
0182:            /**
0183:             * project to create a test class in
0184:             */
0185:            private Project project;
0186:            private WizardDescriptor wizard;
0187:
0188:            // focus change detection mechanism
0189:
0190:            /**
0191:             * true, if the current chosen project have multiple testable SourceGroups.
0192:             * If it does, class name entered in the Class to Test textfield must be
0193:             * checked agains all of them (to detect ambiguity) and if there are
0194:             * multiple classes matching, the user must be forced to choose one
0195:             * before leaving the textfield.
0196:             * <p>
0197:             * The focus change detection mechanism is activated by the
0198:             * {@link #hierarchyListener} after this wizard panel is added
0199:             * to the wizard dialog. The listener activates the mechanism
0200:             * only if the mechanism is
0201:             * {@linkplain #focusChangeDetectionEnabled enabled}.
0202:             *
0203:             * @see  #setUp
0204:             */
0205:            private boolean multipleSourceRoots;
0206:            /**
0207:             * true if the focus change detection mechanism is enabled.
0208:             * Being it enabled does not mean that it is activated
0209:             * - it cannot be activated until the visual component is added
0210:             * to the wizard dialog
0211:             */
0212:            private boolean interactionRestrictionsEnabled = false;
0213:            /**
0214:             * true if the focus change detection mechanism is active
0215:             */
0216:            private boolean interactionRestrictionsActive = false;
0217:            /** <!-- PENDING --> */
0218:            private boolean interactionRestrictionsSuspended = false;
0219:            /** */
0220:            private boolean mouseClicksBlocked = false;
0221:            /**
0222:             * hierarchy listener that detects when the visual component
0223:             * is added to the wizard dialog. Once it is added to the dialog,
0224:             * the focus change detection mechanism can be activated.
0225:             *
0226:             * @see  #focusChangeDetectionEnabled
0227:             */
0228:            private HierarchyListener displayabilityListener;
0229:            /** root pane of the wizard dialog */
0230:            private JRootPane rootPane;
0231:            /**
0232:             * default button of the wizard.
0233:             * It is actually the default button of the dialog's {@link #rootPane}.
0234:             */
0235:            private JButton defaultButton;
0236:            /**
0237:             * action key of the root pane's original default action
0238:             * <!-- PENDING -->
0239:             */
0240:            private String rootPaneDefaultActionKey;
0241:            /**
0242:             * root pane's original default action
0243:             * <!-- PENDING -->
0244:             */
0245:            private Action rootPaneDefaultAction;
0246:            /**
0247:             * mouse listener of the wizard dialog's glass pane.
0248:             * It is a part of the focus change detection mechanism.
0249:             */
0250:            private MouseInputListener glassPaneListener;
0251:            /**
0252:             * UI components on which mouse events are checked and evauluated.
0253:             * The mouse events are checked only if there are
0254:             * {@link #multipleSourceRoots}.
0255:             */
0256:            private Component[] mouseBlocked;
0257:            /** 
0258:             * UI components on which mnemonic activation is checked and evaluated.
0259:             * Mnemonic activation events are checked only if there are
0260:             * {@link #multipleSourceRoots}.
0261:             */
0262:            private JComponent[] mnemonicBlocked;
0263:            /**
0264:             * information about actions mapped to action keys of UI components
0265:             * accessible using mnemonics.
0266:             * This is used for blocking access to those components using
0267:             * mnemonics and for restoring the UI components' action maps
0268:             * to the original state.
0269:             *
0270:             * @see  #blockMnemonics
0271:             * @see  #unblockMnemonics
0272:             */
0273:            private ActionMappingInfo[] actionMappingInfo;
0274:            /**
0275:             * component that is explicitely allowed to gain focus.
0276:             * This is used when a button press event is about to be dispatched
0277:             * to the button, so that the focus listener does not interrupt
0278:             * focus transfer to the button.
0279:             */
0280:            private Component focusGainAllowedFor;
0281:
0282:            // project structure (static)
0283:
0284:            /**
0285:             * <code>SourceGroups</code> that have at least one test
0286:             * <code>SourceGroup</code> assigned. It is equal to set of keys
0287:             * of the {@link #sourcesToTestsMap}.
0288:             * It is updated whenever {@link #project} changes.
0289:             *
0290:             * @see  #setUp
0291:             */
0292:            private SourceGroup[] testableSourceGroups;
0293:            /** root folders of {@link #testableSourceGroups} */
0294:            private FileObject[] testableSourceGroupsRoots;
0295:            /** <!-- PENDING --> */
0296:            private SourceGroup[] allTestSourceGroups;
0297:            /**
0298:             * relation between <code>SourceGroup</code>s
0299:             * and their respective test <code>SourceGroup</code>s.
0300:             * It is updated whenever {@link #project} changes.
0301:             *
0302:             * @see  #setUp
0303:             */
0304:            private Map<SourceGroup, Object[]> sourcesToTestsMap;
0305:
0306:            // entered and computed data
0307:
0308:            /**
0309:             * index of the first <code>SourceGroup</code> where a file named
0310:             * according to contents of {@link #srcRelFileNameSys} was found.
0311:             * The search is performed in {@link #testableSourceGroupsRoots}.
0312:             * If such a file is not found in any of the source groups roots,
0313:             * this variable is set to <code>-1</code>.
0314:             *
0315:             * @see  #classExists
0316:             */
0317:            private int sourceGroupParentIndex = -1;
0318:            /** */
0319:            private FileObject srcFile;
0320:            private SourceGroup srcGroup = null;
0321:            private String testsRootDirName = ""; //NOI18N
0322:            private String srcRelFileNameSys = ""; //NOI18N
0323:            private String testRelFileName = ""; //NOI18N
0324:            /** */
0325:            private FileObject testRootFolder;
0326:            /** */
0327:            private int classNameLength = 0;
0328:            /** length of the string denoting name of the selected SourceGroup */
0329:            private boolean srcGroupNameDisplayed = false;
0330:            /** <!-- PENDING --> */
0331:            private boolean programmaticChange = false;
0332:            /** <!-- PENDING --> */
0333:            private boolean navigationFilterEnabled = false;
0334:            /** <!-- PENDING --> */
0335:            private ClsNameNavigationFilter clsNameNavigationFilter;
0336:            /** <!-- PENDING --> */
0337:            private ClsNameDocumentFilter clsNameDocumentFilter;
0338:
0339:            /** */
0340:            private boolean ignoreCboxItemChanges = false;
0341:            /** */
0342:            private boolean ignoreClsNameChanges = false;
0343:
0344:            // validation of entered data
0345:
0346:            /**
0347:             * <code>true</code> if data entered in the form are valid.
0348:             * The data are valid if the entered class name denotes an existing
0349:             * class and at least one of the <em>Method Access Levels</em>
0350:             * checkboxes is selected.
0351:             */
0352:            private boolean isValid = false;
0353:            /** is the class name non-empty and valid? */
0354:            private boolean classNameValid = false;
0355:            /**
0356:             * <code>true</code> if and only if a file named
0357:             * according to contents of {@link #srcRelFileNameSys} was found.
0358:             * The search is performed in {@link #testableSourceGroupsRoots}.
0359:             * If this variable is <code>true</code>, variable
0360:             * {@link #sourceGroupParentIndex} is set to a non-negative value.
0361:             */
0362:            private boolean classExists = false;
0363:            /**
0364:             * <code>true</code> if and only if at least one of the checkboxes
0365:             * in the <em>Method Access Levels</em> group is selected
0366:             */
0367:            private boolean chkBoxesValid = false;
0368:
0369:            //--------------------------------------------------------------------------
0370:
0371:            public SimpleTestStepLocation() {
0372:                visualComp = createVisualComp();
0373:            }
0374:
0375:            private Component createVisualComp() {
0376:                JLabel lblClassToTest = new JLabel();
0377:                JLabel lblCreatedTestClass = new JLabel();
0378:                JLabel lblProject = new JLabel();
0379:                JLabel lblLocation = new JLabel();
0380:                JLabel lblFile = new JLabel();
0381:                tfClassToTest = new JTextField(25);
0382:                btnBrowse = new JButton();
0383:                tfTestClass = new JTextField();
0384:                tfProjectName = new JTextField();
0385:                cboxLocation = new JComboBox();
0386:                tfCreatedFile = new JTextField();
0387:
0388:                ResourceBundle bundle = NbBundle
0389:                        .getBundle(SimpleTestStepLocation.class);
0390:
0391:                Mnemonics.setLocalizedText(lblClassToTest, bundle
0392:                        .getString("LBL_ClassToTest"));//NOI18N
0393:                Mnemonics.setLocalizedText(lblCreatedTestClass, bundle
0394:                        .getString("LBL_TestClass")); //NOI18N
0395:                Mnemonics.setLocalizedText(lblProject, bundle
0396:                        .getString("LBL_Project")); //NOI18N
0397:                Mnemonics.setLocalizedText(lblLocation, bundle
0398:                        .getString("LBL_Location")); //NOI18N
0399:                Mnemonics.setLocalizedText(lblFile, bundle
0400:                        .getString("LBL_CreatedFile"));//NOI18N
0401:                Mnemonics.setLocalizedText(btnBrowse, bundle
0402:                        .getString("LBL_Browse")); //NOI18N
0403:
0404:                lblClassToTest.setLabelFor(tfClassToTest);
0405:                lblCreatedTestClass.setLabelFor(tfTestClass);
0406:                lblProject.setLabelFor(tfProjectName);
0407:                lblFile.setLabelFor(tfCreatedFile);
0408:                lblLocation.setLabelFor(cboxLocation);
0409:
0410:                tfTestClass.setEditable(false);
0411:                tfProjectName.setEditable(false);
0412:                tfCreatedFile.setEditable(false);
0413:
0414:                tfTestClass.setFocusable(false);
0415:                tfProjectName.setFocusable(false);
0416:                tfCreatedFile.setFocusable(false);
0417:
0418:                cboxLocation.setEditable(false);
0419:
0420:                JCheckBox[] chkBoxes;
0421:
0422:                JComponent accessLevels = GuiUtils.createChkBoxGroup(NbBundle
0423:                        .getMessage(GuiUtils.class,
0424:                                "JUnitCfgOfCreate.groupAccessLevels"), //NOI18N
0425:                        chkBoxes = GuiUtils.createCheckBoxes(new String[] {
0426:                                GuiUtils.CHK_PUBLIC, GuiUtils.CHK_PROTECTED,
0427:                                GuiUtils.CHK_PACKAGE }));
0428:                chkPublic = chkBoxes[0];
0429:                chkProtected = chkBoxes[1];
0430:                chkPackagePrivate = chkBoxes[2];
0431:
0432:                JComponent optCode = GuiUtils.createChkBoxGroup(NbBundle
0433:                        .getMessage(GuiUtils.class,
0434:                                "JUnitCfgOfCreate.groupOptCode"), //NOI18N
0435:                        chkBoxes = GuiUtils.createCheckBoxes(new String[] {
0436:                                GuiUtils.CHK_SETUP, GuiUtils.CHK_TEARDOWN,
0437:                                GuiUtils.CHK_METHOD_BODIES }));
0438:                chkSetUp = chkBoxes[0];
0439:                chkTearDown = chkBoxes[1];
0440:                chkMethodBodies = chkBoxes[2];
0441:
0442:                JComponent optComments = GuiUtils.createChkBoxGroup(NbBundle
0443:                        .getMessage(GuiUtils.class,
0444:                                "JUnitCfgOfCreate.groupOptComments"), //NOI18N
0445:                        chkBoxes = GuiUtils.createCheckBoxes(new String[] {
0446:                                GuiUtils.CHK_JAVADOC, GuiUtils.CHK_HINTS }));
0447:                chkJavadoc = chkBoxes[0];
0448:                chkHints = chkBoxes[1];
0449:
0450:                /* set layout of the components: */
0451:                JPanel targetPanel = new SizeRestrictedPanel(
0452:                        new GridBagLayout(), false, true);
0453:
0454:                GridBagConstraints gbcLeft = new GridBagConstraints();
0455:                gbcLeft.anchor = GridBagConstraints.WEST;
0456:                gbcLeft.gridwidth = 1;
0457:                gbcLeft.insets = new Insets(0, 0, 6, 12);
0458:                gbcLeft.fill = GridBagConstraints.NONE;
0459:                gbcLeft.weightx = 0.0f;
0460:
0461:                GridBagConstraints gbcRight = new GridBagConstraints();
0462:                gbcRight.anchor = GridBagConstraints.WEST;
0463:                gbcRight.gridwidth = GridBagConstraints.REMAINDER;
0464:                gbcRight.insets = new Insets(0, 0, 6, 0);
0465:                gbcRight.fill = GridBagConstraints.BOTH;
0466:                gbcRight.weightx = 1.0f;
0467:
0468:                // Class to Test:
0469:
0470:                gbcRight.gridwidth = 1;
0471:
0472:                GridBagConstraints gbcBrowse = new GridBagConstraints();
0473:                gbcBrowse.insets = new Insets(0, 11, 6, 0);
0474:                gbcBrowse.gridwidth = GridBagConstraints.REMAINDER;
0475:
0476:                targetPanel.add(lblClassToTest, gbcLeft);
0477:                targetPanel.add(tfClassToTest, gbcRight);
0478:                targetPanel.add(btnBrowse, gbcBrowse);
0479:
0480:                // Created Test Class:
0481:
0482:                gbcLeft.insets.bottom = gbcRight.insets.bottom = 24;
0483:
0484:                targetPanel.add(lblCreatedTestClass, gbcLeft);
0485:                targetPanel.add(tfTestClass, gbcRight);
0486:                targetPanel.add(new JPanel(), gbcBrowse); //filler
0487:
0488:                // Project:
0489:
0490:                gbcRight.gridwidth = GridBagConstraints.REMAINDER;
0491:
0492:                gbcLeft.insets.bottom = gbcRight.insets.bottom = 6;
0493:
0494:                targetPanel.add(lblProject, gbcLeft);
0495:                targetPanel.add(tfProjectName, gbcRight);
0496:
0497:                // Location:
0498:
0499:                gbcLeft.insets.bottom = gbcRight.insets.bottom = 12;
0500:
0501:                targetPanel.add(lblLocation, gbcLeft);
0502:                targetPanel.add(cboxLocation, gbcRight);
0503:
0504:                // Created File:
0505:
0506:                gbcLeft.insets.bottom = gbcRight.insets.bottom = 0;
0507:
0508:                targetPanel.add(lblFile, gbcLeft);
0509:                targetPanel.add(tfCreatedFile, gbcRight);
0510:
0511:                JComponent optionsBox = new SizeRestrictedPanel(false, true);
0512:                optionsBox
0513:                        .setLayout(new BoxLayout(optionsBox, BoxLayout.X_AXIS));
0514:                optionsBox.add(accessLevels);
0515:                optionsBox.add(Box.createHorizontalStrut(18));
0516:                optionsBox.add(optCode);
0517:                optionsBox.add(Box.createHorizontalStrut(18));
0518:                optionsBox.add(optComments);
0519:                //align groups of the checkboxes vertically to the top:
0520:                accessLevels.setAlignmentY(0.0f);
0521:                optCode.setAlignmentY(0.0f);
0522:                optComments.setAlignmentY(0.0f);
0523:
0524:                final Box result = Box.createVerticalBox();
0525:                result.add(targetPanel);
0526:                result.add(Box.createVerticalStrut(12));
0527:                JPanel separatorPanel = new SizeRestrictedPanel(
0528:                        new GridLayout(), false, true);
0529:                separatorPanel.add(new JSeparator());
0530:                result.add(separatorPanel);
0531:                result.add(Box.createVerticalStrut(12));
0532:                result.add(optionsBox);
0533:                //result.add(Box.createVerticalGlue());  //not necessary
0534:
0535:                /* tune layout of the components within the box: */
0536:                targetPanel.setAlignmentX(0.0f);
0537:                optionsBox.setAlignmentX(0.0f);
0538:                optCode.setAlignmentX(0.0f);
0539:                optComments.setAlignmentX(0.0f);
0540:
0541:                result.setName(bundle.getString("LBL_panel_ChooseClass"));
0542:
0543:                addAccessibilityDescriptions(result);
0544:                setUpInteraction();
0545:
0546:                return result;
0547:            }
0548:
0549:            /**
0550:             * Sets up tooltips and accessibility names and descriptions
0551:             * for GUI elements of the wizard panel.
0552:             *
0553:             * @param  wizPanel  wizard panel whose elements need to be made accessible.
0554:             */
0555:            private void addAccessibilityDescriptions(Component wizPanel) {
0556:                final ResourceBundle bundle = NbBundle
0557:                        .getBundle(SimpleTestStepLocation.class);
0558:
0559:                tfClassToTest.setToolTipText(bundle
0560:                        .getString("SimpleTest.classToTest.toolTip")); //NOI18N
0561:                tfClassToTest.getAccessibleContext().setAccessibleName(
0562:                        bundle.getString("SimpleTest.classToTest.AN")); //NOI18N
0563:                tfClassToTest.getAccessibleContext().setAccessibleDescription(
0564:                        bundle.getString("SimpleTest.classToTest.AD")); //NOI18N
0565:
0566:                btnBrowse.setToolTipText(bundle
0567:                        .getString("SimpleTest.btnBrowse.toolTip")); //NOI18N
0568:                btnBrowse.getAccessibleContext().setAccessibleName(
0569:                        bundle.getString("SimpleTest.btnBrowse.AN")); //NOI18N
0570:                btnBrowse.getAccessibleContext().setAccessibleDescription(
0571:                        bundle.getString("SimpleTest.btnBrowse.AD")); //NOI18N
0572:
0573:                cboxLocation.setToolTipText(bundle
0574:                        .getString("SimpleTest.location.toolTip")); //NOI18N
0575:                cboxLocation.getAccessibleContext().setAccessibleName(
0576:                        bundle.getString("SimpleTest.location.AN")); //NOI18N
0577:                cboxLocation.getAccessibleContext().setAccessibleDescription(
0578:                        bundle.getString("SimpleTest.location.AD")); //NOI18N
0579:
0580:                wizPanel.getAccessibleContext().setAccessibleDescription(
0581:                        bundle.getString("SimpleTest.AD")); //NOI18N
0582:            }
0583:
0584:            /**
0585:             * <!-- PENDING -->
0586:             *
0587:             * @return  <code>true</code> if the selected item has changed,
0588:             *          <code>false</code> otherwise
0589:             */
0590:            private boolean updateLocationComboBox() {
0591:                Object[] srcRootsToOffer;
0592:
0593:                if ((allTestSourceGroups.length == 1) || (srcGroup == null)) {
0594:                    srcRootsToOffer = allTestSourceGroups;
0595:                } else {
0596:                    srcRootsToOffer = sourcesToTestsMap.get(srcGroup);
0597:                }
0598:
0599:                Object previousSelectedItem = cboxLocation.getSelectedItem();
0600:
0601:                ignoreCboxItemChanges = true;
0602:                try {
0603:                    Object[] items = createNamedItems(srcRootsToOffer);
0604:                    cboxLocation.setModel(new DefaultComboBoxModel(items));
0605:                    if (previousSelectedItem != null) {
0606:                        cboxLocation.setSelectedItem(previousSelectedItem);//may not process
0607:                    }
0608:                } finally {
0609:                    ignoreCboxItemChanges = false;
0610:                }
0611:
0612:                Object newSelectedItem = cboxLocation.getSelectedItem();
0613:
0614:                return !newSelectedItem.equals(previousSelectedItem);
0615:            }
0616:
0617:            /**
0618:             */
0619:            private static NamedObject[] createNamedItems(
0620:                    final Object[] srcRoots) {
0621:
0622:                //PENDING - should not the source groups be sorted (alphabetically)?
0623:                NamedObject[] items = new NamedObject[srcRoots.length];
0624:                for (int i = 0; i < srcRoots.length; i++) {
0625:                    String name = (srcRoots[i] instanceof  SourceGroup) ? ((SourceGroup) srcRoots[i])
0626:                            .getDisplayName()
0627:                            : (srcRoots[i] instanceof  FileObject) ? FileUtil
0628:                                    .getFileDisplayName((FileObject) srcRoots[i])
0629:                                    : srcRoots[i].toString();
0630:                    items[i] = new NamedObject(srcRoots[i], name);
0631:                }
0632:                return items;
0633:            }
0634:
0635:            /**
0636:             */
0637:            private void setUpInteraction() {
0638:
0639:                class UIListener implements  ActionListener, DocumentListener,
0640:                        FocusListener, ItemListener {
0641:                    public void actionPerformed(ActionEvent e) {
0642:
0643:                        /* button Browse... pressed */
0644:
0645:                        chooseClass();
0646:                    }
0647:
0648:                    public void insertUpdate(DocumentEvent e) {
0649:                        classNameChanged();
0650:                    }
0651:
0652:                    public void removeUpdate(DocumentEvent e) {
0653:                        classNameChanged();
0654:                    }
0655:
0656:                    public void changedUpdate(DocumentEvent e) {
0657:                        classNameChanged();
0658:                    }
0659:
0660:                    public void focusGained(FocusEvent e) {
0661:                        Object source = e.getSource();
0662:                        if (source == tfClassToTest) {
0663:                            //tfClassToTest.getDocument().addDocumentListener(this);
0664:                        }
0665:                    }
0666:
0667:                    public void focusLost(FocusEvent e) {
0668:                        Object source = e.getSource();
0669:                        if (source == tfClassToTest) {
0670:                            //tfClassToTest.getDocument().removeDocumentListener(this);
0671:                            if (!e.isTemporary()) {
0672:                                tfClassToTestFocusLost(e);
0673:                            }
0674:                        } else if ((source == btnBrowse) && !e.isTemporary()) {
0675:                            btnBrowseFocusLost(e);
0676:                        }
0677:                    }
0678:
0679:                    public void itemStateChanged(ItemEvent e) {
0680:                        if (e.getSource() == cboxLocation) {
0681:                            if (!ignoreCboxItemChanges) {
0682:                                locationChanged();
0683:                            }
0684:                        } else {
0685:                            /*
0686:                             * source is one of the Method Access Levels ckeck-boxes
0687:                             */
0688:                            checkChkBoxesValidity();
0689:                            setValidity();
0690:                        }
0691:                    }
0692:                }
0693:
0694:                final UIListener listener = new UIListener();
0695:
0696:                btnBrowse.addActionListener(listener);
0697:                tfClassToTest.addFocusListener(listener);
0698:                btnBrowse.addFocusListener(listener);
0699:                cboxLocation.addItemListener(listener);
0700:                chkPublic.addItemListener(listener);
0701:                chkProtected.addItemListener(listener);
0702:                chkPackagePrivate.addItemListener(listener);
0703:                tfClassToTest.getDocument().addDocumentListener(listener);
0704:            }
0705:
0706:            /**
0707:             */
0708:            private void tfClassToTestFocusLost(FocusEvent e) {
0709:                final Component allowFocusGain = focusGainAllowedFor;
0710:                focusGainAllowedFor = null;
0711:
0712:                if (multipleSourceRoots && interactionRestrictionsActive
0713:                        && !interactionRestrictionsSuspended) {
0714:
0715:                    final Component opposite = e.getOppositeComponent();
0716:
0717:                    if ((allowFocusGain != null)
0718:                            && (opposite == allowFocusGain)) {
0719:                        return;
0720:                    }
0721:                    if (opposite == btnBrowse) {
0722:                        return;
0723:                    }
0724:                    if ((opposite instanceof  JLabel)
0725:                            && (((JLabel) opposite).getLabelFor() == tfClassToTest)) {
0726:                        /*
0727:                         * When a JLabel's mnemonic key is pressed, the JLabel gains focus
0728:                         * until the key is released again. That's why we must ignore such
0729:                         * focus transfers.
0730:                         */
0731:                        return;
0732:                    }
0733:
0734:                    if (!maybeDisplaySourceGroupChooser()) {
0735:
0736:                        /* send the request back to the Test to Class textfield: */
0737:                        tfClassToTest.requestFocus();
0738:                    }
0739:                }
0740:            }
0741:
0742:            /**
0743:             */
0744:            private void btnBrowseFocusLost(FocusEvent e) {
0745:                final Component allowFocusGain = focusGainAllowedFor;
0746:                focusGainAllowedFor = null;
0747:
0748:                if (multipleSourceRoots && interactionRestrictionsActive
0749:                        && !interactionRestrictionsSuspended) {
0750:
0751:                    final Component opposite = e.getOppositeComponent();
0752:
0753:                    if ((allowFocusGain != null)
0754:                            && (opposite == allowFocusGain)) {
0755:                        return;
0756:                    }
0757:                    if (opposite == tfClassToTest) {
0758:                        return;
0759:                    }
0760:                    if ((opposite instanceof  JLabel)
0761:                            && (((JLabel) opposite).getLabelFor() == tfClassToTest)) {
0762:                        /*
0763:                         * When a JLabel's mnemonic key is pressed, the JLabel gains focus
0764:                         * until the key is released again. That's why we must ignore such
0765:                         * focus transfers.
0766:                         */
0767:                        return;
0768:                    }
0769:
0770:                    if (!maybeDisplaySourceGroupChooser()) {
0771:
0772:                        /* send the request back to the Browse... button: */
0773:                        btnBrowse.requestFocus();
0774:                    }
0775:                }
0776:            }
0777:
0778:            /**
0779:             * <!-- PENDING -->
0780:             *
0781:             * @return  <code>false</code> if the SourceGroup chooser was displayed
0782:             *          and the user cancelled the choice; <code>true</code> otherwise
0783:             */
0784:            private boolean maybeDisplaySourceGroupChooser() {
0785:                assert multipleSourceRoots;
0786:
0787:                if (classExists && (srcGroup == null)) {
0788:                    SourceGroup[] candidates = findParentGroupCandidates();
0789:
0790:                    assert candidates.length != 0; //because the class exists
0791:
0792:                    if (candidates.length == 1) {
0793:                        setSelectedSrcGroup(candidates[0]);
0794:                        return true;
0795:                    } else {
0796:                        SourceGroup chosenSrcGroup = chooseSrcGroup(candidates);
0797:                        if (chosenSrcGroup != null) {
0798:                            setSelectedSrcGroup(chosenSrcGroup);
0799:                            return true;
0800:                        } else {
0801:                            return false;
0802:                        }
0803:                    }
0804:                } else {
0805:                    return true;
0806:                }
0807:            }
0808:
0809:            /**
0810:             * Displays a source root chooser which allows the user to choose
0811:             * a parent source root for the entered class name.
0812:             *
0813:             * @param  candidates  source roots to be offered to the user
0814:             * @return  the chosen source root,
0815:             *          or <code>null</code> if the user cancelled the choice
0816:             */
0817:            private SourceGroup chooseSrcGroup(final SourceGroup[] candidates) {
0818:                assert (candidates != null) && (candidates.length != 0);
0819:
0820:                final String[] rootNames = new String[candidates.length];
0821:                for (int i = 0; i < rootNames.length; i++) {
0822:                    rootNames[i] = candidates[i].getDisplayName();
0823:                }
0824:
0825:                final JButton btn = new JButton(NbBundle.getMessage(getClass(),
0826:                        "LBL_SelectBtn")); //NOI18N
0827:                final JList list = new JList(rootNames);
0828:                list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
0829:                list.setSelectedIndex(0);
0830:                list.addListSelectionListener(new ListSelectionListener() {
0831:                    public void valueChanged(ListSelectionEvent e) {
0832:                        btn.setEnabled(!list.isSelectionEmpty());
0833:                    }
0834:                });
0835:                JPanel panel = new JPanel(new BorderLayout(0, 0));
0836:                panel.add(list, BorderLayout.CENTER);
0837:                panel.setBorder(BorderFactory.createCompoundBorder(
0838:                        BorderFactory.createEmptyBorder(12, 12, 0, 12),
0839:                        BorderFactory.createBevelBorder(BevelBorder.LOWERED)));
0840:
0841:                String dialogTitle = NbBundle.getMessage(getClass(),
0842:                        "LBL_SourceRootChooserTitle"); //NOI18N
0843:                DialogDescriptor descriptor = new DialogDescriptor(
0844:                        panel, //component
0845:                        dialogTitle, //title
0846:                        true, //modal
0847:                        new Object[] { //options
0848:                        btn, NotifyDescriptor.CANCEL_OPTION },
0849:                        btn, //default option
0850:                        DialogDescriptor.DEFAULT_ALIGN, (HelpCtx) null,
0851:                        (ActionListener) null);
0852:                Object selected = DialogDisplayer.getDefault().notify(
0853:                        descriptor);
0854:                return (selected == btn) ? candidates[list.getSelectedIndex()]
0855:                        : (SourceGroup) null;
0856:            }
0857:
0858:            /**
0859:             */
0860:            private void setSelectedSrcGroup(SourceGroup srcGroup) {
0861:                setSelectedSrcGroup(srcGroup, true);
0862:            }
0863:
0864:            /**
0865:             * <!-- PENDING -->
0866:             */
0867:            private void setSelectedSrcGroup(SourceGroup srcGroup,
0868:                    boolean updateDisp) {
0869:                assert multipleSourceRoots
0870:                        && ((srcGroup == null) || (classNameValid && classExists));
0871:
0872:                if (!checkObjChanged(this .srcGroup, srcGroup)) {
0873:                    return;
0874:                }
0875:
0876:                this .srcGroup = srcGroup;
0877:
0878:                if (updateDisp) {
0879:
0880:                    /* update the display: */
0881:                    try {
0882:                        programmaticChange = true;
0883:
0884:                        String className = tfClassToTest.getText().substring(0,
0885:                                classNameLength);
0886:                        String srcGroupDisplay = getSrcGrpDisp(srcGroup);
0887:
0888:                        ignoreClsNameChanges = true;
0889:                        tfClassToTest.setText(className + srcGroupDisplay);
0890:                        ignoreClsNameChanges = false;
0891:
0892:                        classNameLength = className.length();
0893:                        classNameChanged();
0894:                        srcGroupNameDisplayed = true;
0895:                        setNavigationFilterEnabled(true);
0896:                    } finally {
0897:                        ignoreClsNameChanges = false;
0898:                        programmaticChange = false;
0899:                    }
0900:                }
0901:
0902:                updateInteractionRestrictionsState();
0903:
0904:                /*
0905:                 * There is no need to check and set validity.
0906:                 * The user should be offered to choose a source root only when
0907:                 * the entered class name is valid and the class exists
0908:                 * in at least two source roots.
0909:                 */
0910:
0911:                /* update target folder: */
0912:                if (allTestSourceGroups.length > 1) {
0913:                    boolean locationChanged = updateLocationComboBox();
0914:                    if (locationChanged) {
0915:                        updateTargetFolderData();
0916:                    }
0917:                }
0918:
0919:                /* update name of the file to be created: */
0920:                updateCreatedFileName();
0921:
0922:                /* set 'srcFile': */
0923:                srcFile = (srcGroup != null) ? srcGroup.getRootFolder()
0924:                        .getFileObject(srcRelFileNameSys) : null;
0925:
0926:                assert (srcGroup == null) || (srcFile != null);
0927:            }
0928:
0929:            /**
0930:             */
0931:            private static String getSrcGrpDisp(SourceGroup srcGroup) {
0932:                if (srcGroup == null) {
0933:                    return ""; //NOI18N
0934:                } else {
0935:                    String srcGroupName = srcGroup.getDisplayName();
0936:                    return new StringBuffer(srcGroupName.length() + 3).append(
0937:                            ' ').append('(').append(srcGroupName).append(')')
0938:                            .toString();
0939:                }
0940:            }
0941:
0942:            /**
0943:             */
0944:            private void setNavigationFilterEnabled(boolean enabled) {
0945:                if (enabled == navigationFilterEnabled) {
0946:                    if (enabled) {
0947:                        clsNameNavigationFilter.ensureCursorInRange();
0948:                    }
0949:                    return;
0950:                }
0951:
0952:                if (enabled) {
0953:                    if (clsNameNavigationFilter == null) {
0954:                        clsNameNavigationFilter = new ClsNameNavigationFilter();
0955:                    }
0956:                    tfClassToTest.setNavigationFilter(clsNameNavigationFilter);
0957:                    clsNameNavigationFilter.ensureCursorInRange();
0958:                } else {
0959:                    tfClassToTest.setNavigationFilter(null);
0960:                }
0961:                this .navigationFilterEnabled = enabled;
0962:            }
0963:
0964:            /**
0965:             * <!-- PENDING -->
0966:             */
0967:            private void updateInteractionRestrictionsState() {
0968:                setInteractionRestrictionsSuspended(!classNameValid
0969:                        || !classExists || (srcGroup != null));
0970:            }
0971:
0972:            /**
0973:             */
0974:            private void updateTargetFolderData() {
0975:                Object item = cboxLocation.getSelectedItem();
0976:                if (item != null) {
0977:                    SourceGroup targetSourceGroup = (SourceGroup) ((NamedObject) item).object;
0978:                    testRootFolder = targetSourceGroup.getRootFolder();
0979:                    testsRootDirName = FileUtil
0980:                            .getFileDisplayName(testRootFolder);
0981:                } else {
0982:                    testRootFolder = null;
0983:                    testsRootDirName = ""; //NOI18N
0984:                }
0985:            }
0986:
0987:            /**
0988:             * Called whenever selection in the Location combo-box is changed.
0989:             */
0990:            private void locationChanged() {
0991:                updateTargetFolderData();
0992:                updateCreatedFileName();
0993:            }
0994:
0995:            /**
0996:             */
0997:            private void classNameChanged() {
0998:                if (ignoreClsNameChanges) {
0999:                    return;
1000:                }
1001:
1002:                String className;
1003:                if (!programmaticChange) {
1004:                    className = tfClassToTest.getText().trim();
1005:                    classNameLength = className.length();
1006:                } else {
1007:                    className = tfClassToTest.getText().substring(0,
1008:                            classNameLength);
1009:                }
1010:
1011:                String testClassName;
1012:                if (className.length() != 0) {
1013:                    srcRelFileNameSys = className.replace('.', '/') + ".java"; //NOI18N
1014:                    testClassName = className + testClassNameSuffix;
1015:                    testRelFileName = testClassName.replace('.',
1016:                            File.separatorChar)
1017:                            + ".java"; //NOI18N
1018:                } else {
1019:                    srcRelFileNameSys = ""; //NOI18N
1020:                    testClassName = ""; //NOI18N
1021:                    testRelFileName = ""; //NOI18N
1022:                }
1023:                tfTestClass.setText(testClassName);
1024:
1025:                if (!programmaticChange) {
1026:                    updateCreatedFileName();
1027:                    if (checkClassNameValidity()) {
1028:                        checkSelectedClassExists();
1029:                    }
1030:                    setErrorMsg(msgStack.getDisplayedMessage());
1031:                    setValidity();
1032:
1033:                    /*
1034:                     * The user modified the class name.
1035:                     * It may be ambiguous - it may match classes in multiple SourceGroups.
1036:                     */
1037:                    if (multipleSourceRoots) {
1038:                        setSelectedSrcGroup(null, false);
1039:                    }
1040:                }
1041:
1042:                if (multipleSourceRoots) {
1043:                    updateInteractionRestrictionsState();
1044:                }
1045:            }
1046:
1047:            /**
1048:             * Identifies all <code>SourceGroup</code>s containing file having the
1049:             * name entered by the user.
1050:             * This method assumes that at least one such <code>SourceGroup</code>
1051:             * has already been found and its index stored in field
1052:             * {@link #sourceGroupParentIndex}.
1053:             *
1054:             * @return  array of matching <code>SourceGroup</code>s
1055:             *          (always contains at least one element)
1056:             */
1057:            private SourceGroup[] findParentGroupCandidates() {
1058:                assert sourceGroupParentIndex >= 0;
1059:
1060:                List<SourceGroup> cands = null;
1061:                final int count = testableSourceGroups.length;
1062:                for (int i = sourceGroupParentIndex + 1; i < count; i++) {
1063:                    final FileObject groupRoot = testableSourceGroupsRoots[i];
1064:                    FileObject srcFile = groupRoot
1065:                            .getFileObject(srcRelFileNameSys);
1066:                    if (srcFile != null
1067:                            && testableSourceGroups[i].contains(srcFile)) {
1068:                        if (cands == null) {
1069:                            cands = new ArrayList<SourceGroup>(
1070:                                    testableSourceGroups.length - i + 1);
1071:                            cands
1072:                                    .add(testableSourceGroups[sourceGroupParentIndex]);
1073:                        }
1074:                        cands.add(testableSourceGroups[i]);
1075:                    }
1076:                }
1077:                return cands == null ? new SourceGroup[] { testableSourceGroups[sourceGroupParentIndex] }
1078:                        : cands.toArray(new SourceGroup[cands.size()]);
1079:            }
1080:
1081:            /**
1082:             */
1083:            private void updateCreatedFileName() {
1084:                tfCreatedFile.setText(testsRootDirName + File.separatorChar
1085:                        + testRelFileName);
1086:            }
1087:
1088:            /**
1089:             * Checks validity of the entered class name, updates messages
1090:             * on the message stack and updates the <code>classNameValid</code> field.
1091:             *
1092:             * @see  #msgStack
1093:             * @see  #setValidity()
1094:             */
1095:            private boolean checkClassNameValidity() {
1096:                String className = tfClassToTest.getText().trim();
1097:                if (srcGroupNameDisplayed) {
1098:                    className = className.substring(0, classNameLength);
1099:                }
1100:
1101:                if (className.length() == 0) {
1102:                    msgStack.clearMessage(MSG_LAYER_CLASSNAME);
1103:                    classNameValid = false;
1104:                } else if (Utils.isValidClassName(className)) {
1105:                    msgStack.clearMessage(MSG_LAYER_CLASSNAME);
1106:                    classNameValid = true;
1107:                } else {
1108:                    if (msgClassNameInvalid == null) {
1109:                        msgClassNameInvalid = NbBundle.getMessage(
1110:                                JUnitCfgOfCreate.class, "MSG_InvalidClassName"); //NOI18N
1111:                    }
1112:                    msgStack.setMessage(MSG_LAYER_CLASSNAME,
1113:                            msgClassNameInvalid);
1114:                    classNameValid = false;
1115:                }
1116:
1117:                return classNameValid;
1118:            }
1119:
1120:            /**
1121:             * Checks whether a class having the entered name exists, updates messages
1122:             * on the message stack and updates the <code>classExists</code> field.
1123:             *
1124:             * @see  #setValidity()
1125:             */
1126:            private boolean checkSelectedClassExists() {
1127:                sourceGroupParentIndex = -1;
1128:
1129:                final int count = testableSourceGroups.length;
1130:                for (int i = 0; i < count; i++) {
1131:                    final FileObject groupRoot = testableSourceGroupsRoots[i];
1132:                    FileObject srcFile = groupRoot
1133:                            .getFileObject(srcRelFileNameSys);
1134:                    if (srcFile != null
1135:                            && testableSourceGroups[i].contains(srcFile)) {
1136:                        this .srcFile = srcFile;
1137:                        sourceGroupParentIndex = i;
1138:                        break;
1139:                    }
1140:                }
1141:
1142:                classExists = (sourceGroupParentIndex != -1);
1143:
1144:                if (classExists) {
1145:                    msgStack.clearMessage(MSG_LAYER_CLASSNAME);
1146:                } else {
1147:                    if (msgClassToTestDoesNotExist == null) {
1148:                        msgClassToTestDoesNotExist = NbBundle.getMessage(
1149:                                SimpleTestStepLocation.class,
1150:                                "MSG_ClassToTestDoesNotExist"); //NOI18N
1151:                    }
1152:                    msgStack.setMessage(MSG_LAYER_CLASSNAME,
1153:                            msgClassToTestDoesNotExist);
1154:                }
1155:
1156:                return classExists;
1157:            }
1158:
1159:            /**
1160:             * Checks whether at least one of the <em>Method Access Levels</em>
1161:             * checkboxes is selected, updates messages
1162:             * on the message stack and updates the <code>chkBoxesValid</code> field.
1163:             *
1164:             * @see  #setValidity()
1165:             */
1166:            private boolean checkChkBoxesValidity() {
1167:                chkBoxesValid = chkPublic.isSelected()
1168:                        || chkProtected.isSelected()
1169:                        || chkPackagePrivate.isSelected();
1170:                String msgUpdate;
1171:                if (chkBoxesValid) {
1172:                    msgUpdate = msgStack.clearMessage(MSG_LAYER_CHECKBOXES);
1173:                } else {
1174:                    if (msgChkBoxesInvalid == null) {
1175:                        //PENDING - text of the message:
1176:                        msgChkBoxesInvalid = NbBundle.getMessage(
1177:                                JUnitCfgOfCreate.class,
1178:                                "MSG_AllMethodTypesDisabled"); //NOI18N
1179:                    }
1180:                    msgUpdate = msgStack.setMessage(MSG_LAYER_CHECKBOXES,
1181:                            msgChkBoxesInvalid);
1182:                }
1183:                if (msgUpdate != null) {
1184:                    setErrorMsg(msgStack.getDisplayedMessage());
1185:                }
1186:                return chkBoxesValid;
1187:            }
1188:
1189:            /**
1190:             * Updates the <code>isValid</code> field and notifies all registered
1191:             * <code>ChangeListener</code>s if validity has changed.
1192:             */
1193:            private void setValidity() {
1194:                boolean wasValid = isValid;
1195:
1196:                isValid = classNameValid && classExists && chkBoxesValid;
1197:
1198:                if (isValid != wasValid) {
1199:                    fireChange();
1200:
1201:                    updateInteractionRestrictionsState();
1202:
1203:                    /*
1204:                     * This must be called after fireChange() because fireChange()
1205:                     * sets state (enabled/disabled) of the default button.
1206:                     */
1207:                    if (isValid && interactionRestrictionsEnabled
1208:                            && !interactionRestrictionsActive) {
1209:                        tryActivateInteractionRestrictions();
1210:                    }
1211:                }
1212:            }
1213:
1214:            /**
1215:             * Displays the given message in the wizard's message area.
1216:             *
1217:             * @param  message  message to be displayed, or <code>null</code>
1218:             *                  if the message area should be cleared
1219:             */
1220:            private void setErrorMsg(String message) {
1221:                if (wizard != null) {
1222:                    wizard.putProperty("WizardPanel_errorMessage", message); //NOI18N
1223:                }
1224:            }
1225:
1226:            /**
1227:             * Displays a class chooser dialog and lets the user to select a class.
1228:             * If the user confirms their choice, full name of the selected class
1229:             * is put into the <em>Class To Test</em> text field.
1230:             */
1231:            private void chooseClass() {
1232:                try {
1233:                    final Node[] sourceGroupNodes = new Node[testableSourceGroups.length];
1234:                    for (int i = 0; i < sourceGroupNodes.length; i++) {
1235:                        /*
1236:                         * Note:
1237:                         * Precise structure of this view is *not* specified by the API.
1238:                         */
1239:                        Node srcGroupNode = PackageView
1240:                                .createPackageView(testableSourceGroups[i]);
1241:                        sourceGroupNodes[i] = new FilterNode(srcGroupNode,
1242:                                new JavaChildren(srcGroupNode));
1243:                    }
1244:
1245:                    Node rootNode;
1246:                    if (sourceGroupNodes.length == 1) {
1247:                        rootNode = new FilterNode(sourceGroupNodes[0],
1248:                                new JavaChildren(sourceGroupNodes[0]));
1249:                    } else {
1250:                        Children children = new Children.Array();
1251:                        children.add(sourceGroupNodes);
1252:
1253:                        AbstractNode node = new AbstractNode(children);
1254:                        node.setName("Project Source Roots"); //NOI18N
1255:                        node.setDisplayName(NbBundle.getMessage(getClass(),
1256:                                "LBL_Sources"));//NOI18N
1257:                        //PENDING - set a better icon for the root node
1258:                        rootNode = node;
1259:                    }
1260:
1261:                    NodeAcceptor acceptor = new NodeAcceptor() {
1262:                        public boolean acceptNodes(Node[] nodes) {
1263:                            Node.Cookie cookie;
1264:                            return nodes.length == 1
1265:                                    && (cookie = nodes[0]
1266:                                            .getCookie(DataObject.class)) != null
1267:                                    && ((DataObject) cookie).getPrimaryFile()
1268:                                            .isFolder() == false;
1269:                        }
1270:                    };
1271:
1272:                    Node selectedNode = NodeOperation.getDefault().select(
1273:                            NbBundle.getMessage(SimpleTestStepLocation.class,
1274:                                    "LBL_WinTitle_SelectClass"), //NOI18N
1275:                            NbBundle.getMessage(SimpleTestStepLocation.class,
1276:                                    "LBL_SelectClassToTest"), //NOI18N
1277:                            rootNode, acceptor)[0];
1278:
1279:                    SourceGroup selectedSourceGroup;
1280:                    if (sourceGroupNodes.length == 1) {
1281:                        selectedSourceGroup = testableSourceGroups[0];
1282:                    } else {
1283:                        Node previous = null;
1284:                        Node current = selectedNode.getParentNode();
1285:                        Node parent;
1286:                        while ((parent = current.getParentNode()) != null) {
1287:                            previous = current;
1288:                            current = parent;
1289:                        }
1290:                        /*
1291:                         * 'current' now contains the root node of displayed node
1292:                         * hierarchy. 'current' contains a parent node of the source
1293:                         * root and 'previous' contains the parent source root of
1294:                         * the selected class.
1295:                         */
1296:                        selectedSourceGroup = null;
1297:                        Node selectedSrcGroupNode = previous;
1298:                        for (int i = 0; i < sourceGroupNodes.length; i++) {
1299:                            if (sourceGroupNodes[i] == selectedSrcGroupNode) {
1300:                                selectedSourceGroup = testableSourceGroups[i];
1301:                                sourceGroupParentIndex = i;
1302:                                break;
1303:                            }
1304:                        }
1305:                        assert selectedSourceGroup != null;
1306:                        assert sourceGroupParentIndex >= 0;
1307:                    }
1308:                    srcGroup = selectedSourceGroup;
1309:
1310:                    FileObject selectedFileObj = selectedNode.getCookie(
1311:                            DataObject.class).getPrimaryFile();
1312:
1313:                    /* display selected class name: */
1314:                    try {
1315:                        programmaticChange = true;
1316:
1317:                        String className = getClassName(selectedFileObj);
1318:                        classNameLength = className.length();
1319:                        if (!multipleSourceRoots) {
1320:                            /*
1321:                             * Caution! Calling setText("className") triggers two
1322:                             * text change events - once when the original text is
1323:                             * cleared and the second time when the new text is set.
1324:                             * Method classNameChanged() must only be called when the
1325:                             * text change is complete (see issue #91794) so we set
1326:                             * the 'ignoreClsNameChanges' flag for the time the text
1327:                             * is being changed and then call the classNameChanged()
1328:                             * explicitely.
1329:                             */
1330:                            ignoreClsNameChanges = true;
1331:                            tfClassToTest.setText(className);
1332:                            ignoreClsNameChanges = false;
1333:                            classNameChanged();
1334:                        } else {
1335:                            String srcGroupDisplay = getSrcGrpDisp(selectedSourceGroup);
1336:
1337:                            ignoreClsNameChanges = true;
1338:                            tfClassToTest.setText(className + srcGroupDisplay);
1339:                            ignoreClsNameChanges = false;
1340:
1341:                            classNameLength = className.length();
1342:                            classNameChanged();
1343:                            srcGroupNameDisplayed = true;
1344:                            setNavigationFilterEnabled(true);
1345:                        }
1346:                        /*
1347:                         * Change of text of the Class to Test text-field triggers
1348:                         * update of variable 'testRelFileName'.
1349:                         */
1350:                    } finally {
1351:                        ignoreClsNameChanges = false;
1352:                        programmaticChange = false;
1353:                    }
1354:
1355:                    /* set class name validity: */
1356:                    classNameValid = true;
1357:                    classExists = true;
1358:                    String msgUpdate = msgStack
1359:                            .clearMessage(MSG_LAYER_CLASSNAME);
1360:                    if (msgUpdate != null) {
1361:                        setErrorMsg(msgUpdate);
1362:                    }
1363:                    setValidity();
1364:                    updateInteractionRestrictionsState();
1365:
1366:                    /* update target folder: */
1367:                    if (multipleSourceRoots && (allTestSourceGroups.length > 1)) {
1368:                        boolean locationChanged = updateLocationComboBox();
1369:                        if (locationChanged) {
1370:                            updateTargetFolderData(); //sets also 'testRootFolder'
1371:                        }
1372:                    }
1373:
1374:                    /* update name of the file to be created: */
1375:                    updateCreatedFileName();
1376:
1377:                    /* set 'srcFile': */
1378:                    srcFile = selectedFileObj;
1379:
1380:                } catch (UserCancelException ex) {
1381:                    // if the user cancels the choice, do nothing
1382:                }
1383:            }
1384:
1385:            private static String getClassName(FileObject fileObj) {
1386:                //PENDING: is it ensured that the classpath is non-null?
1387:                return ClassPath.getClassPath(fileObj, ClassPath.SOURCE)
1388:                        .getResourceName(fileObj, '.', false);
1389:            }
1390:
1391:            public Component getComponent() {
1392:                return visualComp;
1393:            }
1394:
1395:            public boolean isValid() {
1396:                return isValid;
1397:            }
1398:
1399:            public HelpCtx getHelp() {
1400:                //PENDINGg
1401:                return null;
1402:            }
1403:
1404:            public void readSettings(WizardDescriptor settings) {
1405:                wizard = settings;
1406:
1407:                chkPublic.setSelected(Boolean.TRUE.equals(wizard
1408:                        .getProperty(GuiUtils.CHK_PUBLIC)));
1409:                chkProtected.setSelected(Boolean.TRUE.equals(wizard
1410:                        .getProperty(GuiUtils.CHK_PROTECTED)));
1411:                chkPackagePrivate.setSelected(Boolean.TRUE.equals(wizard
1412:                        .getProperty(GuiUtils.CHK_PACKAGE)));
1413:                chkSetUp.setSelected(Boolean.TRUE.equals(wizard
1414:                        .getProperty(GuiUtils.CHK_SETUP)));
1415:                chkTearDown.setSelected(Boolean.TRUE.equals(wizard
1416:                        .getProperty(GuiUtils.CHK_TEARDOWN)));
1417:                chkMethodBodies.setSelected(Boolean.TRUE.equals(wizard
1418:                        .getProperty(GuiUtils.CHK_METHOD_BODIES)));
1419:                chkJavadoc.setSelected(Boolean.TRUE.equals(wizard
1420:                        .getProperty(GuiUtils.CHK_JAVADOC)));
1421:                chkHints.setSelected(Boolean.TRUE.equals(wizard
1422:                        .getProperty(GuiUtils.CHK_HINTS)));
1423:            }
1424:
1425:            public void storeSettings(WizardDescriptor settings) {
1426:                wizard = settings;
1427:
1428:                wizard.putProperty(SimpleTestCaseWizard.PROP_CLASS_TO_TEST,
1429:                        srcFile);
1430:                wizard.putProperty(SimpleTestCaseWizard.PROP_TEST_ROOT_FOLDER,
1431:                        testRootFolder);
1432:                wizard.putProperty(GuiUtils.CHK_PUBLIC, Boolean
1433:                        .valueOf(chkPublic.isSelected()));
1434:                wizard.putProperty(GuiUtils.CHK_PROTECTED, Boolean
1435:                        .valueOf(chkProtected.isSelected()));
1436:                wizard.putProperty(GuiUtils.CHK_PACKAGE, Boolean
1437:                        .valueOf(chkPackagePrivate.isSelected()));
1438:                wizard.putProperty(GuiUtils.CHK_SETUP, Boolean.valueOf(chkSetUp
1439:                        .isSelected()));
1440:                wizard.putProperty(GuiUtils.CHK_TEARDOWN, Boolean
1441:                        .valueOf(chkTearDown.isSelected()));
1442:                wizard.putProperty(GuiUtils.CHK_METHOD_BODIES, Boolean
1443:                        .valueOf(chkMethodBodies.isSelected()));
1444:                wizard.putProperty(GuiUtils.CHK_JAVADOC, Boolean
1445:                        .valueOf(chkJavadoc.isSelected()));
1446:                wizard.putProperty(GuiUtils.CHK_HINTS, Boolean.valueOf(chkHints
1447:                        .isSelected()));
1448:            }
1449:
1450:            public void addChangeListener(ChangeListener l) {
1451:                if (changeListeners == null) {
1452:                    changeListeners = new ArrayList<ChangeListener>(4);
1453:                }
1454:                changeListeners.add(l);
1455:            }
1456:
1457:            public void removeChangeListener(ChangeListener l) {
1458:                if (changeListeners != null) {
1459:                    if (changeListeners.remove(l) && changeListeners.isEmpty()) {
1460:                        changeListeners = null;
1461:                    }
1462:                }
1463:            }
1464:
1465:            private void fireChange() {
1466:                if (changeListeners != null) {
1467:                    ChangeEvent e = new ChangeEvent(this );
1468:                    for (ChangeListener l : changeListeners) {
1469:                        l.stateChanged(e);
1470:                    }
1471:                }
1472:            }
1473:
1474:            /**
1475:             */
1476:            void setUp(final Utils utils) {
1477:                final Project project = utils.getProject();
1478:
1479:                if (project == this .project) {
1480:                    return;
1481:                }
1482:
1483:                this .project = project;
1484:                this .sourcesToTestsMap = utils.getSourcesToTestsMap(true);
1485:
1486:                int sourceGroupsCnt = sourcesToTestsMap.size();
1487:                Set<Map.Entry<SourceGroup, Object[]>> mapEntries = sourcesToTestsMap
1488:                        .entrySet();
1489:                List<SourceGroup> testGroups = new ArrayList<SourceGroup>(
1490:                        sourceGroupsCnt + 4);
1491:
1492:                testableSourceGroups = new SourceGroup[sourceGroupsCnt];
1493:                testableSourceGroupsRoots = new FileObject[sourceGroupsCnt];
1494:                multipleSourceRoots = (sourceGroupsCnt > 1);
1495:
1496:                Iterator<Map.Entry<SourceGroup, Object[]>> iterator = mapEntries
1497:                        .iterator();
1498:                for (int i = 0; i < sourceGroupsCnt; i++) {
1499:                    Map.Entry<SourceGroup, Object[]> entry = iterator.next();
1500:                    SourceGroup srcGroup = entry.getKey();
1501:
1502:                    testableSourceGroups[i] = srcGroup;
1503:                    testableSourceGroupsRoots[i] = srcGroup.getRootFolder();
1504:
1505:                    Object[] testGroupsSubset = entry.getValue();
1506:                    for (int j = 0; j < testGroupsSubset.length; j++) {
1507:                        SourceGroup testGroup = (SourceGroup) testGroupsSubset[j];
1508:                        if (!testGroups.contains(testGroup)) {
1509:                            testGroups.add(testGroup);
1510:                        }
1511:                    }
1512:                }
1513:                allTestSourceGroups = testGroups
1514:                        .toArray(new SourceGroup[testGroups.size()]);
1515:
1516:                tfProjectName.setText(ProjectUtils.getInformation(project)
1517:                        .getDisplayName());
1518:                try {
1519:                    programmaticChange = true;
1520:
1521:                    ignoreClsNameChanges = true;
1522:                    tfClassToTest.setText(""); //NOI18N
1523:                    ignoreClsNameChanges = false;
1524:
1525:                    classNameLength = 0;
1526:                    classNameChanged();
1527:                    srcGroupNameDisplayed = false;
1528:                    setNavigationFilterEnabled(false);
1529:                } finally {
1530:                    ignoreClsNameChanges = false;
1531:                    programmaticChange = false;
1532:                }
1533:                if (checkClassNameValidity()) {
1534:                    checkSelectedClassExists();
1535:                } else {
1536:                    classExists = false;
1537:                }
1538:                setErrorMsg(msgStack.getDisplayedMessage());
1539:                setValidity();
1540:
1541:                //PENDING - if possible, we should pre-set the test source group
1542:                //          corresponding to the currently selected node
1543:                updateLocationComboBox();
1544:                updateTargetFolderData(); //sets also 'testRootFolder'
1545:                updateCreatedFileName();
1546:
1547:                srcFile = null;
1548:
1549:                if (!multipleSourceRoots) {
1550:                    setInteractionRestrictionsEnabled(false);
1551:                } else {
1552:                    AbstractDocument doc = (AbstractDocument) tfClassToTest
1553:                            .getDocument();
1554:                    if (clsNameDocumentFilter == null) {
1555:                        clsNameDocumentFilter = new ClsNameDocumentFilter();
1556:                    }
1557:                    if (doc.getDocumentFilter() != clsNameDocumentFilter) {
1558:                        doc.setDocumentFilter(clsNameDocumentFilter);
1559:                    }
1560:                    setInteractionRestrictionsEnabled(true);
1561:                }
1562:            }
1563:
1564:            /**
1565:             */
1566:            void cleanUp() {
1567:                setInteractionRestrictionsEnabled(false);
1568:            }
1569:
1570:            /**
1571:             * <!-- PENDING -->
1572:             */
1573:            private void setInteractionRestrictionsEnabled(boolean enabled) {
1574:                if (enabled == interactionRestrictionsEnabled) {
1575:                    return;
1576:                }
1577:
1578:                class DisplayabilityListener implements  HierarchyListener {
1579:                    public void hierarchyChanged(HierarchyEvent e) {
1580:                        long flags = e.getChangeFlags();
1581:                        if ((flags & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
1582:                            if (visualComp.isDisplayable()) {
1583:                                if (interactionRestrictionsEnabled) {
1584:                                    setInteractionRestrictionsActive(true);
1585:                                }
1586:                            } else {
1587:                                setInteractionRestrictionsActive(false);
1588:                            }
1589:                        }
1590:                    }
1591:                }
1592:
1593:                if (enabled) {
1594:                    this .interactionRestrictionsEnabled = true;
1595:
1596:                    assert displayabilityListener == null;
1597:                    displayabilityListener = new DisplayabilityListener();
1598:                    visualComp.addHierarchyListener(displayabilityListener);
1599:
1600:                    if (visualComp.isDisplayable()) {
1601:                        setInteractionRestrictionsActive(true);
1602:                    }
1603:                } else {
1604:                    this .interactionRestrictionsEnabled = false;
1605:
1606:                    setInteractionRestrictionsActive(false);
1607:
1608:                    visualComp.removeHierarchyListener(displayabilityListener);
1609:                    displayabilityListener = null;
1610:                }
1611:            }
1612:
1613:            /**
1614:             * Activates or deactivates the focus detection mechanism.
1615:             * <!-- PENDING -->
1616:             */
1617:            private void setInteractionRestrictionsActive(boolean active) {
1618:                if (active == this .interactionRestrictionsActive) {
1619:                    return;
1620:                }
1621:
1622:                if (active) {
1623:                    tryActivateInteractionRestrictions();
1624:                } else {
1625:                    deactivateInteractionRestrictions();
1626:                }
1627:            }
1628:
1629:            /**
1630:             */
1631:            private void tryActivateInteractionRestrictions() {
1632:                assert interactionRestrictionsActive == false;
1633:                assert interactionRestrictionsEnabled;
1634:
1635:                if (rootPane == null) {
1636:                    rootPane = SwingUtilities.getRootPane(visualComp);
1637:                }
1638:
1639:                if (rootPane != null) {
1640:                    defaultButton = rootPane.getDefaultButton();
1641:                    if (defaultButton != null) {
1642:                        activateInteractionRestrictions();
1643:                    }
1644:                }
1645:            }
1646:
1647:            /**
1648:             */
1649:            private void activateInteractionRestrictions() {
1650:                assert interactionRestrictionsActive == false;
1651:                assert (rootPane != null) && (defaultButton != null);
1652:
1653:                if ((mouseBlocked == null) || (mnemonicBlocked == null)) {
1654:                    findComponentsToBlock();
1655:                    assert (mouseBlocked != null) && (mnemonicBlocked != null);
1656:                }
1657:                blockDefaultRootPaneAction();
1658:                blockMnemonics();
1659:                setMouseClicksBlockingActive(!interactionRestrictionsSuspended);
1660:
1661:                interactionRestrictionsActive = true;
1662:            }
1663:
1664:            /**
1665:             */
1666:            private void deactivateInteractionRestrictions() {
1667:                assert interactionRestrictionsActive == true;
1668:                assert (defaultButton != null) && (rootPane != null);
1669:
1670:                setMouseClicksBlockingActive(false);
1671:                unblockMnemonics();
1672:                unblockDefaultRootPaneAction();
1673:
1674:                defaultButton = null;
1675:                rootPane = null;
1676:
1677:                interactionRestrictionsActive = false;
1678:                interactionRestrictionsSuspended = false;
1679:            }
1680:
1681:            /**
1682:             */
1683:            private void setInteractionRestrictionsSuspended(boolean suspended) {
1684:                if (suspended != this .interactionRestrictionsSuspended) {
1685:                    setMouseClicksBlockingActive(interactionRestrictionsActive
1686:                            && !suspended);
1687:                    this .interactionRestrictionsSuspended = suspended;
1688:                }
1689:            }
1690:
1691:            /**
1692:             */
1693:            private void setMouseClicksBlockingActive(boolean blockingActive) {
1694:                if (blockingActive != this .mouseClicksBlocked) {
1695:                    if (blockingActive) {
1696:                        blockMouseClicks();
1697:                    } else {
1698:                        unblockMouseClicks();
1699:                    }
1700:                    this .mouseClicksBlocked = blockingActive;
1701:                }
1702:            }
1703:
1704:            /**
1705:             * Searches the visual component and collects components
1706:             * on which mouse events or activation by mnemonics needs to be check
1707:             * and evaluated.
1708:             *
1709:             * @see  #mouseBlocked
1710:             * @see  #mnemonicBlocked
1711:             */
1712:            private void findComponentsToBlock() {
1713:                assert rootPane != null;
1714:
1715:                final Collection<Component> mouseBlocked = new ArrayList<Component>(
1716:                        20);
1717:                final Collection<JComponent> mnemBlocked = new ArrayList<JComponent>(
1718:                        20);
1719:
1720:                final List<Component> stack = new ArrayList<Component>(16);
1721:                stack.add(rootPane.getContentPane());
1722:                int lastIndex = 0;
1723:
1724:                while (lastIndex != -1) {
1725:
1726:                    Component c = stack.remove(lastIndex--);
1727:
1728:                    if (!c.isVisible()) {
1729:                        continue;
1730:                    }
1731:
1732:                    if (c instanceof  JLabel) {
1733:                        JLabel lbl = (JLabel) c;
1734:                        Component labelFor = lbl.getLabelFor();
1735:                        if ((labelFor != null) && (labelFor != tfClassToTest)
1736:                                && (lbl.getDisplayedMnemonic() != 0)) {
1737:                            mnemBlocked.add(lbl);
1738:                        }
1739:                    } else if (c instanceof  AbstractButton) {
1740:                        if (c != btnBrowse) {
1741:                            AbstractButton btn = (AbstractButton) c;
1742:                            mouseBlocked.add(btn);
1743:                            if (btn.getMnemonic() != 0) {
1744:                                mnemBlocked.add(btn);
1745:                            }
1746:                        }
1747:                    } else if (!(c instanceof  Container)) {
1748:                        if (c.isFocusable() && (c != tfClassToTest)) {
1749:                            mouseBlocked.add(c);
1750:                        }
1751:                    } else {
1752:                        Component[] content = ((Container) c).getComponents();
1753:                        switch (content.length) {
1754:                        case 0:
1755:                            break;
1756:                        case 1:
1757:                            stack.add(content[0]);
1758:                            lastIndex++;
1759:                            break;
1760:                        default:
1761:                            stack.addAll(Arrays.asList(content));
1762:                            lastIndex += content.length;
1763:                            break;
1764:                        }
1765:                    }
1766:                }
1767:                //mouseBlocked.add(defaultButton);
1768:                //mnemBlocked.add(defaultButton);
1769:
1770:                this .mouseBlocked = new Component[mouseBlocked.size()];
1771:                if (mouseBlocked.size() != 0) {
1772:                    mouseBlocked.toArray(this .mouseBlocked);
1773:                }
1774:                this .mnemonicBlocked = new JComponent[mnemBlocked.size()];
1775:                if (mnemBlocked.size() != 0) {
1776:                    mnemBlocked.toArray(this .mnemonicBlocked);
1777:                }
1778:            }
1779:
1780:            /**
1781:             */
1782:            private void blockDefaultRootPaneAction() {
1783:                assert (rootPane != null) && (defaultButton != null)
1784:                        && (rootPane.getDefaultButton() == defaultButton);
1785:
1786:                final String actionKey1 = "press"; //NOI18N
1787:                final String actionKey2 = "pressed"; //NOI18N
1788:                String actionKey;
1789:
1790:                ActionMap actionMap = rootPane.getActionMap();
1791:
1792:                Action originalAction = actionMap.get(actionKey = actionKey1);
1793:                if (originalAction == null) {
1794:                    originalAction = actionMap.get(actionKey = actionKey2);
1795:                }
1796:                assert originalAction != null;
1797:
1798:                if (originalAction == null) {
1799:                    return;
1800:                }
1801:
1802:                actionMap.put(actionKey, new SelectSrcGrpAction(rootPane,
1803:                        originalAction));
1804:                rootPaneDefaultActionKey = actionKey;
1805:                rootPaneDefaultAction = originalAction;
1806:            }
1807:
1808:            /**
1809:             */
1810:            private void unblockDefaultRootPaneAction() {
1811:                assert rootPane != null;
1812:
1813:                if (rootPaneDefaultAction == null) {
1814:
1815:                    /* blockDefaultRootPaneAction() did not pass */
1816:                    return;
1817:                }
1818:
1819:                rootPane.getActionMap().put(rootPaneDefaultActionKey,
1820:                        rootPaneDefaultAction);
1821:
1822:                rootPaneDefaultActionKey = null;
1823:                rootPaneDefaultAction = null;
1824:            }
1825:
1826:            /**
1827:             * Modifies behaviour of the default button.
1828:             */
1829:            private void blockMnemonics() {
1830:                assert rootPane != null;
1831:
1832:                if (actionMappingInfo == null) {
1833:                    findActionMappings();
1834:                }
1835:
1836:                assert actionMappingInfo != null;
1837:                assert actionMappingInfo.length == mnemonicBlocked.length;
1838:
1839:                final JComponent[] comps = mnemonicBlocked;
1840:                for (int i = 0; i < comps.length; i++) {
1841:                    ActionMappingInfo mappingInfo = actionMappingInfo[i];
1842:                    if (mappingInfo != null) {
1843:                        comps[i].getActionMap().put(
1844:                                mappingInfo.actionKey,
1845:                                new SelectSrcGrpAction(comps[i],
1846:                                        mappingInfo.originalAction));
1847:                    } else if (comps[i] instanceof  JLabel) {
1848:                        ActionMap map = new JLabelActionMap(comps[i]);
1849:                        map.setParent(comps[i].getActionMap());
1850:                        comps[i].setActionMap(map);
1851:                        continue;
1852:                    }
1853:                }
1854:            }
1855:
1856:            /**
1857:             */
1858:            private void unblockMnemonics() {
1859:                assert rootPane != null;
1860:
1861:                if (actionMappingInfo == null) {
1862:
1863:                    /* blockMnemonics() did not pass */
1864:                    return;
1865:                }
1866:
1867:                assert actionMappingInfo.length == mnemonicBlocked.length;
1868:
1869:                final JComponent[] comps = mnemonicBlocked;
1870:                for (int i = 0; i < comps.length; i++) {
1871:                    ActionMappingInfo mappingInfo = actionMappingInfo[i];
1872:                    if (mappingInfo != null) {
1873:                        comps[i]
1874:                                .getActionMap()
1875:                                .put(
1876:                                        mappingInfo.actionKey,
1877:                                        mappingInfo.inProximateActionMap ? mappingInfo.originalAction
1878:                                                : (Action) null);
1879:                    } else if (comps[i] instanceof  JLabel) {
1880:                        comps[i].setActionMap(comps[i].getActionMap()
1881:                                .getParent());
1882:                    }
1883:                }
1884:            }
1885:
1886:            /**
1887:             */
1888:            private void findActionMappings() {
1889:                assert mnemonicBlocked != null;
1890:
1891:                final String actionKey1 = "pressed"; //NOI18N
1892:                final String actionKey2 = "press"; //NOI18N
1893:
1894:                actionMappingInfo = new ActionMappingInfo[mnemonicBlocked.length];
1895:
1896:                final JComponent[] comps = mnemonicBlocked;
1897:                for (int i = 0; i < comps.length; i++) {
1898:                    JComponent c = comps[i];
1899:
1900:                    ActionMap actionMap = comps[i].getActionMap();
1901:
1902:                    String primaryKey = actionKey1;
1903:                    String secondaryKey = actionKey2;
1904:
1905:                    if (c instanceof  JLabel) {
1906:                        actionMappingInfo[i] = null;
1907:                        continue;
1908:                    }
1909:
1910:                    String actionKey;
1911:                    Action originalAction = actionMap
1912:                            .get(actionKey = primaryKey);
1913:                    if (originalAction == null) {
1914:                        originalAction = actionMap
1915:                                .get(actionKey = secondaryKey);
1916:                    }
1917:                    if (originalAction == null) {
1918:                        ErrorManager
1919:                                .getDefault()
1920:                                .log(
1921:                                        ErrorManager.EXCEPTION,
1922:                                        "JUnitWizard - Test for Existing Class: " //NOI18N
1923:                                                + "press action not found for a " //NOI18N
1924:                                                + c.getClass().getName()
1925:                                                + " component"); //NOI18N
1926:                        actionMappingInfo[i] = null;
1927:                        continue;
1928:                    }
1929:
1930:                    ActionMappingInfo mappingInfo = new ActionMappingInfo();
1931:                    mappingInfo.actionKey = actionKey;
1932:                    mappingInfo.originalAction = originalAction;
1933:                    /*mappingInfo.inProximateActionMap = false;*///it's the default
1934:                    /* find whether the mapping is defined in the proximate ActionMap */
1935:                    final String keyToFind = actionKey;
1936:                    final Object[] keys = actionMap.keys();
1937:                    if (keys != null) {
1938:                        for (int j = 0; j < keys.length; j++) {
1939:                            if (keyToFind.equals(keys[j])) {
1940:                                mappingInfo.inProximateActionMap = true;
1941:                                break;
1942:                            }
1943:                        }
1944:                    }
1945:
1946:                    actionMappingInfo[i] = mappingInfo;
1947:                }
1948:            }
1949:
1950:            /**
1951:             * Contains information about <code>ActionMap</code> mapping
1952:             * of a UI component.
1953:             * There is one instance of this class per each JComponent
1954:             * in the {@link #mnemonicBlocked} array.
1955:             */
1956:            private static class ActionMappingInfo {
1957:                /** action key for action which activates the component */
1958:                String actionKey;
1959:                /** original action mapped to the actionKey */
1960:                Action originalAction;
1961:                /**
1962:                 * true if the mapping was defined in the component's
1963:                 * proximate ActionMap; false otherwise
1964:                 */
1965:                boolean inProximateActionMap;
1966:            }
1967:
1968:            /**
1969:             * <!-- PENDING -->
1970:             */
1971:            final class JLabelActionMap extends ActionMap {
1972:
1973:                private final Component component;
1974:
1975:                JLabelActionMap(Component comp) {
1976:                    super ();
1977:                    this .component = comp;
1978:                }
1979:
1980:                @Override
1981:                public Action get(Object key) {
1982:                    if (key.equals("press")) { //NOI18N
1983:                        Action defaultAction = super .get(key);
1984:                        return (defaultAction != null) ? new SelectSrcGrpAction(
1985:                                component, defaultAction)
1986:                                : null;
1987:                    } else {
1988:                        return super .get(key);
1989:                    }
1990:                }
1991:
1992:            }
1993:
1994:            /**
1995:             * Sets up a glass pane - one part of the focus change detection mechanism.
1996:             */
1997:            private void blockMouseClicks() {
1998:                assert rootPane != null;
1999:
2000:                final Component glassPane = rootPane.getGlassPane();
2001:
2002:                if (glassPaneListener == null) {
2003:                    glassPaneListener = new GlassPaneListener();
2004:                }
2005:                glassPane.addMouseListener(glassPaneListener);
2006:                glassPane.addMouseMotionListener(glassPaneListener);
2007:                glassPane.setVisible(true);
2008:            }
2009:
2010:            /**
2011:             * Cleans up a glass pane - one part of the focus change detection
2012:             * mechanism.
2013:             */
2014:            private void unblockMouseClicks() {
2015:                assert rootPane != null;
2016:
2017:                if (glassPaneListener == null) {
2018:                    return;
2019:                }
2020:
2021:                final Component glassPane = rootPane.getGlassPane();
2022:
2023:                glassPane.setVisible(false);
2024:                glassPane.removeMouseMotionListener(glassPaneListener);
2025:                glassPane.removeMouseListener(glassPaneListener);
2026:            }
2027:
2028:            /**
2029:             *
2030:             */
2031:            final class GlassPaneListener implements  MouseInputListener {
2032:                final Component glassPane = rootPane.getGlassPane();
2033:                final Component layeredPane = rootPane.getLayeredPane();
2034:                final Container contentPane = rootPane.getContentPane();
2035:
2036:                public void mouseMoved(MouseEvent e) {
2037:                    redispatchEvent(e);
2038:                }
2039:
2040:                public void mouseDragged(MouseEvent e) {
2041:                    redispatchEvent(e);
2042:                }
2043:
2044:                public void mouseClicked(MouseEvent e) {
2045:                    redispatchEvent(e);
2046:                }
2047:
2048:                public void mouseEntered(MouseEvent e) {
2049:                    redispatchEvent(e);
2050:                }
2051:
2052:                public void mouseExited(MouseEvent e) {
2053:                    redispatchEvent(e);
2054:                }
2055:
2056:                public void mousePressed(MouseEvent e) {
2057:                    evaluateEvent(e);
2058:                }
2059:
2060:                public void mouseReleased(MouseEvent e) {
2061:                    redispatchEvent(e);
2062:                }
2063:
2064:                private void evaluateEvent(MouseEvent e) {
2065:                    assert multipleSourceRoots;
2066:
2067:                    Component component = getDeepestComponent(e);
2068:                    if (component == null) {
2069:                        return;
2070:                    }
2071:
2072:                    boolean isBlocked = false;
2073:                    if (SwingUtilities.isLeftMouseButton(e)) {
2074:                        final Component[] blocked = mouseBlocked;
2075:                        for (int i = 0; i < blocked.length; i++) {
2076:                            if (component == blocked[i]) {
2077:                                isBlocked = true;
2078:                                break;
2079:                            }
2080:                        }
2081:                    }
2082:
2083:                    boolean askUserToChoose;
2084:                    SourceGroup[] candidates = null;
2085:                    if (!isBlocked || interactionRestrictionsSuspended) {
2086:                        askUserToChoose = false;
2087:                    } else if (component == defaultButton) {
2088:                        candidates = findParentGroupCandidates();
2089:                        askUserToChoose = (candidates.length > 1);
2090:                    } else if (!SwingUtilities.isDescendingFrom(component,
2091:                            visualComp)) {
2092:                        askUserToChoose = false;
2093:                    } else {
2094:                        candidates = findParentGroupCandidates();
2095:                        askUserToChoose = (candidates.length > 1);
2096:                    }
2097:
2098:                    assert (askUserToChoose == false)
2099:                            || (candidates.length > 1);
2100:
2101:                    if (askUserToChoose) {
2102:                        SourceGroup srcGroup = chooseSrcGroup(candidates);
2103:                        if (srcGroup != null) {
2104:                            setSelectedSrcGroup(srcGroup);
2105:                            focusGainAllowedFor = component;
2106:                            component.requestFocus();
2107:                        }
2108:                    } else {
2109:                        if (candidates != null) {
2110:                            assert candidates.length == 1;
2111:
2112:                            setSelectedSrcGroup(candidates[0]);
2113:                        }
2114:                        focusGainAllowedFor = component;
2115:                        try {
2116:                            redispatchEvent(e, component);
2117:                        } finally {
2118:                            clearFocusGainAllowedVar();
2119:                        }
2120:                    }
2121:                }
2122:
2123:                private void redispatchEvent(MouseEvent e) {
2124:                    Component deepestComp = getDeepestComponent(e);
2125:                    if (deepestComp != null) {
2126:                        redispatchEvent(e, deepestComp);
2127:                    }
2128:                }
2129:
2130:                private void redispatchEvent(MouseEvent e, Component component) {
2131:                    Point componentPoint = SwingUtilities.convertPoint(
2132:                            glassPane, e.getPoint(), component);
2133:                    component.dispatchEvent(new MouseEvent(component,
2134:                            e.getID(), e.getWhen(), e.getModifiers(),
2135:                            componentPoint.x, componentPoint.y, e
2136:                                    .getClickCount(), e.isPopupTrigger()));
2137:                }
2138:
2139:                private Component getDeepestComponent(MouseEvent e) {
2140:                    Point contentPanePoint = SwingUtilities.convertPoint(
2141:                            glassPane, e.getPoint(), contentPane);
2142:                    return SwingUtilities.getDeepestComponentAt(contentPane,
2143:                            contentPanePoint.x, contentPanePoint.y);
2144:                }
2145:            }
2146:
2147:            /**
2148:             * Action that is activated by a mnemonic keystroke.
2149:             */
2150:            private class SelectSrcGrpAction extends AbstractAction {
2151:                private final Component component;
2152:                private final Action delegate;
2153:
2154:                public SelectSrcGrpAction(Component comp, Action delegate) {
2155:                    this .component = comp;
2156:                    this .delegate = delegate;
2157:                }
2158:
2159:                public void actionPerformed(ActionEvent e) {
2160:                    assert multipleSourceRoots;
2161:
2162:                    boolean askUserToChoose;
2163:                    SourceGroup[] candidates = null;
2164:                    if (interactionRestrictionsSuspended) {
2165:                        askUserToChoose = false;
2166:                    } else if ((component == defaultButton)
2167:                            || (component == rootPane)) {
2168:                        candidates = findParentGroupCandidates();
2169:                        askUserToChoose = (candidates.length > 1);
2170:                    } else if (!SwingUtilities.isDescendingFrom(component,
2171:                            visualComp)) {
2172:                        askUserToChoose = false;
2173:                    } else {
2174:                        candidates = findParentGroupCandidates();
2175:                        askUserToChoose = (candidates.length > 1);
2176:                    }
2177:
2178:                    assert (askUserToChoose == false)
2179:                            || (candidates.length > 1);
2180:
2181:                    if (askUserToChoose) {
2182:                        SourceGroup srcGroup = chooseSrcGroup(candidates);
2183:                        if (srcGroup != null) {
2184:                            setSelectedSrcGroup(srcGroup);
2185:                            if (component == rootPane) {
2186:                                defaultButton.requestFocus();
2187:                            } else {
2188:                                component.requestFocus();
2189:                            }
2190:                        }
2191:                    } else {
2192:                        if (candidates != null) {
2193:                            assert candidates.length == 1;
2194:
2195:                            setSelectedSrcGroup(candidates[0]);
2196:                        }
2197:                        redispatchEvent(e);
2198:                    }
2199:                }
2200:
2201:                private void redispatchEvent(ActionEvent e) {
2202:                    focusGainAllowedFor = component;
2203:                    try {
2204:                        delegate.actionPerformed(e);
2205:                    } finally {
2206:                        clearFocusGainAllowedVar();
2207:                    }
2208:                }
2209:
2210:                @Override
2211:                public boolean isEnabled() {
2212:                    return delegate.isEnabled();
2213:                }
2214:            }
2215:
2216:            /**
2217:             * <!-- PENDING -->
2218:             */
2219:            private class ClsNameDocumentFilter extends DocumentFilter {
2220:                public ClsNameDocumentFilter() {
2221:                }
2222:
2223:                @Override
2224:                public void replace(DocumentFilter.FilterBypass bypass,
2225:                        int offset, int length, String text, AttributeSet attrs)
2226:                        throws BadLocationException {
2227:                    if (!programmaticChange && srcGroupNameDisplayed) {
2228:                        removeSrcGroupName(bypass);
2229:                    }
2230:                    super .replace(bypass, offset, length, text, attrs);
2231:                }
2232:
2233:                @Override
2234:                public void insertString(DocumentFilter.FilterBypass bypass,
2235:                        int offset, String string, AttributeSet attr)
2236:                        throws BadLocationException {
2237:                    if (!programmaticChange && srcGroupNameDisplayed) {
2238:                        removeSrcGroupName(bypass);
2239:                    }
2240:                    super .insertString(bypass, offset, string, attr);
2241:                }
2242:
2243:                @Override
2244:                public void remove(DocumentFilter.FilterBypass bypass,
2245:                        int offset, int length) throws BadLocationException {
2246:                    if (!programmaticChange && srcGroupNameDisplayed) {
2247:                        removeSrcGroupName(bypass);
2248:                    }
2249:                    super .remove(bypass, offset, length);
2250:                }
2251:
2252:                private void removeSrcGroupName(
2253:                        DocumentFilter.FilterBypass bypass)
2254:                        throws BadLocationException {
2255:                    bypass.remove(classNameLength, tfClassToTest.getText()
2256:                            .length()
2257:                            - classNameLength);
2258:                    srcGroupNameDisplayed = false;
2259:                    setNavigationFilterEnabled(false);
2260:                }
2261:            }
2262:
2263:            /**
2264:             * <!-- PENDING -->
2265:             */
2266:            private class ClsNameNavigationFilter extends NavigationFilter {
2267:                public ClsNameNavigationFilter() {
2268:                }
2269:
2270:                @Override
2271:                public void setDot(NavigationFilter.FilterBypass bypass,
2272:                        int dot, Position.Bias bias) {
2273:                    if (dot > classNameLength) {
2274:                        bypass.setDot(classNameLength, bias);
2275:                    } else {
2276:                        super .setDot(bypass, dot, bias);
2277:                    }
2278:                }
2279:
2280:                @Override
2281:                public void moveDot(NavigationFilter.FilterBypass bypass,
2282:                        int dot, Position.Bias bias) {
2283:                    if (dot > classNameLength) {
2284:                        bypass.moveDot(classNameLength, bias);
2285:                    } else {
2286:                        super .moveDot(bypass, dot, bias);
2287:                    }
2288:                }
2289:
2290:                public void ensureCursorInRange() {
2291:                    if (srcGroupNameDisplayed) {
2292:                        if (tfClassToTest.getCaretPosition() > classNameLength) {
2293:                            tfClassToTest.setCaretPosition(classNameLength);
2294:                        }
2295:                    }
2296:                }
2297:            }
2298:
2299:            /**
2300:             * Sends a request to clear the {@link #focusGainAllowedFor} variable
2301:             * to the end of the event queue.
2302:             */
2303:            private void clearFocusGainAllowedVar() {
2304:                SwingUtilities.invokeLater(new Runnable() {
2305:                    public void run() {
2306:                        focusGainAllowedFor = null;
2307:                    }
2308:                });
2309:            }
2310:
2311:            /**
2312:             */
2313:            private static boolean checkObjChanged(Object oldObj, Object newObj) {
2314:                return ((oldObj != null) || (newObj != null))
2315:                        && ((oldObj == null) || !oldObj.equals(newObj));
2316:            }
2317:
2318:            /* *
2319:             * /
2320:            private static void printCallstack(String header) {
2321:                
2322:                //PENDING - this method is not needed in the final version
2323:                
2324:                if (header != null) {
2325:                    System.out.println(header);
2326:                }
2327:
2328:                StackTraceElement[] frames = new Exception().getStackTrace();
2329:                int count = Math.min(5, frames.length);
2330:                for (int i = 1; i < frames.length; i++) {
2331:                    String methodName = frames[i].getMethodName();
2332:                    if (!methodName.startsWith("access$")) {
2333:                        System.out.println("   " + methodName + "(...)");
2334:                        if (--count == 0) {
2335:                            break;
2336:                        }
2337:                    }
2338:                }
2339:                System.out.println();
2340:            }
2341:             */
2342:
2343:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.