1 19 24 package org.openide.explorer.propertysheet; 25 26 import java.util.logging.Level ; 27 import java.util.logging.Logger ; 28 import org.openide.*; 29 import org.openide.nodes.Node.Property; 30 31 import java.awt.*; 32 import java.awt.event.*; 33 34 import java.beans.*; 35 36 import java.util.EventObject ; 37 38 import javax.swing.*; 39 import javax.swing.event.*; 40 import javax.swing.table.*; 41 42 43 46 final class SheetCellEditor implements TableCellEditor, ActionListener { 47 48 ChangeEvent ce = null; 49 ReusablePropertyEnv reusableEnv; 50 51 52 private javax.swing.event.EventListenerList listenerList = null; 53 private InplaceEditorFactory factory = null; 54 private ButtonPanel buttonPanel = null; 55 InplaceEditor inplaceEditor = null; 56 boolean lastUpdateSuccess = true; 57 58 59 SheetCellEditor(ReusablePropertyEnv env) { 60 reusableEnv = env; 61 } 62 63 void setInplaceEditor(InplaceEditor ie) { 64 if (ie == inplaceEditor) { 65 return; 66 } 67 68 if (PropUtils.isLoggable(SheetCellEditor.class)) { 69 PropUtils.log(SheetCellEditor.class, " SheetCellEditor.setInplaceEditor " + ie); } 71 72 if (ie == null) { 73 if (inplaceEditor != null) { 74 inplaceEditor.clear(); 75 } 76 } else { 77 ie.addActionListener(this); 78 } 79 80 if (inplaceEditor != null) { 81 inplaceEditor.removeActionListener(this); 82 } 83 84 inplaceEditor = ie; 85 } 86 87 PropertyEditor getPropertyEditor() { 88 PropertyEditor result; 89 90 if (inplaceEditor == null) { 91 result = null; 92 } else { 93 result = inplaceEditor.getPropertyEditor(); 94 } 95 96 return result; 97 } 98 99 public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { 100 Component result = null; 101 102 SheetTable stb = (SheetTable) table; 104 lastUpdateSuccess = true; 105 106 Property p = (Property) stb.getSheetModel().getPropertySetModel().getFeatureDescriptor(row); 108 109 result = getEditorComponent( 110 p, this, table.getForeground(), table.getBackground(), table.getSelectionBackground(), 111 table.getSelectionForeground() 112 ); 113 114 if (result instanceof ButtonPanel) { 115 ((ButtonPanel) result).setButtonAction(stb.getCustomEditorAction()); 116 } 117 118 if (result != null) { 119 result.setFont(stb.getFont()); 120 } 121 122 return result; 123 } 124 125 private InplaceEditorFactory factory() { 126 if (factory == null) { 127 factory = new InplaceEditorFactory(true, reusableEnv); 128 } 129 130 return factory; 131 } 132 133 private ButtonPanel buttonPanel() { 134 if (buttonPanel == null) { 135 buttonPanel = new ButtonPanel(); 136 } 137 138 return buttonPanel; 139 } 140 141 public boolean isLastUpdateSuccessful() { 142 return lastUpdateSuccess; 143 } 144 145 public Component getEditorComponent( 146 Property p, ActionListener al, Color foreground, Color background, Color selBg, Color selFg 147 ) { 148 JComponent result = null; 149 InplaceEditor inplace; 150 151 setInplaceEditor(inplace = factory().getInplaceEditor(p, false)); 154 155 PropertyEditor ped = inplaceEditor.getPropertyEditor(); 158 159 if (ped instanceof PropUtils.NoPropertyEditorEditor) { 162 setInplaceEditor(null); 163 164 return null; 165 } 166 167 boolean propRequestsSuppressButton = Boolean.TRUE.equals(p.getValue("suppressCustomEditor")); 169 JComponent realEditor = null; 170 171 if (ped.supportsCustomEditor() && !propRequestsSuppressButton) { 172 realEditor = inplaceEditor.getComponent(); 173 174 ButtonPanel bp = buttonPanel(); 175 176 bp.setInplaceEditor(inplace); 178 179 result = bp; 181 } else { 182 result = inplaceEditor.getComponent(); 183 } 184 185 return result; 186 } 187 188 192 public void actionPerformed(ActionEvent ae) { 193 if (PropUtils.isLoggable(SheetCellEditor.class)) { 194 PropUtils.log(SheetCellEditor.class, "Editor received an action event - " + ae.getActionCommand()); } 196 197 if (!(ae.getSource() instanceof InplaceEditor)) { 198 if (PropUtils.isLoggable(SheetCellEditor.class)) { 199 PropUtils.log( 200 SheetCellEditor.class, 201 " Event came from an unknown object type - assuming a legacy EnhancedPropertyEditor is the cause and updating property" 202 ); } 204 205 if (inplaceEditor != null) { 208 if (PropUtils.isLoggable(SheetCellEditor.class)) { 209 PropUtils.log(SheetCellEditor.class, "WRITING PROPERTY VALUE FROM EDITOR TO PROPERTY"); } 211 212 PropUtils.updateProp(inplaceEditor.getPropertyModel(), inplaceEditor.getPropertyEditor(), ""); } 214 215 cancelCellEditing(); 216 } 217 218 if (ae.getActionCommand() == InplaceEditor.COMMAND_SUCCESS) { 219 stopCellEditing(); 220 } else if (ae.getActionCommand() == InplaceEditor.COMMAND_FAILURE) { 221 if (PropUtils.psCommitOnFocusLoss) { 222 stopCellEditing(); 223 } else { 224 cancelCellEditing(); 225 } 226 } else { 227 return; 228 } 229 } 230 231 protected void fireEditingStopped() { 232 if (PropUtils.isLoggable(SheetCellEditor.class)) { 233 PropUtils.log(SheetCellEditor.class, " SheetCellEditor firing editing stopped to table "); } 235 236 if (listenerList == null) { 237 return; 238 } 239 240 Object [] listeners = listenerList.getListenerList(); 241 242 for (int i = listeners.length - 2; i >= 0; i -= 2) { 243 if (listeners[i] == CellEditorListener.class) { 244 if (ce == null) { 245 ce = new ChangeEvent(this); 246 } 247 248 ((CellEditorListener) listeners[i + 1]).editingStopped(ce); 249 } 250 } 251 } 252 253 protected void fireEditingCancelled() { 254 if (PropUtils.isLoggable(SheetCellEditor.class)) { 255 PropUtils.log(SheetCellEditor.class, " SheetCellEditor firing editing cancelled to table "); } 257 258 if (listenerList == null) { 259 return; 260 } 261 262 Object [] listeners = listenerList.getListenerList(); 263 264 for (int i = listeners.length - 2; i >= 0; i -= 2) { 265 if (listeners[i] == CellEditorListener.class) { 266 if (ce == null) { 267 ce = new ChangeEvent(this); 268 } 269 270 ((CellEditorListener) listeners[i + 1]).editingCanceled(ce); 271 } 272 } 273 } 274 275 276 public InplaceEditor getInplaceEditor() { 277 return inplaceEditor; 278 } 279 280 public void cancelCellEditing() { 281 if (inplaceEditor != null) { 282 try { 283 if (PropUtils.isLoggable(SheetCellEditor.class)) { 284 PropUtils.log(SheetCellEditor.class, " SheetCellEditor.cancelCellEditing ", true); } 286 287 fireEditingCancelled(); 288 } finally { 289 setInplaceEditor(null); 290 } 291 } 292 } 293 294 public Object getCellEditorValue() { 295 if (inplaceEditor != null) { 296 return inplaceEditor.getValue(); 297 } 298 299 return null; 300 } 301 302 public boolean isCellEditable(EventObject anEvent) { 303 return true; 304 } 305 306 public boolean shouldSelectCell(EventObject anEvent) { 307 if (anEvent instanceof MouseEvent) { 308 MouseEvent e = (MouseEvent) anEvent; 309 310 return e.getID() != MouseEvent.MOUSE_DRAGGED; 311 } 312 313 return true; 314 } 315 316 private boolean inStopCellEditing = false; 319 320 public boolean stopCellEditing() { 321 if (PropUtils.isLoggable(SheetCellEditor.class)) { 322 PropUtils.log(SheetCellEditor.class, "SheetCellEditor.StopCellEditing", true); } 324 325 if (inplaceEditor != null && !inStopCellEditing ) { 326 inStopCellEditing = true; 327 try { 328 Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getPermanentFocusOwner(); 329 330 if (!PropUtils.psCommitOnFocusLoss) { 336 if ( 337 (!(c instanceof JTable)) && (!inplaceEditor.isKnownComponent(c)) && 338 (c != inplaceEditor.getComponent()) 339 ) { 340 if (PropUtils.isLoggable(SheetCellEditor.class)) { 341 PropUtils.log(SheetCellEditor.class, "Focused component is unknown - discarding"); } 343 344 return false; 345 } 346 } 347 348 PropertyModel mdl = inplaceEditor.getPropertyModel(); 350 351 try { 352 lastUpdateSuccess = PropUtils.updateProp(inplaceEditor); 353 } catch (NullPointerException npe) { 354 if ((inplaceEditor == null) || (inplaceEditor.getPropertyEditor() == null)) { 355 String propID; 356 357 if (mdl instanceof NodePropertyModel) { 358 propID = ((NodePropertyModel) mdl).getProperty().toString() + " editor class " + 359 ((mdl.getPropertyEditorClass() != null) ? mdl.getPropertyEditorClass().getName() 360 : " unknown editor class") + " "; 361 } else { 362 propID = ""; 363 } 364 365 Logger.getAnonymousLogger().warning( 374 "Property " + propID + "value changed *while* the property sheet was setting its value " + 375 "but before it had been set. This almost always means that the " + 376 "property editor has modified the property's value itself. " + 377 "Property editors should NEVER directly modify properties, it is " + 378 "up to the displayer to decide if/when the property should be " + 379 "updated. This behavior may cause an exception in the " + "future." 380 ); 381 Logger.getAnonymousLogger().log(Level.FINE, null, npe); 382 383 return false; 384 } else { 385 throw npe; 386 } 387 } 388 389 if (PropUtils.isLoggable(SheetCellEditor.class)) { 394 PropUtils.log(SheetCellEditor.class, " SheetCellEditor Firing editing stopped"); } 396 397 fireEditingStopped(); 398 399 tryPostSetAction(mdl); 401 402 } finally { 404 setInplaceEditor(null); 405 inStopCellEditing = false; 406 } 407 408 return true; 409 410 } else { 414 return false; 415 } 416 } 417 418 419 void tryPostSetAction(PropertyModel mdl) { 420 if (mdl instanceof ExPropertyModel) { 421 FeatureDescriptor fd = ((ExPropertyModel) mdl).getFeatureDescriptor(); 422 423 if (fd != null) { 424 Action a = (Action) fd.getValue("postSetAction"); 426 if (a != null) { 427 if (PropUtils.isLoggable(SheetCellEditor.class)) { 428 PropUtils.log(SheetCellEditor.class, " Running post-set action " + a); } 430 431 ActionEvent ae = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, InplaceEditor.COMMAND_SUCCESS); 432 a.actionPerformed(ae); 433 } 434 } 435 } 436 } 437 438 public synchronized void addCellEditorListener(javax.swing.event.CellEditorListener listener) { 439 if (listenerList == null) { 440 listenerList = new javax.swing.event.EventListenerList (); 441 } 442 443 listenerList.add(javax.swing.event.CellEditorListener .class, listener); 444 } 445 446 public synchronized void removeCellEditorListener(javax.swing.event.CellEditorListener listener) { 447 listenerList.remove(CellEditorListener.class, listener); 448 449 if (listenerList.getListenerCount(CellEditorListener.class) == 0) { 454 if (inplaceEditor != null) { 455 inplaceEditor.clear(); 456 } 457 } 458 } 459 } 460 | Popular Tags |