1 19 package org.openide.explorer.propertysheet; 20 21 import org.openide.DialogDescriptor; 22 import org.openide.DialogDisplayer; 23 import org.openide.explorer.propertysheet.editors.EnhancedCustomPropertyEditor; 24 import org.openide.nodes.Node; 25 import org.openide.util.HelpCtx; 26 import org.openide.util.NbBundle; 27 28 import java.awt.Component ; 29 import java.awt.Window ; 30 import java.awt.event.*; 31 32 import java.beans.*; 33 import java.util.logging.Level ; 34 import java.util.logging.Logger ; 35 36 import javax.swing.JButton ; 37 import javax.swing.JComponent ; 38 import javax.swing.UIManager ; 39 import org.openide.awt.Mnemonics; 40 import org.openide.util.Exceptions; 41 42 43 48 final class PropertyDialogManager implements VetoableChangeListener, ActionListener { 49 50 private static final String PROPERTY_DESCRIPTION = "description"; private static Throwable doNotNotify; 52 53 54 55 56 private PropertyChangeListener listener; 57 58 59 private Object oldValue; 60 61 62 private PropertyEditor editor; 63 64 65 private PropertyModel model; 66 67 68 private Node.Property prop; 69 70 71 private boolean changed = false; 72 73 74 private Component component; 75 76 77 private Window dialog; 78 79 80 private JButton okButton; 81 82 83 private Runnable errorPerformer; 84 private boolean okButtonState = true; 85 private Object envStateBeforeDisplay = null; 86 87 88 private PropertyEnv env; 89 private Object lastValueFromEditor; 90 private boolean cancelled = false; 91 private boolean ok = false; 92 private boolean reset = false; 93 94 public PropertyDialogManager( 95 String title, final boolean isModal, final PropertyEditor editor, PropertyModel model, 96 final PropertyEnv env 97 ) { 98 this.editor = editor; 99 100 if (env != null) { 101 env.addVetoableChangeListener(this); 102 } 103 104 this.component = editor.getCustomEditor(); 105 106 if (component == null) { 107 throw new NullPointerException ( 108 "Cannot create a dialog" + " for a null component. Offending property editor class:" + 109 editor.getClass().getName() 110 ); 111 } 112 113 this.model = model; 114 this.env = env; 115 116 HelpCtx helpCtx = null; 117 if (env != null) { 118 Object helpID = env.getFeatureDescriptor().getValue(ExPropertyEditor.PROPERTY_HELP_ID); 119 120 if ((helpID != null) && helpID instanceof String && (component != null) && component instanceof JComponent ) { 121 HelpCtx.setHelpIDString((JComponent ) component, (String ) helpID); 122 helpCtx = new HelpCtx((String ) helpID); 123 } 124 } 125 126 if (component instanceof JComponent ) { 128 Object compTitle = ((JComponent ) component).getClientProperty("title"); 129 130 if (compTitle instanceof String ) { 131 title = (String ) compTitle; 132 } 133 } 134 135 createDialog(isModal, title, helpCtx); 137 initializeListeners(); 138 } 139 140 142 145 public Window getDialog() { 146 return dialog; 147 } 148 149 153 public void vetoableChange(PropertyChangeEvent evt) 154 throws PropertyVetoException { 155 if ((env != null) && (PropertyEnv.PROP_STATE.equals(evt.getPropertyName()))) { 156 okButtonState = evt.getNewValue() != PropertyEnv.STATE_INVALID; 157 158 if (okButton != null) { 159 okButton.setEnabled(okButtonState); 160 } 161 } 162 } 163 164 166 169 private void createDialog(boolean isModal, String title, HelpCtx helpCtx) { 170 if (component instanceof Window ) { 171 dialog = (Window ) component; 174 dialog.pack(); 175 176 return; 177 } 178 179 boolean cannotWrite = false; 181 boolean defaultValue = false; 182 183 if (model instanceof ExPropertyModel) { 184 FeatureDescriptor fd = ((ExPropertyModel) model).getFeatureDescriptor(); 185 186 if (fd instanceof Node.Property) { 187 prop = (Node.Property) fd; 188 cannotWrite = !prop.canWrite(); 189 defaultValue = PropUtils.shallBeRDVEnabled(prop); 190 } 191 } 192 193 Object defaultOption; 194 Object [] options; 195 196 if ((editor == null) || (cannotWrite)) { 197 JButton closeButton = new JButton (getString("CTL_Close")); 198 closeButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_CTL_Close")); 199 options = new Object [] { closeButton }; 200 defaultOption = closeButton; 201 } else { 202 okButton = new JButton (getString("CTL_OK")); 203 okButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_CTL_OK")); 204 205 JButton cancelButton = new JButton (getString("CTL_Cancel")); 206 cancelButton.setVerifyInputWhenFocusTarget(false); 207 cancelButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_CTL_Cancel")); 208 cancelButton.setDefaultCapable(false); 209 210 if (defaultValue) { 211 JButton defaultButton = new JButton (); 212 String name = getString("CTL_Default"); 213 Mnemonics.setLocalizedText(defaultButton, name); 214 defaultButton.setActionCommand(name); 215 defaultButton.getAccessibleContext().setAccessibleDescription(getString("ACSD_CTL_Default")); 216 defaultButton.setDefaultCapable(false); 217 defaultButton.setVerifyInputWhenFocusTarget(false); 218 219 if ("Aqua".equals(UIManager.getLookAndFeel().getID())) { 220 options = new Object [] { defaultButton, cancelButton, okButton }; 222 } else { 223 options = new Object [] { okButton, defaultButton, cancelButton }; 224 } 225 } else { 226 if ("Aqua".equals(UIManager.getLookAndFeel().getID())) { 227 options = new Object [] { cancelButton, okButton }; 228 } else { 229 options = new Object [] { okButton, cancelButton }; 230 } 231 } 232 233 defaultOption = okButton; 234 } 235 236 if ((env != null) && (okButton != null)) { 237 okButtonState = env.getState() != PropertyEnv.STATE_INVALID; 238 239 if (okButton != null) { 240 okButton.setEnabled(okButtonState); 241 } 242 } 243 244 if (env != null) { 245 envStateBeforeDisplay = env.getState(); 246 } 247 248 249 DialogDescriptor descriptor = new DialogDescriptor(component, title, 252 isModal, options, defaultOption, DialogDescriptor.DEFAULT_ALIGN, 253 helpCtx, this); 254 dialog = DialogDisplayer.getDefault().createDialog(descriptor); 255 } 256 257 260 private void initializeListeners() { 261 dialog.addWindowListener( 263 new WindowAdapter() { 264 266 public void windowClosing(WindowEvent e) { 267 if ((editor != null) && !(component instanceof Window )) { 268 cancelValue(); 271 } 272 273 if (env != null) { 275 env.removeVetoableChangeListener(PropertyDialogManager.this); 276 } 277 278 dialog.dispose(); 279 } 280 281 282 public void windowClosed(WindowEvent e) { 283 if (component instanceof Window ) { 284 if (component instanceof EnhancedCustomPropertyEditor) { 291 try { 292 Object newValue = ((EnhancedCustomPropertyEditor) component).getPropertyValue(); 293 model.setValue(newValue); 294 } catch (java.lang.reflect.InvocationTargetException ite) { 295 notifyUser(ite); 296 } catch (IllegalStateException ise) { 297 notifyUser(ise); 298 } 299 } else if ((env != null) && (!env.isChangeImmediate())) { 300 try { 301 model.setValue(lastValueFromEditor); 302 } catch (java.lang.reflect.InvocationTargetException ite) { 303 notifyUser(ite); 304 } catch (IllegalStateException ise) { 305 notifyUser(ise); 306 } 307 } 308 } 309 310 if (listener != null) { 311 editor.removePropertyChangeListener(listener); 312 } 313 314 dialog.removeWindowListener(this); 315 } 316 } 317 ); 318 319 if (editor != null) { 321 try { 322 oldValue = model.getValue(); 323 } catch (Exception e) { 324 } 327 328 lastValueFromEditor = editor.getValue(); 329 editor.addPropertyChangeListener( 330 listener = new PropertyChangeListener() { 331 332 public void propertyChange(PropertyChangeEvent e) { 333 changed = true; 334 lastValueFromEditor = editor.getValue(); 335 336 if (ExPropertyEditor.PROP_VALUE_VALID.equals(e.getPropertyName())) { 341 if (okButton != null) { 342 if (e.getNewValue() instanceof Boolean ) { 343 Boolean newButtonState = (Boolean ) e.getNewValue(); 344 okButtonState = newButtonState.booleanValue(); 345 346 if (env != null) { 347 env.setState( 348 okButtonState ? PropertyEnv.STATE_VALID : PropertyEnv.STATE_INVALID 349 ); 350 } else { 351 okButton.setEnabled(okButtonState); 352 } 353 354 if (e.getOldValue() instanceof Runnable ) { 355 errorPerformer = (Runnable ) e.getOldValue(); 356 } else { 357 errorPerformer = null; 358 } 359 } 360 } 361 } 362 } 363 } 364 ); 365 366 if (component == null) { 367 throw new NullPointerException (editor.getClass().getName() + " returned null from getCustomEditor()"); 368 } 369 370 component.addPropertyChangeListener( 371 listener = new PropertyChangeListener() { 372 373 public void propertyChange(PropertyChangeEvent e) { 374 if (DialogDescriptor.PROP_HELP_CTX.equals(e.getPropertyName())) { 375 if (dialog instanceof PropertyChangeListener) { 376 ((PropertyChangeListener) dialog).propertyChange(e); 377 } 378 } 379 } 380 } 381 ); 382 } 383 } 384 385 388 private void cancelValue() { 389 if ( 390 (!changed) || (component instanceof EnhancedCustomPropertyEditor) || 391 ((env != null) && (!env.isChangeImmediate())) 392 ) { 393 if ((env != null) && (envStateBeforeDisplay != null)) { 394 env.setState(envStateBeforeDisplay); 395 } 396 397 return; 398 } 399 400 try { 401 model.setValue(oldValue); 402 } catch (Exception e) { 403 } 406 } 407 408 public boolean wasCancelled() { 409 return cancelled; 410 } 411 412 public boolean wasOK() { 413 return ok; 414 } 415 416 public boolean wasReset() { 417 return reset; 418 } 419 420 424 public void actionPerformed(ActionEvent evt) { 425 String label = evt.getActionCommand(); 426 if (label.equals(getString("CTL_Cancel"))) { 427 cancelled = true; cancelValue(); 429 } 430 431 ok = false; 432 reset = false; 433 434 if (label.equals(getString("CTL_Default"))) { 435 reset = true; 436 437 if (prop != null) { 438 try { 439 prop.restoreDefaultValue(); 440 } catch (IllegalAccessException iae) { 441 notifyUser(iae); 442 } catch (java.lang.reflect.InvocationTargetException ite) { 443 notifyUser(ite); 444 } 445 } 446 } 447 448 if (label.equals(getString("CTL_OK"))) { 449 ok = true; 450 451 if ((env != null) && (env.getState() == PropertyEnv.STATE_NEEDS_VALIDATION)) { 452 env.setState(PropertyEnv.STATE_VALID); 453 454 if (env.getState() != PropertyEnv.STATE_VALID) { 455 return; 457 } 458 } 459 460 if (component instanceof EnhancedCustomPropertyEditor) { 461 try { 462 Object newValue = ((EnhancedCustomPropertyEditor) component).getPropertyValue(); 463 model.setValue(newValue); 464 } catch (java.lang.reflect.InvocationTargetException ite) { 465 notifyUser(ite); 466 return; 467 } catch (IllegalStateException ise) { 468 notifyUser(ise); 469 return; 470 } catch (IllegalArgumentException iae) { 471 notifyUser(iae); 472 return; 473 } 474 } else if ((env != null) && (!env.isChangeImmediate())) { 475 try { 476 model.setValue(lastValueFromEditor); 477 } catch (java.lang.reflect.InvocationTargetException ite) { 478 notifyUser(ite); 479 return; 480 } catch (IllegalStateException ise) { 481 notifyUser(ise); 482 return; 483 } 484 } 485 486 if (!okButtonState) { 489 if (errorPerformer != null) { 490 errorPerformer.run(); 491 } 492 493 return; 494 } 495 } 496 497 changed = false; 499 500 if (env != null) { 501 env.removeVetoableChangeListener(this); 502 } 503 504 dialog.dispose(); 505 } 506 507 private static String getString(String key) { 508 return NbBundle.getBundle(PropertyDialogManager.class).getString(key); 509 } 510 511 515 static void doNotNotify(Throwable ex) { 516 doNotNotify = ex; 517 } 518 519 522 static void notify(Throwable ex) { 523 Throwable d = doNotNotify; 524 doNotNotify = null; 525 526 if (d == ex) { 527 return; 528 } 529 530 Exceptions.printStackTrace(ex); 531 } 532 533 541 private static void notifyUser(Exception e) { 542 String userMessage = Exceptions.findLocalizedMessage(e); 543 544 if (userMessage != null) { 545 Exceptions.printStackTrace(e); 546 } else { 547 Logger.getLogger(PropertyDialogManager.class.getName()).log(Level.INFO, null, e); 550 } 551 } 552 553 Component getComponent() { 554 return component; 555 } 556 557 PropertyEditor getEditor() { 558 return editor; 559 } 560 561 } 562 | Popular Tags |