1 19 20 package org.netbeans.modules.junit.wizards; 21 22 import java.awt.BorderLayout ; 23 import java.awt.Component ; 24 import java.awt.Container ; 25 import java.awt.GridBagConstraints ; 26 import java.awt.GridBagLayout ; 27 import java.awt.GridLayout ; 28 import java.awt.Insets ; 29 import java.awt.Point ; 30 import java.awt.event.ActionEvent ; 31 import java.awt.event.ActionListener ; 32 import java.awt.event.FocusEvent ; 33 import java.awt.event.FocusListener ; 34 import java.awt.event.HierarchyEvent ; 35 import java.awt.event.HierarchyListener ; 36 import java.awt.event.ItemEvent ; 37 import java.awt.event.ItemListener ; 38 import java.awt.event.MouseEvent ; 39 import java.io.File ; 40 import java.util.ArrayList ; 41 import java.util.Arrays ; 42 import java.util.Collection ; 43 import java.util.Iterator ; 44 import java.util.List ; 45 import java.util.Map ; 46 import java.util.ResourceBundle ; 47 import java.util.Set ; 48 import javax.swing.AbstractAction ; 49 import javax.swing.AbstractButton ; 50 import javax.swing.Action ; 51 import javax.swing.ActionMap ; 52 import javax.swing.BorderFactory ; 53 import javax.swing.Box ; 54 import javax.swing.BoxLayout ; 55 import javax.swing.DefaultComboBoxModel ; 56 import javax.swing.JButton ; 57 import javax.swing.JCheckBox ; 58 import javax.swing.JComboBox ; 59 import javax.swing.JComponent ; 60 import javax.swing.JLabel ; 61 import javax.swing.JList ; 62 import javax.swing.JPanel ; 63 import javax.swing.JRootPane ; 64 import javax.swing.JSeparator ; 65 import javax.swing.JTextField ; 66 import javax.swing.ListSelectionModel ; 67 import javax.swing.SwingUtilities ; 68 import javax.swing.border.BevelBorder ; 69 import javax.swing.event.ChangeEvent ; 70 import javax.swing.event.ChangeListener ; 71 import javax.swing.event.DocumentEvent ; 72 import javax.swing.event.DocumentListener ; 73 import javax.swing.event.ListSelectionEvent ; 74 import javax.swing.event.ListSelectionListener ; 75 import javax.swing.event.MouseInputListener ; 76 import javax.swing.text.AbstractDocument ; 77 import javax.swing.text.AttributeSet ; 78 import javax.swing.text.BadLocationException ; 79 import javax.swing.text.DocumentFilter ; 80 import javax.swing.text.NavigationFilter ; 81 import javax.swing.text.Position ; 82 import org.netbeans.api.java.classpath.ClassPath; 83 import org.netbeans.api.project.Project; 84 import org.netbeans.api.project.ProjectUtils; 85 import org.netbeans.api.project.SourceGroup; 86 import org.netbeans.modules.junit.GuiUtils; 87 import org.netbeans.modules.junit.JUnitCfgOfCreate; 88 import org.netbeans.modules.junit.MessageStack; 89 import org.netbeans.modules.junit.NamedObject; 90 import org.netbeans.modules.junit.SizeRestrictedPanel; 91 import org.netbeans.modules.junit.TestCreator; 92 import org.netbeans.spi.java.project.support.ui.PackageView; 93 import org.openide.DialogDescriptor; 94 import org.openide.DialogDisplayer; 95 import org.openide.ErrorManager; 96 import org.openide.NotifyDescriptor; 97 import org.openide.WizardDescriptor; 98 import org.openide.awt.Mnemonics; 99 import org.openide.filesystems.FileObject; 100 import org.openide.filesystems.FileUtil; 101 import org.openide.loaders.DataObject; 102 import org.openide.loaders.TemplateWizard; 103 import org.openide.nodes.AbstractNode; 104 import org.openide.nodes.Children; 105 import org.openide.nodes.FilterNode; 106 import org.openide.nodes.Node; 107 import org.openide.nodes.NodeAcceptor; 108 import org.openide.nodes.NodeOperation; 109 import org.openide.util.HelpCtx; 110 import org.openide.util.NbBundle; 111 import org.openide.util.UserCancelException; 112 113 117 public final class SimpleTestStepLocation implements WizardDescriptor.Panel { 118 119 125 private static final int MSG_LAYER_CHECKBOXES = 0; 126 131 private static final int MSG_LAYER_CLASSNAME = 1; 132 133 private final String testClassNameSuffix 134 = NbBundle.getMessage(TestCreator.class, 135 "PROP_test_classname_suffix"); 137 private Component visualComp; 138 private List <ChangeListener > changeListeners; 139 private JTextField tfClassToTest; 140 private JButton btnBrowse; 141 private JTextField tfTestClass; 142 private JTextField tfProjectName; 143 private JComboBox cboxLocation; 144 private JTextField tfCreatedFile; 145 146 private JCheckBox chkPublic; 147 private JCheckBox chkProtected; 148 private JCheckBox chkPackagePrivate; 149 private JCheckBox chkSetUp; 150 private JCheckBox chkTearDown; 151 private JCheckBox chkMethodBodies; 152 private JCheckBox chkJavadoc; 153 private JCheckBox chkHints; 154 155 156 private final MessageStack msgStack = new MessageStack(2); 157 private String msgClassNameInvalid; 158 private String msgClassToTestDoesNotExist; 159 private String msgChkBoxesInvalid; 160 161 162 165 private Project project; 166 private TemplateWizard wizard; 167 168 169 171 186 private boolean multipleSourceRoots; 187 193 private boolean interactionRestrictionsEnabled = false; 194 197 private boolean interactionRestrictionsActive = false; 198 199 private boolean interactionRestrictionsSuspended = false; 200 201 private boolean mouseClicksBlocked = false; 202 209 private HierarchyListener displayabilityListener; 210 211 private JRootPane rootPane; 212 216 private JButton defaultButton; 217 221 private String rootPaneDefaultActionKey; 222 226 private Action rootPaneDefaultAction; 227 231 private MouseInputListener glassPaneListener; 232 237 private Component [] mouseBlocked; 238 243 private JComponent [] mnemonicBlocked; 244 254 private ActionMappingInfo[] actionMappingInfo; 255 261 private Component focusGainAllowedFor; 262 263 264 266 274 private SourceGroup[] testableSourceGroups; 275 276 private FileObject[] testableSourceGroupsRoots; 277 278 private SourceGroup[] allTestSourceGroups; 279 286 private Map <SourceGroup,Object []> sourcesToTestsMap; 287 288 289 291 300 private int sourceGroupParentIndex = -1; 301 302 private FileObject srcFile; 303 private SourceGroup srcGroup = null; 304 private String testsRootDirName = ""; private String srcRelFileNameSys = ""; private String testRelFileName = ""; 308 private FileObject testRootFolder; 309 310 private int classNameLength = 0; 311 312 private boolean srcGroupNameDisplayed = false; 313 314 private boolean programmaticChange = false; 315 316 private boolean navigationFilterEnabled = false; 317 318 private ClsNameNavigationFilter clsNameNavigationFilter; 319 320 private ClsNameDocumentFilter clsNameDocumentFilter; 321 322 323 private boolean ignoreCboxItemChanges = false; 324 325 private boolean ignoreClsNameChanges = false; 326 327 328 330 336 private boolean isValid = false; 337 338 private boolean classNameValid = false; 339 346 private boolean classExists = false; 347 351 private boolean chkBoxesValid = false; 352 353 354 356 public SimpleTestStepLocation() { 357 visualComp = createVisualComp(); 358 } 359 360 private Component createVisualComp() { 361 JLabel lblClassToTest = new JLabel (); 362 JLabel lblCreatedTestClass = new JLabel (); 363 JLabel lblProject = new JLabel (); 364 JLabel lblLocation = new JLabel (); 365 JLabel lblFile = new JLabel (); 366 tfClassToTest = new JTextField (35); 367 btnBrowse = new JButton (); 368 tfTestClass = new JTextField (); 369 tfProjectName = new JTextField (); 370 cboxLocation = new JComboBox (); 371 tfCreatedFile = new JTextField (); 372 373 ResourceBundle bundle 374 = NbBundle.getBundle(SimpleTestStepLocation.class); 375 376 Mnemonics.setLocalizedText(lblClassToTest, 377 bundle.getString("LBL_ClassToTest")); Mnemonics.setLocalizedText(lblCreatedTestClass, 379 bundle.getString("LBL_TestClass")); Mnemonics.setLocalizedText(lblProject, 381 bundle.getString("LBL_Project")); Mnemonics.setLocalizedText(lblLocation, 383 bundle.getString("LBL_Location")); Mnemonics.setLocalizedText(lblFile, 385 bundle.getString("LBL_CreatedFile")); Mnemonics.setLocalizedText(btnBrowse, 387 bundle.getString("LBL_Browse")); 389 lblClassToTest.setLabelFor(tfClassToTest); 390 lblCreatedTestClass.setLabelFor(tfTestClass); 391 lblProject.setLabelFor(tfProjectName); 392 lblFile.setLabelFor(tfCreatedFile); 393 lblLocation.setLabelFor(cboxLocation); 394 395 tfTestClass.setEditable(false); 396 tfProjectName.setEditable(false); 397 tfCreatedFile.setEditable(false); 398 399 tfTestClass.setFocusable(false); 400 tfProjectName.setFocusable(false); 401 tfCreatedFile.setFocusable(false); 402 403 cboxLocation.setEditable(false); 404 405 JCheckBox [] chkBoxes; 406 407 JComponent accessLevels = GuiUtils.createChkBoxGroup( 408 NbBundle.getMessage( 409 GuiUtils.class, 410 "JUnitCfgOfCreate.groupAccessLevels"), chkBoxes = GuiUtils.createCheckBoxes(new String [] { 412 GuiUtils.CHK_PUBLIC, 413 GuiUtils.CHK_PROTECTED, 414 GuiUtils.CHK_PACKAGE})); 415 chkPublic = chkBoxes[0]; 416 chkProtected = chkBoxes[1]; 417 chkPackagePrivate = chkBoxes[2]; 418 419 JComponent optCode = GuiUtils.createChkBoxGroup( 420 NbBundle.getMessage( 421 GuiUtils.class, 422 "JUnitCfgOfCreate.groupOptCode"), chkBoxes = GuiUtils.createCheckBoxes(new String [] { 424 GuiUtils.CHK_SETUP, 425 GuiUtils.CHK_TEARDOWN, 426 GuiUtils.CHK_METHOD_BODIES})); 427 chkSetUp = chkBoxes[0]; 428 chkTearDown = chkBoxes[1]; 429 chkMethodBodies = chkBoxes[2]; 430 431 JComponent optComments = GuiUtils.createChkBoxGroup( 432 NbBundle.getMessage( 433 GuiUtils.class, 434 "JUnitCfgOfCreate.groupOptComments"), chkBoxes = GuiUtils.createCheckBoxes(new String [] { 436 GuiUtils.CHK_JAVADOC, 437 GuiUtils.CHK_HINTS})); 438 chkJavadoc = chkBoxes[0]; 439 chkHints = chkBoxes[1]; 440 441 442 JPanel targetPanel 443 = new SizeRestrictedPanel(new GridBagLayout (), false, true); 444 445 GridBagConstraints gbcLeft = new GridBagConstraints (); 446 gbcLeft.anchor = GridBagConstraints.WEST; 447 gbcLeft.gridwidth = 1; 448 gbcLeft.insets = new Insets (0, 0, 6, 12); 449 gbcLeft.fill = GridBagConstraints.NONE; 450 gbcLeft.weightx = 0.0f; 451 452 GridBagConstraints gbcRight = new GridBagConstraints (); 453 gbcRight.anchor = GridBagConstraints.WEST; 454 gbcRight.gridwidth = GridBagConstraints.REMAINDER; 455 gbcRight.insets = new Insets (0, 0, 6, 0); 456 gbcRight.fill = GridBagConstraints.BOTH; 457 gbcRight.weightx = 1.0f; 458 459 461 gbcRight.gridwidth = 1; 462 463 GridBagConstraints gbcBrowse = new GridBagConstraints (); 464 gbcBrowse.insets = new Insets (0, 11, 6, 0); 465 gbcBrowse.gridwidth = GridBagConstraints.REMAINDER; 466 467 targetPanel.add(lblClassToTest, gbcLeft); 468 targetPanel.add(tfClassToTest, gbcRight); 469 targetPanel.add(btnBrowse, gbcBrowse); 470 471 473 gbcLeft.insets.bottom = gbcRight.insets.bottom = 24; 474 475 targetPanel.add(lblCreatedTestClass, gbcLeft); 476 targetPanel.add(tfTestClass, gbcRight); 477 targetPanel.add(new JPanel (), gbcBrowse); 479 481 gbcRight.gridwidth = GridBagConstraints.REMAINDER; 482 483 gbcLeft.insets.bottom = gbcRight.insets.bottom = 6; 484 485 targetPanel.add(lblProject, gbcLeft); 486 targetPanel.add(tfProjectName, gbcRight); 487 488 490 gbcLeft.insets.bottom = gbcRight.insets.bottom = 12; 491 492 targetPanel.add(lblLocation, gbcLeft); 493 targetPanel.add(cboxLocation, gbcRight); 494 495 497 gbcLeft.insets.bottom = gbcRight.insets.bottom = 0; 498 499 targetPanel.add(lblFile, gbcLeft); 500 targetPanel.add(tfCreatedFile, gbcRight); 501 502 504 JComponent accessLevelsBox = new SizeRestrictedPanel(true, false); 505 accessLevelsBox.setLayout( 506 new BoxLayout (accessLevelsBox, BoxLayout.Y_AXIS)); 507 accessLevelsBox.add(accessLevels); 508 accessLevelsBox.add(Box.createVerticalGlue()); 509 510 JComponent optionalCodeBox = new SizeRestrictedPanel(true, false); 511 optionalCodeBox.setLayout( 512 new BoxLayout (optionalCodeBox, BoxLayout.Y_AXIS)); 513 optionalCodeBox.add(optCode); 514 optionalCodeBox.add(Box.createVerticalStrut(11)); 515 optionalCodeBox.add(optComments); 516 optionalCodeBox.add(Box.createVerticalGlue()); 517 518 JComponent optionsBox = new SizeRestrictedPanel(false, true); 519 optionsBox.setLayout( 520 new BoxLayout (optionsBox, BoxLayout.X_AXIS)); 521 optionsBox.add(accessLevelsBox); 522 optionsBox.add(Box.createHorizontalStrut(18)); 523 optionsBox.add(optionalCodeBox); 524 optionsBox.add(Box.createHorizontalGlue()); 525 526 final Box result = Box.createVerticalBox(); 527 result.add(targetPanel); 528 result.add(Box.createVerticalStrut(12)); 529 JPanel separatorPanel = new SizeRestrictedPanel(new GridLayout (), 530 false, true); 531 separatorPanel.add(new JSeparator ()); 532 result.add(separatorPanel); 533 result.add(Box.createVerticalStrut(12)); 534 result.add(optionsBox); 535 537 538 targetPanel.setAlignmentX(0.0f); 539 optionsBox.setAlignmentX(0.0f); 540 optCode.setAlignmentX(0.0f); 541 optComments.setAlignmentX(0.0f); 542 543 result.setName(bundle.getString("LBL_panel_ChooseClass")); 544 545 addAccessibilityDescriptions(result); 546 setUpInteraction(); 547 548 return result; 549 } 550 551 557 private void addAccessibilityDescriptions(Component wizPanel) { 558 final ResourceBundle bundle 559 = NbBundle.getBundle(SimpleTestStepLocation.class); 560 561 tfClassToTest.setToolTipText( 562 bundle.getString("SimpleTest.classToTest.toolTip")); tfClassToTest.getAccessibleContext().setAccessibleName( 564 bundle.getString("SimpleTest.classToTest.AN")); tfClassToTest.getAccessibleContext().setAccessibleDescription( 566 bundle.getString("SimpleTest.classToTest.AD")); 568 btnBrowse.setToolTipText( 569 bundle.getString("SimpleTest.btnBrowse.toolTip")); btnBrowse.getAccessibleContext().setAccessibleName( 571 bundle.getString("SimpleTest.btnBrowse.AN")); btnBrowse.getAccessibleContext().setAccessibleDescription( 573 bundle.getString("SimpleTest.btnBrowse.AD")); 575 cboxLocation.setToolTipText( 576 bundle.getString("SimpleTest.location.toolTip")); cboxLocation.getAccessibleContext().setAccessibleName( 578 bundle.getString("SimpleTest.location.AN")); cboxLocation.getAccessibleContext().setAccessibleDescription( 580 bundle.getString("SimpleTest.location.AD")); 582 wizPanel.getAccessibleContext().setAccessibleDescription( 583 bundle.getString("SimpleTest.AD")); } 585 586 592 private boolean updateLocationComboBox() { 593 Object [] srcRootsToOffer; 594 595 if ((allTestSourceGroups.length == 1) || (srcGroup == null)) { 596 srcRootsToOffer = allTestSourceGroups; 597 } else { 598 srcRootsToOffer = (Object []) sourcesToTestsMap.get(srcGroup); 599 } 600 601 Object previousSelectedItem = cboxLocation.getSelectedItem(); 602 603 ignoreCboxItemChanges = true; 604 try { 605 Object [] items = createNamedItems(srcRootsToOffer); 606 cboxLocation.setModel(new DefaultComboBoxModel (items)); 607 if (previousSelectedItem != null) { 608 cboxLocation.setSelectedItem(previousSelectedItem); } 610 } finally { 611 ignoreCboxItemChanges = false; 612 } 613 614 Object newSelectedItem = cboxLocation.getSelectedItem(); 615 616 return !newSelectedItem.equals(previousSelectedItem); 617 } 618 619 621 private static NamedObject[] createNamedItems(final Object [] srcRoots) { 622 623 NamedObject[] items = new NamedObject[srcRoots.length]; 625 for (int i = 0; i < srcRoots.length; i++) { 626 String name = (srcRoots[i] instanceof SourceGroup) 627 ? ((SourceGroup) srcRoots[i]).getDisplayName() 628 : (srcRoots[i] instanceof FileObject) 629 ? FileUtil.getFileDisplayName((FileObject) 630 srcRoots[i]) 631 : srcRoots[i].toString(); 632 items[i] = new NamedObject(srcRoots[i], 633 name); 634 } 635 return items; 636 } 637 638 640 private void setUpInteraction() { 641 642 class UIListener implements ActionListener , DocumentListener , 643 FocusListener , ItemListener { 644 public void actionPerformed(ActionEvent e) { 645 646 647 648 chooseClass(); 649 } 650 public void insertUpdate(DocumentEvent e) { 651 classNameChanged(); 652 } 653 public void removeUpdate(DocumentEvent e) { 654 classNameChanged(); 655 } 656 public void changedUpdate(DocumentEvent e) { 657 classNameChanged(); 658 } 659 public void focusGained(FocusEvent e) { 660 Object source = e.getSource(); 661 if (source == tfClassToTest) { 662 } 664 } 665 public void focusLost(FocusEvent e) { 666 Object source = e.getSource(); 667 if (source == tfClassToTest) { 668 if (!e.isTemporary()) { 670 tfClassToTestFocusLost(e); 671 } 672 } else if ((source == btnBrowse) && !e.isTemporary()) { 673 btnBrowseFocusLost(e); 674 } 675 } 676 public void itemStateChanged(ItemEvent e) { 677 if (e.getSource() == cboxLocation) { 678 if (!ignoreCboxItemChanges) { 679 locationChanged(); 680 } 681 } else { 682 685 checkChkBoxesValidity(); 686 setValidity(); 687 } 688 } 689 } 690 691 final UIListener listener = new UIListener(); 692 693 btnBrowse.addActionListener(listener); 694 tfClassToTest.addFocusListener(listener); 695 btnBrowse.addFocusListener(listener); 696 cboxLocation.addItemListener(listener); 697 chkPublic.addItemListener(listener); 698 chkProtected.addItemListener(listener); 699 chkPackagePrivate.addItemListener(listener); 700 tfClassToTest.getDocument().addDocumentListener(listener); 701 } 702 703 705 private void tfClassToTestFocusLost(FocusEvent e) { 706 final Component allowFocusGain = focusGainAllowedFor; 707 focusGainAllowedFor = null; 708 709 if (multipleSourceRoots 710 && interactionRestrictionsActive 711 && !interactionRestrictionsSuspended) { 712 713 final Component opposite = e.getOppositeComponent(); 714 715 if ((allowFocusGain != null) && (opposite == allowFocusGain)) { 716 return; 717 } 718 if (opposite == btnBrowse) { 719 return; 720 } 721 if ((opposite instanceof JLabel ) 722 && (((JLabel ) opposite).getLabelFor() == tfClassToTest)) { 723 728 return; 729 } 730 731 if (!maybeDisplaySourceGroupChooser()) { 732 733 734 tfClassToTest.requestFocus(); 735 } 736 } 737 } 738 739 741 private void btnBrowseFocusLost(FocusEvent e) { 742 final Component allowFocusGain = focusGainAllowedFor; 743 focusGainAllowedFor = null; 744 745 if (multipleSourceRoots 746 && interactionRestrictionsActive 747 && !interactionRestrictionsSuspended) { 748 749 final Component opposite = e.getOppositeComponent(); 750 751 if ((allowFocusGain != null) && (opposite == allowFocusGain)) { 752 return; 753 } 754 if (opposite == tfClassToTest) { 755 return; 756 } 757 if ((opposite instanceof JLabel ) 758 && (((JLabel ) opposite).getLabelFor() == tfClassToTest)) { 759 764 return; 765 } 766 767 if (!maybeDisplaySourceGroupChooser()) { 768 769 770 btnBrowse.requestFocus(); 771 } 772 } 773 } 774 775 781 private boolean maybeDisplaySourceGroupChooser() { 782 assert multipleSourceRoots; 783 784 if (classExists && (srcGroup == null)) { 785 SourceGroup[] candidates = findParentGroupCandidates(); 786 787 assert candidates.length != 0; 789 if (candidates.length == 1) { 790 setSelectedSrcGroup(candidates[0]); 791 return true; 792 } else { 793 SourceGroup chosenSrcGroup = chooseSrcGroup(candidates); 794 if (chosenSrcGroup != null) { 795 setSelectedSrcGroup(chosenSrcGroup); 796 return true; 797 } else { 798 return false; 799 } 800 } 801 } else { 802 return true; 803 } 804 } 805 806 814 private SourceGroup chooseSrcGroup(final SourceGroup[] candidates) { 815 assert (candidates != null) && (candidates.length != 0); 816 817 final String [] rootNames = new String [candidates.length]; 818 for (int i = 0; i < rootNames.length; i++) { 819 rootNames[i] = candidates[i].getDisplayName(); 820 } 821 822 final JButton btn = new JButton ( 823 NbBundle.getMessage(getClass(), 824 "LBL_SelectBtn")); final JList list = new JList (rootNames); 826 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 827 list.setSelectedIndex(0); 828 list.addListSelectionListener(new ListSelectionListener () { 829 public void valueChanged(ListSelectionEvent e) { 830 btn.setEnabled(!list.isSelectionEmpty()); 831 } 832 }); 833 JPanel panel = new JPanel (new BorderLayout (0, 0)); 834 panel.add(list, BorderLayout.CENTER); 835 panel.setBorder(BorderFactory.createCompoundBorder( 836 BorderFactory.createEmptyBorder(12, 12, 0, 12), 837 BorderFactory.createBevelBorder(BevelBorder.LOWERED))); 838 839 String dialogTitle = NbBundle.getMessage( 840 getClass(), 841 "LBL_SourceRootChooserTitle"); DialogDescriptor descriptor 843 = new DialogDescriptor(panel, dialogTitle, true, new Object [] { btn, 848 NotifyDescriptor.CANCEL_OPTION}, 849 btn, DialogDescriptor.DEFAULT_ALIGN, 851 (HelpCtx) null, 852 (ActionListener ) null); 853 Object selected = DialogDisplayer.getDefault().notify(descriptor); 854 return (selected == btn) ? candidates[list.getSelectedIndex()] 855 : (SourceGroup) null; 856 } 857 858 860 private void setSelectedSrcGroup(SourceGroup srcGroup) { 861 setSelectedSrcGroup(srcGroup, true); 862 } 863 864 867 private void setSelectedSrcGroup(SourceGroup srcGroup, boolean updateDisp) { 868 assert multipleSourceRoots 869 && ((srcGroup == null) || (classNameValid && classExists)); 870 871 if (!checkObjChanged(this.srcGroup, srcGroup)) { 872 return; 873 } 874 875 this.srcGroup = srcGroup; 876 877 if (updateDisp) { 878 879 880 try { 881 programmaticChange = true; 882 883 String className = tfClassToTest.getText() 884 .substring(0, classNameLength); 885 String srcGroupDisplay = getSrcGrpDisp(srcGroup); 886 887 ignoreClsNameChanges = true; 888 tfClassToTest.setText(className + srcGroupDisplay); 889 ignoreClsNameChanges = false; 890 891 classNameLength = className.length(); 892 classNameChanged(); 893 srcGroupNameDisplayed = true; 894 setNavigationFilterEnabled(true); 895 } finally { 896 ignoreClsNameChanges = false; 897 programmaticChange = false; 898 } 899 } 900 901 updateInteractionRestrictionsState(); 902 903 909 910 911 if (allTestSourceGroups.length > 1) { 912 boolean locationChanged = updateLocationComboBox(); 913 if (locationChanged) { 914 updateTargetFolderData(); 915 } 916 } 917 918 919 updateCreatedFileName(); 920 921 922 srcFile = (srcGroup != null) 923 ? srcGroup.getRootFolder().getFileObject(srcRelFileNameSys) 924 : null; 925 926 assert (srcGroup == null) || (srcFile != null); 927 } 928 929 931 private static String getSrcGrpDisp(SourceGroup srcGroup) { 932 if (srcGroup == null) { 933 return ""; } else { 935 String srcGroupName = srcGroup.getDisplayName(); 936 return new StringBuffer (srcGroupName.length() + 3) 937 .append(' ') 938 .append('(').append(srcGroupName).append(')') 939 .toString(); 940 } 941 } 942 943 945 private void setNavigationFilterEnabled(boolean enabled) { 946 if (enabled == navigationFilterEnabled) { 947 if (enabled) { 948 clsNameNavigationFilter.ensureCursorInRange(); 949 } 950 return; 951 } 952 953 if (enabled) { 954 if (clsNameNavigationFilter == null) { 955 clsNameNavigationFilter = new ClsNameNavigationFilter(); 956 } 957 tfClassToTest.setNavigationFilter(clsNameNavigationFilter); 958 clsNameNavigationFilter.ensureCursorInRange(); 959 } else { 960 tfClassToTest.setNavigationFilter(null); 961 } 962 this.navigationFilterEnabled = enabled; 963 } 964 965 968 private void updateInteractionRestrictionsState() { 969 setInteractionRestrictionsSuspended( 970 !classNameValid || !classExists || (srcGroup != null)); 971 } 972 973 975 private void updateTargetFolderData() { 976 Object item = cboxLocation.getSelectedItem(); 977 if (item != null) { 978 SourceGroup targetSourceGroup = (SourceGroup) 979 ((NamedObject) item).object; 980 testRootFolder = targetSourceGroup.getRootFolder(); 981 testsRootDirName = FileUtil.getFileDisplayName(testRootFolder); 982 } else { 983 testRootFolder = null; 984 testsRootDirName = ""; } 986 } 987 988 991 private void locationChanged() { 992 updateTargetFolderData(); 993 updateCreatedFileName(); 994 } 995 996 998 private void classNameChanged() { 999 if (ignoreClsNameChanges) { 1000 return; 1001 } 1002 1003 String className; 1004 if (!programmaticChange) { 1005 className = tfClassToTest.getText().trim(); 1006 classNameLength = className.length(); 1007 } else { 1008 className = tfClassToTest.getText().substring(0, classNameLength); 1009 } 1010 1011 String testClassName; 1012 if (className.length() != 0) { 1013 srcRelFileNameSys = className.replace('.', '/') 1014 + ".java"; testClassName = className + testClassNameSuffix; 1016 testRelFileName = testClassName.replace('.', File.separatorChar) 1017 + ".java"; } else { 1019 srcRelFileNameSys = ""; testClassName = ""; testRelFileName = ""; } 1023 tfTestClass.setText(testClassName); 1024 1025 if (!programmaticChange) { 1026 updateCreatedFileName(); 1027 if (checkClassNameValidity()) { 1028 checkSelectedClassExists(); 1029 } 1030 setErrorMsg(msgStack.getDisplayedMessage()); 1031 setValidity(); 1032 1033 1037 if (multipleSourceRoots) { 1038 setSelectedSrcGroup(null, false); 1039 } 1040 } 1041 1042 if (multipleSourceRoots) { 1043 updateInteractionRestrictionsState(); 1044 } 1045 } 1046 1047 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.getFileObject(srcRelFileNameSys); 1065 if (srcFile != null && testableSourceGroups[i].contains(srcFile)) { 1066 if (cands == null) { 1067 cands = new ArrayList <SourceGroup>(testableSourceGroups.length - i + 1); 1068 cands.add(testableSourceGroups[sourceGroupParentIndex]); 1069 } 1070 cands.add(testableSourceGroups[i]); 1071 } 1072 } 1073 return cands == null 1074 ? new SourceGroup[] {testableSourceGroups[sourceGroupParentIndex]} 1075 : cands.toArray(new SourceGroup[cands.size()]); 1076 } 1077 1078 1080 private void updateCreatedFileName() { 1081 tfCreatedFile.setText(testsRootDirName + File.separatorChar + testRelFileName); 1082 } 1083 1084 1091 private boolean checkClassNameValidity() { 1092 String className = tfClassToTest.getText().trim(); 1093 if (srcGroupNameDisplayed) { 1094 className = className.substring(0, classNameLength); 1095 } 1096 1097 if (className.length() == 0) { 1098 msgStack.clearMessage(MSG_LAYER_CLASSNAME); 1099 classNameValid = false; 1100 } else if (Utils.isValidClassName(className)) { 1101 msgStack.clearMessage(MSG_LAYER_CLASSNAME); 1102 classNameValid = true; 1103 } else { 1104 if (msgClassNameInvalid == null) { 1105 msgClassNameInvalid = NbBundle.getMessage( 1106 JUnitCfgOfCreate.class, 1107 "MSG_InvalidClassName"); } 1109 msgStack.setMessage(MSG_LAYER_CLASSNAME, msgClassNameInvalid); 1110 classNameValid = false; 1111 } 1112 1113 return classNameValid; 1114 } 1115 1116 1122 private boolean checkSelectedClassExists() { 1123 sourceGroupParentIndex = -1; 1124 1125 final int count = testableSourceGroups.length; 1126 for (int i = 0; i < count; i++) { 1127 final FileObject groupRoot = testableSourceGroupsRoots[i]; 1128 FileObject srcFile = groupRoot.getFileObject(srcRelFileNameSys); 1129 if (srcFile != null && testableSourceGroups[i].contains(srcFile)) { 1130 this.srcFile = srcFile; 1131 sourceGroupParentIndex = i; 1132 break; 1133 } 1134 } 1135 1136 classExists = (sourceGroupParentIndex != -1); 1137 1138 if (classExists) { 1139 msgStack.clearMessage(MSG_LAYER_CLASSNAME); 1140 } else { 1141 if (msgClassToTestDoesNotExist == null) { 1142 msgClassToTestDoesNotExist = NbBundle.getMessage( 1143 SimpleTestStepLocation.class, 1144 "MSG_ClassToTestDoesNotExist"); } 1146 msgStack.setMessage(MSG_LAYER_CLASSNAME, 1147 msgClassToTestDoesNotExist); 1148 } 1149 1150 return classExists; 1151 } 1152 1153 1160 private boolean checkChkBoxesValidity() { 1161 chkBoxesValid = chkPublic.isSelected() 1162 || chkProtected.isSelected() 1163 || chkPackagePrivate.isSelected(); 1164 String msgUpdate; 1165 if (chkBoxesValid) { 1166 msgUpdate = msgStack.clearMessage(MSG_LAYER_CHECKBOXES); 1167 } else { 1168 if (msgChkBoxesInvalid == null) { 1169 msgChkBoxesInvalid = NbBundle.getMessage( 1171 JUnitCfgOfCreate.class, 1172 "MSG_AllMethodTypesDisabled"); } 1174 msgUpdate = msgStack.setMessage(MSG_LAYER_CHECKBOXES, 1175 msgChkBoxesInvalid); 1176 } 1177 if (msgUpdate != null) { 1178 setErrorMsg(msgStack.getDisplayedMessage()); 1179 } 1180 return chkBoxesValid; 1181 } 1182 1183 1187 private void setValidity() { 1188 boolean wasValid = isValid; 1189 1190 isValid = classNameValid && classExists && chkBoxesValid; 1191 1192 if (isValid != wasValid) { 1193 fireChange(); 1194 1195 updateInteractionRestrictionsState(); 1196 1197 1201 if (isValid 1202 && interactionRestrictionsEnabled 1203 && !interactionRestrictionsActive) { 1204 tryActivateInteractionRestrictions(); 1205 } 1206 } 1207 } 1208 1209 1215 private void setErrorMsg(String message) { 1216 if (wizard != null) { 1217 wizard.putProperty("WizardPanel_errorMessage", message); } 1219 } 1220 1221 1226 private void chooseClass() { 1227 try { 1228 final Node[] sourceGroupNodes 1229 = new Node[testableSourceGroups.length]; 1230 for (int i = 0; i < sourceGroupNodes.length; i++) { 1231 1235 Node srcGroupNode 1236 = PackageView.createPackageView(testableSourceGroups[i]); 1237 sourceGroupNodes[i] 1238 = new FilterNode(srcGroupNode, 1239 new JavaChildren(srcGroupNode)); 1240 } 1241 1242 Node rootNode; 1243 if (sourceGroupNodes.length == 1) { 1244 rootNode = new FilterNode( 1245 sourceGroupNodes[0], 1246 new JavaChildren(sourceGroupNodes[0])); 1247 } else { 1248 Children children = new Children.Array(); 1249 children.add(sourceGroupNodes); 1250 1251 AbstractNode node = new AbstractNode(children); 1252 node.setName("Project Source Roots"); node.setDisplayName( 1254 NbBundle.getMessage(getClass(), "LBL_Sources")); rootNode = node; 1257 } 1258 1259 NodeAcceptor acceptor = new NodeAcceptor() { 1260 public boolean acceptNodes(Node[] nodes) { 1261 Node.Cookie cookie; 1262 return nodes.length == 1 1263 && (cookie = nodes[0].getCookie(DataObject.class)) 1264 != null 1265 && ((DataObject) cookie).getPrimaryFile().isFolder() 1266 == false; 1267 } 1268 }; 1269 1270 Node selectedNode = NodeOperation.getDefault().select( 1271 NbBundle.getMessage(SimpleTestStepLocation.class, 1272 "LBL_WinTitle_SelectClass"), NbBundle.getMessage(SimpleTestStepLocation.class, 1274 "LBL_SelectClassToTest"), rootNode, 1276 acceptor)[0]; 1277 1278 SourceGroup selectedSourceGroup; 1279 if (sourceGroupNodes.length == 1) { 1280 selectedSourceGroup = testableSourceGroups[0]; 1281 } else { 1282 Node previous = null; 1283 Node current = selectedNode.getParentNode(); 1284 Node parent; 1285 while ((parent = current.getParentNode()) != null) { 1286 previous = current; 1287 current = parent; 1288 } 1289 1295 selectedSourceGroup = null; 1296 Node selectedSrcGroupNode = previous; 1297 for (int i = 0; i < sourceGroupNodes.length; i++) { 1298 if (sourceGroupNodes[i] == selectedSrcGroupNode) { 1299 selectedSourceGroup = testableSourceGroups[i]; 1300 sourceGroupParentIndex = i; 1301 break; 1302 } 1303 } 1304 assert selectedSourceGroup != null; 1305 assert sourceGroupParentIndex >= 0; 1306 } 1307 srcGroup = selectedSourceGroup; 1308 1309 FileObject selectedFileObj 1310 = ((DataObject) selectedNode.getCookie(DataObject.class)) 1311 .getPrimaryFile(); 1312 1313 1314 try { 1315 programmaticChange = true; 1316 1317 String className = getClassName(selectedFileObj); 1318 classNameLength = className.length(); 1319 if (!multipleSourceRoots) { 1320 tfClassToTest.setText(className); 1321 } else { 1322 String srcGroupDisplay = getSrcGrpDisp(selectedSourceGroup); 1323 1324 ignoreClsNameChanges = true; 1325 tfClassToTest.setText(className + srcGroupDisplay); 1326 ignoreClsNameChanges = false; 1327 1328 classNameLength = className.length(); 1329 classNameChanged(); 1330 srcGroupNameDisplayed = true; 1331 setNavigationFilterEnabled(true); 1332 } 1333 1337 } finally { 1338 ignoreClsNameChanges = false; 1339 programmaticChange = false; 1340 } 1341 1342 1343 classNameValid = true; 1344 classExists = true; 1345 String msgUpdate = msgStack.clearMessage(MSG_LAYER_CLASSNAME); 1346 if (msgUpdate != null) { 1347 setErrorMsg(msgUpdate); 1348 } 1349 setValidity(); 1350 updateInteractionRestrictionsState(); 1351 1352 1353 if (multipleSourceRoots && (allTestSourceGroups.length > 1)) { 1354 boolean locationChanged = updateLocationComboBox(); 1355 if (locationChanged) { 1356 updateTargetFolderData(); } 1358 } 1359 1360 1361 updateCreatedFileName(); 1362 1363 1364 srcFile = selectedFileObj; 1365 1366 } catch (UserCancelException ex) { 1367 } 1369 } 1370 1371 private static String getClassName(FileObject fileObj) { 1372 return ClassPath.getClassPath(fileObj, ClassPath.SOURCE) 1374 .getResourceName(fileObj, '.', false); 1375 } 1376 1377 public Component getComponent() { 1378 return visualComp; 1379 } 1380 1381 public boolean isValid() { 1382 return isValid; 1383 } 1384 1385 public HelpCtx getHelp() { 1386 return null; 1388 } 1389 1390 public void readSettings(Object settings) { 1391 wizard = (TemplateWizard) settings; 1392 1393 chkPublic.setSelected( 1394 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_PUBLIC))); 1395 chkProtected.setSelected( 1396 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_PROTECTED))); 1397 chkPackagePrivate.setSelected( 1398 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_PACKAGE))); 1399 chkSetUp.setSelected( 1400 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_SETUP))); 1401 chkTearDown.setSelected( 1402 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_TEARDOWN))); 1403 chkMethodBodies.setSelected( 1404 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_METHOD_BODIES))); 1405 chkJavadoc.setSelected( 1406 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_JAVADOC))); 1407 chkHints.setSelected( 1408 Boolean.TRUE.equals(wizard.getProperty(GuiUtils.CHK_HINTS))); 1409 } 1410 1411 public void storeSettings(Object settings) { 1412 wizard = (TemplateWizard) settings; 1413 1414 wizard.putProperty(SimpleTestCaseWizard.PROP_CLASS_TO_TEST, 1415 srcFile); 1416 wizard.putProperty(SimpleTestCaseWizard.PROP_TEST_ROOT_FOLDER, 1417 testRootFolder); 1418 wizard.putProperty(GuiUtils.CHK_PUBLIC, 1419 Boolean.valueOf(chkPublic.isSelected())); 1420 wizard.putProperty(GuiUtils.CHK_PROTECTED, 1421 Boolean.valueOf(chkProtected.isSelected())); 1422 wizard.putProperty(GuiUtils.CHK_PACKAGE, 1423 Boolean.valueOf(chkPackagePrivate.isSelected())); 1424 wizard.putProperty(GuiUtils.CHK_SETUP, 1425 Boolean.valueOf(chkSetUp.isSelected())); 1426 wizard.putProperty(GuiUtils.CHK_TEARDOWN, 1427 Boolean.valueOf(chkTearDown.isSelected())); 1428 wizard.putProperty(GuiUtils.CHK_METHOD_BODIES, 1429 Boolean.valueOf(chkMethodBodies.isSelected())); 1430 wizard.putProperty(GuiUtils.CHK_JAVADOC, 1431 Boolean.valueOf(chkJavadoc.isSelected())); 1432 wizard.putProperty(GuiUtils.CHK_HINTS, 1433 Boolean.valueOf(chkHints.isSelected())); 1434 } 1435 1436 public void addChangeListener(ChangeListener l) { 1437 if (changeListeners == null) { 1438 changeListeners = new ArrayList <ChangeListener >(4); 1439 } 1440 changeListeners.add(l); 1441 } 1442 1443 public void removeChangeListener(ChangeListener l) { 1444 if (changeListeners != null) { 1445 if (changeListeners.remove(l) && changeListeners.isEmpty()) { 1446 changeListeners = null; 1447 } 1448 } 1449 } 1450 1451 private void fireChange() { 1452 if (changeListeners != null) { 1453 ChangeEvent e = new ChangeEvent (this); 1454 for (ChangeListener l : changeListeners) { 1455 l.stateChanged(e); 1456 } 1457 } 1458 } 1459 1460 1462 void setUp(final Utils utils) { 1463 final Project project = utils.getProject(); 1464 1465 if (project == this.project) { 1466 return; 1467 } 1468 1469 this.project = project; 1470 this.sourcesToTestsMap = utils.getSourcesToTestsMap(true); 1471 1472 int sourceGroupsCnt = sourcesToTestsMap.size(); 1473 Set <Map.Entry <SourceGroup,Object []>> mapEntries = sourcesToTestsMap.entrySet(); 1474 List <SourceGroup> testGroups = new ArrayList <SourceGroup>(sourceGroupsCnt + 4); 1475 1476 testableSourceGroups = new SourceGroup[sourceGroupsCnt]; 1477 testableSourceGroupsRoots = new FileObject[sourceGroupsCnt]; 1478 multipleSourceRoots = (sourceGroupsCnt > 1); 1479 1480 Iterator <Map.Entry <SourceGroup,Object []>> iterator = mapEntries.iterator(); 1481 for (int i = 0; i < sourceGroupsCnt; i++) { 1482 Map.Entry <SourceGroup,Object []> entry = iterator.next(); 1483 SourceGroup srcGroup = entry.getKey(); 1484 1485 testableSourceGroups[i] = srcGroup; 1486 testableSourceGroupsRoots[i] = srcGroup.getRootFolder(); 1487 1488 Object [] testGroupsSubset = entry.getValue(); 1489 for (int j = 0; j < testGroupsSubset.length; j++) { 1490 SourceGroup testGroup = (SourceGroup) testGroupsSubset[j]; 1491 if (!testGroups.contains(testGroup)) { 1492 testGroups.add(testGroup); 1493 } 1494 } 1495 } 1496 allTestSourceGroups = testGroups.toArray( 1497 new SourceGroup[testGroups.size()]); 1498 1499 tfProjectName.setText( 1500 ProjectUtils.getInformation(project).getDisplayName()); 1501 try { 1502 programmaticChange = true; 1503 1504 ignoreClsNameChanges = true; 1505 tfClassToTest.setText(""); ignoreClsNameChanges = false; 1507 1508 classNameLength = 0; 1509 classNameChanged(); 1510 srcGroupNameDisplayed = false; 1511 setNavigationFilterEnabled(false); 1512 } finally { 1513 ignoreClsNameChanges = false; 1514 programmaticChange = false; 1515 } 1516 if (checkClassNameValidity()) { 1517 checkSelectedClassExists(); 1518 } else { 1519 classExists = false; 1520 } 1521 setErrorMsg(msgStack.getDisplayedMessage()); 1522 setValidity(); 1523 1524 updateLocationComboBox(); 1527 updateTargetFolderData(); updateCreatedFileName(); 1529 1530 srcFile = null; 1531 1532 if (!multipleSourceRoots) { 1533 setInteractionRestrictionsEnabled(false); 1534 } else { 1535 AbstractDocument doc = (AbstractDocument ) 1536 tfClassToTest.getDocument(); 1537 if (clsNameDocumentFilter == null) { 1538 clsNameDocumentFilter = new ClsNameDocumentFilter(); 1539 } 1540 if (doc.getDocumentFilter() != clsNameDocumentFilter) { 1541 doc.setDocumentFilter(clsNameDocumentFilter); 1542 } 1543 setInteractionRestrictionsEnabled(true); 1544 } 1545 } 1546 1547 1549 void cleanUp() { 1550 setInteractionRestrictionsEnabled(false); 1551 } 1552 1553 1556 private void setInteractionRestrictionsEnabled(boolean enabled) { 1557 if (enabled == interactionRestrictionsEnabled) { 1558 return; 1559 } 1560 1561 class DisplayabilityListener implements HierarchyListener { 1562 public void hierarchyChanged(HierarchyEvent e) { 1563 long flags = e.getChangeFlags(); 1564 if ((flags & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) { 1565 if (visualComp.isDisplayable()) { 1566 if (interactionRestrictionsEnabled) { 1567 setInteractionRestrictionsActive(true); 1568 } 1569 } else { 1570 setInteractionRestrictionsActive(false); 1571 } 1572 } 1573 } 1574 } 1575 1576 if (enabled) { 1577 this.interactionRestrictionsEnabled = true; 1578 1579 assert displayabilityListener == null; 1580 displayabilityListener = new DisplayabilityListener(); 1581 visualComp.addHierarchyListener(displayabilityListener); 1582 1583 if (visualComp.isDisplayable()) { 1584 setInteractionRestrictionsActive(true); 1585 } 1586 } else { 1587 this.interactionRestrictionsEnabled = false; 1588 1589 setInteractionRestrictionsActive(false); 1590 1591 visualComp.removeHierarchyListener(displayabilityListener); 1592 displayabilityListener = null; 1593 } 1594 } 1595 1596 1600 private void setInteractionRestrictionsActive(boolean active) { 1601 if (active == this.interactionRestrictionsActive) { 1602 return; 1603 } 1604 1605 if (active) { 1606 tryActivateInteractionRestrictions(); 1607 } else { 1608 deactivateInteractionRestrictions(); 1609 } 1610 } 1611 1612 1614 private void tryActivateInteractionRestrictions() { 1615 assert interactionRestrictionsActive == false; 1616 assert interactionRestrictionsEnabled; 1617 1618 if (rootPane == null) { 1619 rootPane = SwingUtilities.getRootPane(visualComp); 1620 } 1621 1622 if (rootPane != null) { 1623 defaultButton = rootPane.getDefaultButton(); 1624 if (defaultButton != null) { 1625 activateInteractionRestrictions(); 1626 } 1627 } 1628 } 1629 1630 1632 private void activateInteractionRestrictions() { 1633 assert interactionRestrictionsActive == false; 1634 assert (rootPane != null) && (defaultButton != null); 1635 1636 if ((mouseBlocked == null) || (mnemonicBlocked == null)) { 1637 findComponentsToBlock(); 1638 assert (mouseBlocked != null) && (mnemonicBlocked != null); 1639 } 1640 blockDefaultRootPaneAction(); 1641 blockMnemonics(); 1642 setMouseClicksBlockingActive(!interactionRestrictionsSuspended); 1643 1644 interactionRestrictionsActive = true; 1645 } 1646 1647 1649 private void deactivateInteractionRestrictions() { 1650 assert interactionRestrictionsActive == true; 1651 assert (defaultButton != null) && (rootPane != null); 1652 1653 setMouseClicksBlockingActive(false); 1654 unblockMnemonics(); 1655 unblockDefaultRootPaneAction(); 1656 1657 defaultButton = null; 1658 rootPane = null; 1659 1660 interactionRestrictionsActive = false; 1661 interactionRestrictionsSuspended = false; 1662 } 1663 1664 1666 private void setInteractionRestrictionsSuspended(boolean suspended) { 1667 if (suspended != this.interactionRestrictionsSuspended) { 1668 setMouseClicksBlockingActive(interactionRestrictionsActive 1669 && !suspended); 1670 this.interactionRestrictionsSuspended = suspended; 1671 } 1672 } 1673 1674 1676 private void setMouseClicksBlockingActive(boolean blockingActive) { 1677 if (blockingActive != this.mouseClicksBlocked) { 1678 if (blockingActive) { 1679 blockMouseClicks(); 1680 } else { 1681 unblockMouseClicks(); 1682 } 1683 this.mouseClicksBlocked = blockingActive; 1684 } 1685 } 1686 1687 1695 private void findComponentsToBlock() { 1696 assert rootPane != null; 1697 1698 final Collection <Component > mouseBlocked 1699 = new ArrayList <Component >(20); 1700 final Collection <JComponent > mnemBlocked 1701 = new ArrayList <JComponent >(20); 1702 1703 final List <Component > stack = new ArrayList <Component >(16); 1704 stack.add(rootPane.getContentPane()); 1705 int lastIndex = 0; 1706 1707 while (lastIndex != -1) { 1708 1709 Component c = stack.remove(lastIndex--); 1710 1711 if (!c.isVisible()) { 1712 continue; 1713 } 1714 1715 if (c instanceof JLabel ) { 1716 JLabel lbl = (JLabel ) c; 1717 Component labelFor = lbl.getLabelFor(); 1718 if ((labelFor != null) && (labelFor != tfClassToTest) 1719 && (lbl.getDisplayedMnemonic() != 0)) { 1720 mnemBlocked.add(lbl); 1721 } 1722 } else if (c instanceof AbstractButton ) { 1723 if (c != btnBrowse) { 1724 AbstractButton btn = (AbstractButton ) c; 1725 mouseBlocked.add(btn); 1726 if (btn.getMnemonic() != 0) { 1727 mnemBlocked.add(btn); 1728 } 1729 } 1730 } else if (!(c instanceof Container )) { 1731 if (c.isFocusable() && (c != tfClassToTest)) { 1732 mouseBlocked.add(c); 1733 } 1734 } else { 1735 Component [] content = ((Container ) c).getComponents(); 1736 switch (content.length) { 1737 case 0: 1738 break; 1739 case 1: 1740 stack.add(content[0]); 1741 lastIndex++; 1742 break; 1743 default: 1744 stack.addAll(Arrays.asList(content)); 1745 lastIndex += content.length; 1746 break; 1747 } 1748 } 1749 } 1750 1753 this.mouseBlocked = new Component [mouseBlocked.size()]; 1754 if (mouseBlocked.size() != 0) { 1755 mouseBlocked.toArray(this.mouseBlocked); 1756 } 1757 this.mnemonicBlocked = new JComponent [mnemBlocked.size()]; 1758 if (mnemBlocked.size() != 0) { 1759 mnemBlocked.toArray(this.mnemonicBlocked); 1760 } 1761 } 1762 1763 1765 private void blockDefaultRootPaneAction() { 1766 assert (rootPane != null) && (defaultButton != null) 1767 && (rootPane.getDefaultButton() == defaultButton); 1768 1769 final String actionKey1 = "press"; final String actionKey2 = "pressed"; String actionKey; 1772 1773 ActionMap actionMap = rootPane.getActionMap(); 1774 1775 Action originalAction = actionMap.get(actionKey = actionKey1); 1776 if (originalAction == null) { 1777 originalAction = actionMap.get(actionKey = actionKey2); 1778 } 1779 assert originalAction != null; 1780 1781 if (originalAction == null) { 1782 return; 1783 } 1784 1785 actionMap.put(actionKey, new SelectSrcGrpAction(rootPane, 1786 originalAction)); 1787 rootPaneDefaultActionKey = actionKey; 1788 rootPaneDefaultAction = originalAction; 1789 } 1790 1791 1793 private void unblockDefaultRootPaneAction() { 1794 assert rootPane != null; 1795 1796 if (rootPaneDefaultAction == null) { 1797 1798 1799 return; 1800 } 1801 1802 rootPane.getActionMap().put(rootPaneDefaultActionKey, 1803 rootPaneDefaultAction); 1804 1805 rootPaneDefaultActionKey = null; 1806 rootPaneDefaultAction = null; 1807 } 1808 1809 1812 private void blockMnemonics() { 1813 assert rootPane != null; 1814 1815 if (actionMappingInfo == null) { 1816 findActionMappings(); 1817 } 1818 1819 assert actionMappingInfo != null; 1820 assert actionMappingInfo.length == mnemonicBlocked.length; 1821 1822 final JComponent [] comps = mnemonicBlocked; 1823 for (int i = 0; i < comps.length; i++) { 1824 ActionMappingInfo mappingInfo = actionMappingInfo[i]; 1825 if (mappingInfo != null) { 1826 comps[i].getActionMap().put( 1827 mappingInfo.actionKey, 1828 new SelectSrcGrpAction(comps[i], 1829 mappingInfo.originalAction)); 1830 } else if (comps[i] instanceof JLabel ) { 1831 ActionMap map = new JLabelActionMap(comps[i]); 1832 map.setParent(comps[i].getActionMap()); 1833 comps[i].setActionMap(map); 1834 continue; 1835 } 1836 } 1837 } 1838 1839 1841 private void unblockMnemonics() { 1842 assert rootPane != null; 1843 1844 if (actionMappingInfo == null) { 1845 1846 1847 return; 1848 } 1849 1850 assert actionMappingInfo.length == mnemonicBlocked.length; 1851 1852 final JComponent [] comps = mnemonicBlocked; 1853 for (int i = 0; i < comps.length; i++) { 1854 ActionMappingInfo mappingInfo = actionMappingInfo[i]; 1855 if (mappingInfo != null) { 1856 comps[i].getActionMap().put( 1857 mappingInfo.actionKey, 1858 mappingInfo.inProximateActionMap 1859 ? mappingInfo.originalAction 1860 : (Action ) null); 1861 } else if (comps[i] instanceof JLabel ) { 1862 comps[i].setActionMap(comps[i].getActionMap().getParent()); 1863 } 1864 } 1865 } 1866 1867 1869 private void findActionMappings() { 1870 assert mnemonicBlocked != null; 1871 1872 final String actionKey1 = "pressed"; final String actionKey2 = "press"; 1875 actionMappingInfo = new ActionMappingInfo[mnemonicBlocked.length]; 1876 1877 final JComponent [] comps = mnemonicBlocked; 1878 for (int i = 0; i < comps.length; i++) { 1879 JComponent c = comps[i]; 1880 1881 ActionMap actionMap = comps[i].getActionMap(); 1882 1883 String primaryKey = actionKey1; 1884 String secondaryKey = actionKey2; 1885 1886 if (c instanceof JLabel ) { 1887 actionMappingInfo[i] = null; 1888 continue; 1889 } 1890 1891 String actionKey; 1892 Action originalAction = actionMap.get(actionKey = primaryKey); 1893 if (originalAction == null) { 1894 originalAction = actionMap.get(actionKey = secondaryKey); 1895 } 1896 if (originalAction == null) { 1897 ErrorManager.getDefault() 1898 .log(ErrorManager.EXCEPTION, 1899 "JUnitWizard - Test for Existing Class: " + "press action not found for a " + c.getClass().getName() + " component"); actionMappingInfo[i] = null; 1903 continue; 1904 } 1905 1906 ActionMappingInfo mappingInfo = new ActionMappingInfo(); 1907 mappingInfo.actionKey = actionKey; 1908 mappingInfo.originalAction = originalAction; 1909 1911 1912 final String keyToFind = actionKey; 1913 final Object [] keys = actionMap.keys(); 1914 if (keys != null) { 1915 for (int j = 0; j < keys.length; j++) { 1916 if (keyToFind.equals(keys[j])) { 1917 mappingInfo.inProximateActionMap = true; 1918 break; 1919 } 1920 } 1921 } 1922 1923 actionMappingInfo[i] = mappingInfo; 1924 } 1925 } 1926 1927 1933 private static class ActionMappingInfo { 1934 1935 String actionKey; 1936 1937 Action originalAction; 1938 1942 boolean inProximateActionMap; 1943 } 1944 1945 1948 final class JLabelActionMap extends ActionMap { 1949 1950 private final Component component; 1951 1952 JLabelActionMap(Component comp) { 1953 super(); 1954 this.component = comp; 1955 } 1956 1957 public Action get(Object key) { 1958 if (key.equals("press")) { Action defaultAction = super.get(key); 1960 return (defaultAction != null) 1961 ? new SelectSrcGrpAction(component, defaultAction) 1962 : null; 1963 } else { 1964 return super.get(key); 1965 } 1966 } 1967 1968 } 1969 1970 1973 private void blockMouseClicks() { 1974 assert rootPane != null; 1975 1976 final Component glassPane = rootPane.getGlassPane(); 1977 1978 if (glassPaneListener == null) { 1979 glassPaneListener = new GlassPaneListener(); 1980 } 1981 glassPane.addMouseListener(glassPaneListener); 1982 glassPane.addMouseMotionListener(glassPaneListener); 1983 glassPane.setVisible(true); 1984 } 1985 1986 1990 private void unblockMouseClicks() { 1991 assert rootPane != null; 1992 1993 if (glassPaneListener == null) { 1994 return; 1995 } 1996 1997 final Component glassPane = rootPane.getGlassPane(); 1998 1999 glassPane.setVisible(false); 2000 glassPane.removeMouseMotionListener(glassPaneListener); 2001 glassPane.removeMouseListener(glassPaneListener); 2002 } 2003 2004 2007 final class GlassPaneListener implements MouseInputListener { 2008 final Component glassPane = rootPane.getGlassPane(); 2009 final Component layeredPane = rootPane.getLayeredPane(); 2010 final Container contentPane = rootPane.getContentPane(); 2011 2012 public void mouseMoved(MouseEvent e) { 2013 redispatchEvent(e); 2014 } 2015 public void mouseDragged(MouseEvent e) { 2016 redispatchEvent(e); 2017 } 2018 public void mouseClicked(MouseEvent e) { 2019 redispatchEvent(e); 2020 } 2021 public void mouseEntered(MouseEvent e) { 2022 redispatchEvent(e); 2023 } 2024 public void mouseExited(MouseEvent e) { 2025 redispatchEvent(e); 2026 } 2027 public void mousePressed(MouseEvent e) { 2028 evaluateEvent(e); 2029 } 2030 public void mouseReleased(MouseEvent e) { 2031 redispatchEvent(e); 2032 } 2033 private void evaluateEvent(MouseEvent e) { 2034 assert multipleSourceRoots; 2035 2036 Component component = getDeepestComponent(e); 2037 if (component == null) { 2038 return; 2039 } 2040 2041 boolean isBlocked = false; 2042 if (SwingUtilities.isLeftMouseButton(e)) { 2043 final Component [] blocked = mouseBlocked; 2044 for (int i = 0; i < blocked.length; i++) { 2045 if (component == blocked[i]) { 2046 isBlocked = true; 2047 break; 2048 } 2049 } 2050 } 2051 2052 boolean askUserToChoose; 2053 SourceGroup[] candidates = null; 2054 if (!isBlocked || interactionRestrictionsSuspended) { 2055 askUserToChoose = false; 2056 } else if (component == defaultButton) { 2057 candidates = findParentGroupCandidates(); 2058 askUserToChoose = (candidates.length > 1); 2059 } else if (!SwingUtilities.isDescendingFrom(component, 2060 visualComp)) { 2061 askUserToChoose = false; 2062 } else { 2063 candidates = findParentGroupCandidates(); 2064 askUserToChoose = (candidates.length > 1); 2065 } 2066 2067 assert (askUserToChoose == false) || (candidates.length > 1); 2068 2069 if (askUserToChoose) { 2070 SourceGroup srcGroup = chooseSrcGroup(candidates); 2071 if (srcGroup != null) { 2072 setSelectedSrcGroup(srcGroup); 2073 focusGainAllowedFor = component; 2074 component.requestFocus(); 2075 } 2076 } else { 2077 if (candidates != null) { 2078 assert candidates.length == 1; 2079 2080 setSelectedSrcGroup(candidates[0]); 2081 } 2082 focusGainAllowedFor = component; 2083 try { 2084 redispatchEvent(e, component); 2085 } finally { 2086 clearFocusGainAllowedVar(); 2087 } 2088 } 2089 } 2090 private void redispatchEvent(MouseEvent e) { 2091 Component deepestComp = getDeepestComponent(e); 2092 if (deepestComp != null) { 2093 redispatchEvent(e, deepestComp); 2094 } 2095 } 2096 private void redispatchEvent(MouseEvent e, Component component) { 2097 Point componentPoint 2098 = SwingUtilities.convertPoint(glassPane, 2099 e.getPoint(), 2100 component); 2101 component.dispatchEvent( 2102 new MouseEvent (component, 2103 e.getID(), 2104 e.getWhen(), 2105 e.getModifiers(), 2106 componentPoint.x, 2107 componentPoint.y, 2108 e.getClickCount(), 2109 e.isPopupTrigger())); 2110 } 2111 private Component getDeepestComponent(MouseEvent e) { 2112 Point contentPanePoint 2113 = SwingUtilities.convertPoint(glassPane, 2114 e.getPoint(), 2115 contentPane); 2116 return SwingUtilities.getDeepestComponentAt( 2117 contentPane, 2118 contentPanePoint.x, 2119 contentPanePoint.y); 2120 } 2121 } 2122 2123 2126 private class SelectSrcGrpAction extends AbstractAction { 2127 private final Component component; 2128 private final Action delegate; 2129 public SelectSrcGrpAction(Component comp, Action delegate) { 2130 this.component = comp; 2131 this.delegate = delegate; 2132 } 2133 public void actionPerformed(ActionEvent e) { 2134 assert multipleSourceRoots; 2135 2136 boolean askUserToChoose; 2137 SourceGroup[] candidates = null; 2138 if (interactionRestrictionsSuspended) { 2139 askUserToChoose = false; 2140 } else if ((component == defaultButton) 2141 || (component == rootPane)) { 2142 candidates = findParentGroupCandidates(); 2143 askUserToChoose = (candidates.length > 1); 2144 } else if (!SwingUtilities.isDescendingFrom(component, 2145 visualComp)) { 2146 askUserToChoose = false; 2147 } else { 2148 candidates = findParentGroupCandidates(); 2149 askUserToChoose = (candidates.length > 1); 2150 } 2151 2152 assert (askUserToChoose == false) || (candidates.length > 1); 2153 2154 if (askUserToChoose) { 2155 SourceGroup srcGroup = chooseSrcGroup(candidates); 2156 if (srcGroup != null) { 2157 setSelectedSrcGroup(srcGroup); 2158 if (component == rootPane) { 2159 defaultButton.requestFocus(); 2160 } else { 2161 component.requestFocus(); 2162 } 2163 } 2164 } else { 2165 if (candidates != null) { 2166 assert candidates.length == 1; 2167 2168 setSelectedSrcGroup(candidates[0]); 2169 } 2170 redispatchEvent(e); 2171 } 2172 } 2173 private void redispatchEvent(ActionEvent e) { 2174 focusGainAllowedFor = component; 2175 try { 2176 delegate.actionPerformed(e); 2177 } finally { 2178 clearFocusGainAllowedVar(); 2179 } 2180 } 2181 public boolean isEnabled() { 2182 return delegate.isEnabled(); 2183 } 2184 } 2185 2186 2189 private class ClsNameDocumentFilter extends DocumentFilter { 2190 public ClsNameDocumentFilter () {} 2191 2192 public void replace(DocumentFilter.FilterBypass bypass, 2193 int offset, 2194 int length, 2195 String text, 2196 AttributeSet attrs) throws BadLocationException { 2197 if (!programmaticChange && srcGroupNameDisplayed) { 2198 removeSrcGroupName(bypass); 2199 } 2200 super.replace(bypass, offset, length, text, attrs); 2201 } 2202 public void insertString( 2203 DocumentFilter.FilterBypass bypass, 2204 int offset, 2205 String string, 2206 AttributeSet attr) throws BadLocationException { 2207 if (!programmaticChange && srcGroupNameDisplayed) { 2208 removeSrcGroupName(bypass); 2209 } 2210 super.insertString(bypass, offset, string, attr); 2211 } 2212 public void remove(DocumentFilter.FilterBypass bypass, 2213 int offset, 2214 int length) throws BadLocationException { 2215 if (!programmaticChange && srcGroupNameDisplayed) { 2216 removeSrcGroupName(bypass); 2217 } 2218 super.remove(bypass, offset, length); 2219 } 2220 private void removeSrcGroupName(DocumentFilter.FilterBypass bypass) 2221 throws BadLocationException { 2222 bypass.remove(classNameLength, 2223 tfClassToTest.getText().length() - classNameLength); 2224 srcGroupNameDisplayed = false; 2225 setNavigationFilterEnabled(false); 2226 } 2227 } 2228 2229 2232 private class ClsNameNavigationFilter extends NavigationFilter { 2233 public ClsNameNavigationFilter () {} 2234 2235 public void setDot(NavigationFilter.FilterBypass bypass, 2236 int dot, 2237 Position.Bias bias) { 2238 if (dot > classNameLength) { 2239 bypass.setDot(classNameLength, bias); 2240 } else { 2241 super.setDot(bypass, dot, bias); 2242 } 2243 } 2244 public void moveDot(NavigationFilter.FilterBypass bypass, 2245 int dot, 2246 Position.Bias bias) { 2247 if (dot > classNameLength) { 2248 bypass.moveDot(classNameLength, bias); 2249 } else { 2250 super.moveDot(bypass, dot, bias); 2251 } 2252 } 2253 public void ensureCursorInRange() { 2254 if (srcGroupNameDisplayed) { 2255 if (tfClassToTest.getCaretPosition() > classNameLength) { 2256 tfClassToTest.setCaretPosition(classNameLength); 2257 } 2258 } 2259 } 2260 } 2261 2262 2266 private void clearFocusGainAllowedVar() { 2267 SwingUtilities.invokeLater(new Runnable () { 2268 public void run() { 2269 focusGainAllowedFor = null; 2270 } 2271 }); 2272 } 2273 2274 2276 private static boolean checkObjChanged(Object oldObj, Object newObj) { 2277 return ((oldObj != null) || (newObj != null)) 2278 && ((oldObj == null) || !oldObj.equals(newObj)); 2279 } 2280 2281 2305 2306} 2307 | Popular Tags |