1 19 20 21 package org.netbeans.modules.search; 22 23 24 import java.awt.BorderLayout ; 25 import java.awt.Component ; 26 import java.awt.Dialog ; 27 import java.awt.GridBagConstraints ; 28 import java.awt.GridBagLayout ; 29 import java.awt.Insets ; 30 import java.awt.event.ActionEvent ; 31 import java.awt.event.ActionListener ; 32 import java.beans.BeanInfo ; 33 import java.beans.Customizer ; 34 import java.beans.IntrospectionException ; 35 import java.beans.PropertyChangeEvent ; 36 import java.beans.PropertyChangeListener ; 37 import java.io.ByteArrayInputStream ; 38 import java.io.IOException ; 39 import java.io.ObjectInputStream ; 40 import java.util.Collection ; 41 import java.util.Collections ; 42 import java.util.ResourceBundle ; 43 import javax.swing.BorderFactory ; 44 import javax.swing.JComboBox ; 45 import javax.swing.JLabel ; 46 import javax.swing.JPanel ; 47 import javax.swing.JTextField ; 48 import org.netbeans.modules.search.types.FullTextCustomizer; 49 50 import org.openide.DialogDescriptor; 51 import org.openide.DialogDisplayer; 52 import org.openide.ErrorManager; 53 import org.openide.awt.Mnemonics; 54 import org.openide.util.HelpCtx; 55 import org.openide.util.NbBundle; 56 import org.openide.util.Utilities; 57 import org.openidex.search.SearchType; 58 59 60 67 public final class SearchTypePanel extends JPanel 68 implements PropertyChangeListener , 69 ActionListener , 70 DialogLifetime { 71 72 73 public static final String PROP_CUSTOMIZED = "customized"; 75 private static final String MODIFICATOR_SUFFIX = " *"; 78 private boolean customized; 79 80 private SearchType searchType; 81 87 private boolean initialized = false; 88 89 final Customizer customizer; 90 91 final Component customizerComponent; 92 97 private SearchCriterion[] savedCriteria; 98 99 private String lastSavedName; 100 101 102 103 public SearchTypePanel(SearchType searchType, 104 final boolean initFromHistory) { 105 initComponents(); 106 initAccessibility(); 107 108 this.searchType = searchType; 109 110 customizer = createCustomizer(this.searchType, initFromHistory); 111 if (customizer != null) { 112 customizerComponent = (Component ) customizer; 113 } else { 114 customizerComponent = null; 115 116 initialized = true; 118 System.err.println("No customizer for " + this.searchType.getName() 122 + ", skipping..."); } 124 125 customizer.setObject(this.searchType); 126 if (initFromHistory && (customizer instanceof FullTextCustomizer)) { 127 ((FullTextCustomizer) customizer).initFromHistory(); 128 } 129 this.searchType.addPropertyChangeListener(this); 130 131 ResourceBundle bundle = NbBundle.getBundle(SearchTypePanel.class); 132 Mnemonics.setLocalizedText( 133 applyCheckBox, 134 bundle.getString("TEXT_BUTTON_APPLY")); 136 Mnemonics.setLocalizedText( 137 saveButton, 138 bundle.getString("TEXT_BUTTON_SAVE_AS")); 140 saveButton.setEnabled(false); 141 142 Mnemonics.setLocalizedText( 143 restoreButton, 144 bundle.getString("TEXT_BUTTON_RESTORE")); 146 147 restoreButton.setEnabled(false); 148 149 customizerPanel.add(customizerComponent, BorderLayout.CENTER); 150 151 setCustomized(this.searchType.isValid()); 152 153 setName(createName()); 155 } 156 157 private void initAccessibility() { 158 ResourceBundle bundle = NbBundle.getBundle(SearchTypePanel.class); 159 this.getAccessibleContext().setAccessibleDescription( 160 bundle.getString("ACS_DIALOG_DESC")); restoreButton.getAccessibleContext().setAccessibleDescription( 162 bundle.getString("ACS_TEXT_BUTTON_RESTORE")); saveButton.getAccessibleContext().setAccessibleDescription( 164 bundle.getString("ACS_TEXT_BUTTON_SAVE_AS")); applyCheckBox.getAccessibleContext().setAccessibleDescription( 166 bundle.getString("ACS_TEXT_BUTTON_APPLY")); } 168 169 174 private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; 176 177 customizerPanel = new javax.swing.JPanel (); 178 179 setLayout(new java.awt.GridBagLayout ()); 180 181 customizerPanel.setLayout(new java.awt.BorderLayout ()); 182 183 gridBagConstraints = new java.awt.GridBagConstraints (); 184 gridBagConstraints.gridwidth = 2; 185 gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; 186 gridBagConstraints.weightx = 1.0; 187 gridBagConstraints.weighty = 1.0; 188 gridBagConstraints.insets = new java.awt.Insets (11, 11, 0, 11); 189 add(customizerPanel, gridBagConstraints); 190 191 applyCheckBox.addActionListener(this); 192 gridBagConstraints = new java.awt.GridBagConstraints (); 193 gridBagConstraints.gridx = 0; 194 gridBagConstraints.gridy = 1; 195 gridBagConstraints.gridwidth = 2; 196 gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; 197 gridBagConstraints.insets = new java.awt.Insets (17, 11, 0, 11); 198 add(applyCheckBox, gridBagConstraints); 199 200 saveButton.addActionListener(this); 201 gridBagConstraints = new java.awt.GridBagConstraints (); 202 gridBagConstraints.gridx = 0; 203 gridBagConstraints.gridy = 2; 204 gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; 205 gridBagConstraints.weightx = 1.0; 206 gridBagConstraints.insets = new java.awt.Insets (11, 11, 11, 0); 207 add(saveButton, gridBagConstraints); 208 209 restoreButton.addActionListener(this); 210 gridBagConstraints = new java.awt.GridBagConstraints (); 211 gridBagConstraints.gridx = 1; 212 gridBagConstraints.gridy = 2; 213 gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; 214 gridBagConstraints.insets = new java.awt.Insets (11, 11, 11, 11); 215 add(restoreButton, gridBagConstraints); 216 217 } 219 220 private final javax.swing.JCheckBox applyCheckBox = new javax.swing.JCheckBox (); 222 private javax.swing.JPanel customizerPanel; 223 private final javax.swing.JButton restoreButton = new javax.swing.JButton (); 224 private final javax.swing.JButton saveButton = new javax.swing.JButton (); 225 227 232 public void actionPerformed(ActionEvent e) { 233 final Object source = e.getSource(); 234 235 if (source == applyCheckBox) { 236 237 238 boolean selected = applyCheckBox.isSelected(); 239 setCustomized(selected); 240 searchType.setValid(selected); 241 242 } else if (source == saveButton) { 243 saveCriterion(); 244 245 } else if (source == restoreButton) { 246 restoreCriterion(); 247 248 } else { 249 250 251 assert false; 252 } 253 } 254 255 258 public void propertyChange(PropertyChangeEvent evt) { 259 if (evt.getSource() == searchType) { 260 261 if (SearchType.PROP_VALID.equals(evt.getPropertyName()) ) { 264 265 if (evt.getNewValue().equals(Boolean.FALSE)) { 266 setCustomized (false); 267 return; 268 } else { 269 setCustomized (true); 270 } 271 } 272 } 273 } 274 275 public void onOk() { 276 if (customizer instanceof DialogLifetime) { 277 ((DialogLifetime)customizer).onOk(); 278 } 279 } 280 281 public void onCancel() { 282 if (customizer instanceof DialogLifetime) { 283 ((DialogLifetime)customizer).onCancel(); 284 } 285 } 286 287 290 private String createName() { 291 String name = searchType.getName(); 292 293 if(customized) { 294 return name + MODIFICATOR_SUFFIX; 295 } else { 296 return name; 297 } 298 } 299 300 307 private static Customizer createCustomizer(final SearchType searchType, 308 final boolean initFromHistory) { 309 final Class searchTypeClass = searchType.getClass(); 310 Class clazz = null; 311 312 if (isDefaultSearchType(searchTypeClass)) { 313 String typeClassName = searchType.getClass().getName(); 314 assert typeClassName.endsWith("Type"); 316 int typeNameLen = typeClassName.length(); 317 String customizerClassName 318 = new StringBuffer (typeNameLen + 6) 319 .append(typeClassName.substring(0, typeNameLen - 4)) 320 .append("Customizer") .toString(); 322 try { 323 clazz = Class.forName(customizerClassName); 324 } catch (Exception ex) { 325 assert false; 326 ErrorManager.getDefault().notify(ErrorManager.ERROR, ex); 327 } 328 } 329 330 if (clazz == null) { 331 final BeanInfo beanInfo; 332 try { 333 beanInfo = Utilities.getBeanInfo(searchTypeClass); 334 } catch (IntrospectionException ie) { 335 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ie); 336 return null; 337 } 338 339 clazz = beanInfo.getBeanDescriptor ().getCustomizerClass (); 340 } 341 if (clazz == null) return null; 342 343 Object o; 344 try { 345 o = clazz.newInstance (); 346 } catch (InstantiationException e) { 347 return null; 348 } catch (IllegalAccessException e) { 349 return null; 350 } 351 352 if (!(o instanceof Component ) || 353 !(o instanceof Customizer )) return null; 354 return (Customizer ) o; 355 } 356 357 367 private static boolean isDefaultSearchType(Class searchTypeClass) { 368 assert SearchType.class.isAssignableFrom(searchTypeClass); 369 370 String mandatoryPackage = "org.netbeans.modules.search.types"; 372 String className = searchTypeClass.getName(); 373 return className.startsWith(mandatoryPackage) 374 && (className.lastIndexOf('.') == mandatoryPackage.length()); 375 } 376 377 382 private void setCustomized(boolean cust) { 383 customized = cust; 384 385 saveButton.setEnabled(customized); 386 applyCheckBox.setSelected(customized); 387 388 setName(createName()); 389 390 firePropertyChange(PROP_CUSTOMIZED, !cust, cust); 391 } 392 393 394 public boolean isCustomized() { 395 return customized; 396 } 397 398 399 private void saveCriterion() { 400 JPanel pane = new JPanel (); 401 pane.setLayout(new BorderLayout (12,0)); 402 403 ResourceBundle bundle = NbBundle.getBundle(SearchTypePanel.class); 404 JLabel nameLab = new JLabel (); 405 Mnemonics.setLocalizedText( 406 nameLab, 407 bundle.getString("TEXT_LABEL_NAME")); 409 pane.add(nameLab, BorderLayout.WEST); 410 pane.getAccessibleContext().setAccessibleDescription( 411 bundle.getString("ACS_SaveAsPanel")); 413 JTextField textField; 414 if (lastSavedName != null) { 415 textField = new JTextField (lastSavedName, 20); 416 } else { 417 textField = new JTextField (20); 418 } 419 textField.getAccessibleContext().setAccessibleDescription( 420 bundle.getString("ACS_TEXT_LABEL_SELECT")); 422 nameLab.setLabelFor(textField); 423 pane.add(textField, BorderLayout.CENTER); 424 pane.setBorder(BorderFactory.createEmptyBorder(12,12,0,11)); 425 426 DialogDescriptor desc = new DialogDescriptor( 427 pane, 428 bundle.getString("TEXT_LABEL_SAVE_CRITERION")); Dialog dialog = DialogDisplayer.getDefault().createDialog(desc); 430 431 while (true) { 432 dialog.setVisible(true); 433 if (desc.getValue().equals(DialogDescriptor.OK_OPTION)) { 434 String name = textField.getText(); 435 if (name.length() > 0) { 436 saveCriterion(name); 437 lastSavedName = name; 438 break; 439 } 440 } else { 441 return; } 443 } 444 } 445 446 447 private void saveCriterion(String name) { 448 SearchType copy = (SearchType) searchType.clone(); 449 copy.setName(name); 450 451 SearchCriterion toSave; 452 try { 453 toSave = new SearchCriterion(copy); 454 } catch (IOException ex) { 455 ErrorManager.getDefault().notify(ErrorManager.EXCEPTION, ex); 456 return; 457 } 458 459 460 String className = toSave.searchTypeClassName; 461 boolean found = false; 462 if (savedCriteria != null) { 463 for (int i = 0; i < savedCriteria.length; i++) { 464 if (savedCriteria[i].name.equals(name) 465 && savedCriteria[i].searchTypeClassName.equals(className)) { 466 found = true; 467 SearchProjectSettings.getInstance() 468 .replaceSearchCriterion(name, className, toSave); 469 savedCriteria[i] = toSave; 470 break; 471 } 472 } 473 } 474 if (!found) { 475 SearchProjectSettings.getInstance().addSearchCriterion(toSave); 476 addSavedCriteria(Collections.singleton(toSave)); 477 } 478 } 479 480 484 private void restoreCriterion() { 485 JPanel pane = new JPanel (); 486 pane.setLayout(new GridBagLayout ()); 487 488 ResourceBundle bundle = NbBundle.getBundle(SearchTypePanel.class); 489 pane.getAccessibleContext().setAccessibleDescription( 490 bundle.getString("ACS_RestorePanel")); 492 JLabel resLabel = new JLabel (); 493 Mnemonics.setLocalizedText( 494 resLabel, 495 bundle.getString("TEXT_LABEL_SELECT")); 497 JComboBox combo = new JComboBox (savedCriteria); 498 combo.getAccessibleContext().setAccessibleDescription( 499 bundle.getString("ACSD_SELECT_CRITERION")); resLabel.setLabelFor(combo); 501 502 GridBagConstraints gbc = new GridBagConstraints (); 503 gbc.insets = new Insets (0, 0, 0, 12); 504 pane.add(resLabel, gbc); 505 506 gbc.fill = GridBagConstraints.HORIZONTAL; 507 gbc.weightx = 1.0d; 508 gbc.insets = new Insets (0, 0, 0, 0); 509 pane.add(combo, gbc); 510 511 pane.setBorder(BorderFactory.createEmptyBorder(12,12,0,11)); 512 513 DialogDescriptor desc = new DialogDescriptor( 514 pane, 515 bundle.getString("TEXT_LABEL_RESTORE_CRITERION")); DialogDisplayer.getDefault().createDialog(desc).setVisible(true); 517 518 if (desc.getValue().equals(DialogDescriptor.OK_OPTION)) { 519 SearchCriterion c = (SearchCriterion) combo.getSelectedItem(); 520 restoreCriterion(c); 521 } 522 } 523 524 525 private void restoreCriterion(SearchCriterion c) { 526 SearchType searchType; 527 ObjectInputStream ois = null; 528 try { 529 ois = new SearchTypeInputStream( 530 new ByteArrayInputStream (c.criterionData)); 531 searchType = (SearchType) ois.readObject(); 532 } catch (Exception ex) { 533 String msg = NbBundle.getMessage( 534 SearchTypePanel.class, 535 "TEXT_MSG_Error_while_loading_criterion"); ErrorManager.getDefault().notify( 537 ErrorManager.EXCEPTION, 538 ErrorManager.getDefault().annotate(ex, msg)); 539 return; 540 } finally { 541 if (ois != null) { 542 try { 543 ois.close(); 544 } catch (IOException ex2) { 545 546 } 547 } 548 } 549 restoreSearchType(searchType); 550 } 551 552 553 private void restoreSearchType(SearchType searchType) { 554 this.searchType.removePropertyChangeListener(this); 555 556 this.searchType = (SearchType) searchType.clone(); 557 initialized = false; 558 initializeWithObject(); 559 this.searchType.addPropertyChangeListener(this); 560 561 setCustomized(true); 562 } 563 564 568 final void initializeWithObject() { 569 if (!initialized) { 570 customizer.setObject(this.searchType); 571 initialized = true; 572 } 573 } 574 575 576 public SearchType getSearchType() { 577 return searchType; 578 } 579 580 585 public boolean equals(Object obj) { 586 try { 587 return searchType.getClass().equals( 588 ((SearchTypePanel) obj).getSearchType().getClass()); 589 } catch (ClassCastException ex) { 590 return false; 591 } 592 } 593 594 595 public HelpCtx getHelpCtx() { 596 return searchType.getHelpCtx(); 597 } 598 599 605 void addSavedCriteria(Collection criteria) { 606 if (criteria.isEmpty()) { 607 return; 608 } 609 610 SearchCriterion[] newCriteria = new SearchCriterion[criteria.size()]; 611 criteria.toArray(newCriteria); 612 if (savedCriteria == null) { 613 savedCriteria = newCriteria; 614 restoreButton.setEnabled(true); 615 } else { 616 617 618 SearchCriterion[] oldCriteria = savedCriteria; 619 savedCriteria = new SearchCriterion[oldCriteria.length 620 + newCriteria.length]; 621 System.arraycopy(oldCriteria, 0, 622 savedCriteria, 0, 623 oldCriteria.length); 624 System.arraycopy(newCriteria, 0, 625 savedCriteria, oldCriteria.length, 626 newCriteria.length); 627 } 628 } 629 630 } 631 | Popular Tags |