KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > openide > explorer > propertysheet > EditablePropertyDisplayer


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 /*
20  * EditablePropertyDisplayer.java
21  *
22  * Created on 18 October 2003, 19:06
23  */

24 package org.openide.explorer.propertysheet;
25
26 import org.openide.nodes.Node.Property;
27 import org.openide.util.NbBundle;
28
29 import java.awt.EventQueue JavaDoc;
30 import java.awt.event.ActionEvent JavaDoc;
31 import java.awt.event.ActionListener JavaDoc;
32 import java.awt.event.FocusListener JavaDoc;
33 import java.awt.event.KeyEvent JavaDoc;
34
35 import java.beans.FeatureDescriptor JavaDoc;
36 import java.beans.PropertyChangeEvent JavaDoc;
37 import java.beans.PropertyChangeListener JavaDoc;
38 import java.beans.PropertyEditor JavaDoc;
39 import java.beans.PropertyVetoException JavaDoc;
40 import java.beans.VetoableChangeListener JavaDoc;
41
42 import java.text.MessageFormat JavaDoc;
43
44 import java.util.EventObject JavaDoc;
45 import java.util.logging.Level JavaDoc;
46 import java.util.logging.Logger JavaDoc;
47
48 import javax.swing.Action JavaDoc;
49 import javax.swing.ActionMap JavaDoc;
50 import javax.swing.InputMap JavaDoc;
51 import javax.swing.JButton JavaDoc;
52 import javax.swing.JComboBox JavaDoc;
53 import javax.swing.JRootPane JavaDoc;
54 import javax.swing.KeyStroke JavaDoc;
55 import javax.swing.event.ChangeEvent JavaDoc;
56 import javax.swing.event.ChangeListener JavaDoc;
57 import javax.swing.event.EventListenerList JavaDoc;
58 import javax.swing.text.JTextComponent JavaDoc;
59 import org.netbeans.modules.openide.explorer.UIException;
60
61
62 /** Extends EditorPropertyDisplayer to implement editor logic, listening for
63  * changes, updating properties, etc.
64  *
65  * @author Tim Boudreau
66  */

67 class EditablePropertyDisplayer extends EditorPropertyDisplayer implements PropertyDisplayer_Editable {
68     private static final Object JavaDoc NO_VALUE = new Object JavaDoc();
69     private int updatePolicy = UPDATE_ON_CONFIRMATION;
70     private String JavaDoc actionCommand = "enterPressed"; //NOI18N
71
private EnvListener envListener = null;
72     private javax.swing.event.EventListenerList JavaDoc listenerList = null;
73     private int actionListenerCount = 0;
74     private InplaceEditorListener ieListener = null;
75     private Object JavaDoc cachedInitialValue = NO_VALUE;
76     private Action JavaDoc customEditorAction = null;
77     boolean customEditorIsOpening = false;
78     private PropertyEditor JavaDoc editor = null;
79     private PropertyEnv attachedEnv = null;
80     private Object JavaDoc lastKnownState = null;
81
82     //Some property panel specific, package private hacks
83
private PropertyChangeListener JavaDoc remoteEnvListener = null;
84     private VetoableChangeListener JavaDoc remotevEnvListener = null;
85
86     /** Creates a new instance of EditablePropertyDisplayer */
87     public EditablePropertyDisplayer(Property p) {
88         super(p, null);
89     }
90
91     EditablePropertyDisplayer(Property p, PropertyModel mdl) {
92         super(p, mdl);
93     }
94
95     public void setEnabled(boolean b) {
96         super.setEnabled(b);
97
98         if (customEditorAction != null) {
99             customEditorAction.setEnabled(b);
100         }
101     }
102
103     public boolean commit() throws IllegalArgumentException JavaDoc {
104         boolean result;
105
106         try {
107             result = _commit();
108         } catch (IllegalArgumentException JavaDoc iae) {
109             result = false;
110
111             if (getUpdatePolicy() != UPDATE_ON_EXPLICIT_REQUEST) {
112                 PropertyDialogManager.notify(iae);
113             } else {
114                 throw iae;
115             }
116         }
117
118         return result;
119     }
120
121     private boolean _commit() throws IllegalArgumentException JavaDoc {
122         // System.err.println("Commit on " + getProperty().getDisplayName() + " value will be " + getInplaceEditor().getValue());
123

124         //Hold the reference and don't call getInplaceEditor() again during this
125
//method - it can trigger a vetoable property change from the property
126
//env which would trigger prematurely replacing the inner component
127
InplaceEditor ine = getInplaceEditor();
128
129         PropertyEditor JavaDoc editor = (ine == null) ? PropUtils.getPropertyEditor(getProperty()) : ine.getPropertyEditor();
130
131         //Cache the state of the property env
132
PropertyEnv env = getPropertyEnv();
133
134         //A temporary instance of PropertyEnv we'll attach to check for state
135
//changes without triggering internal component changes
136
PropertyEnv tempEnv = null;
137
138         if (env != null) {
139             //we want to ignore any events here
140
tempEnv = new PropertyEnv();
141             detachFromEnv(env);
142
143             //Must set the feature descriptor, and it must be the real underlying
144
//feature descriptor in case the property editor will cast the
145
//result of env.getFeatureDescriptor()
146
tempEnv.setFeatureDescriptor(findFeatureDescriptor(this));
147
148             if (editor instanceof ExPropertyEditor) {
149                 //Make sure the editor will not talk to our property env
150
((ExPropertyEditor) editor).attachEnv(tempEnv);
151             }
152         }
153
154         //our result variable
155
boolean success = false;
156
157         // System.err.println("UPDATING THE PROPERTY EDITOR for " + getProperty().getDisplayName() + " to " + getEnteredValue());
158
try {
159             //First, try to put what the user has entered into the property
160
//editor. updatePropertyEditor will try setAsText if the value
161
//object is a string, and setValue if it is not
162
Object JavaDoc result = PropUtils.updatePropertyEditor(getPropertyEditor(), getEnteredValue());
163
164             if (
165                 (result == null) && editor instanceof ExPropertyEditor &&
166                     PropertyEnv.STATE_NEEDS_VALIDATION.equals(tempEnv.getState())
167             ) {
168                 //Give other listeners on the propertyenv a chance to veto the
169
//change
170
String JavaDoc msg = tempEnv.silentlySetState(env.STATE_VALID, getEnteredValue());
171
172                 //something vetoed the change
173
if ((msg != null) && !PropertyEnv.STATE_VALID.equals(env.getState())) {
174                     IllegalArgumentException JavaDoc exc = new IllegalArgumentException JavaDoc("Error setting value"); //NOI18N
175
UIException.annotateUser(exc, msg, null, null, null);
176                     throw exc;
177                 }
178             }
179
180             // System.err.println(" Really updating the property " + getProperty().getDisplayName() + " to " + editor.getValue());
181
//If the result is non null, it as an exception thrown in setAsText.
182
//Now try to write the value into the property. The result will be
183
//Boolean.TRUE if it is updated, Boolean.FALSE if the value was the
184
//same as the property value, or an exception that was thrown.
185
if (result == null) {
186                 result = PropUtils.noDlgUpdateProp(ine.getPropertyModel(), editor);
187             }
188
189             // System.err.println(" result is " + result);
190
//Process the exception, if any
191
if (result instanceof Exception JavaDoc) {
192                 //Okay, something went wrong
193
Exception JavaDoc e = (Exception JavaDoc) result;
194
195                 //We will return it if it's an IAE, or wrap it in one
196
IllegalArgumentException JavaDoc iae;
197
198                 if (e instanceof IllegalArgumentException JavaDoc) {
199                     iae = (IllegalArgumentException JavaDoc) e;
200                 } else {
201                     //Wrap it in an iae and use the localized message from the
202
//real exception
203
String JavaDoc msg = PropUtils.findLocalizedMessage(e, getEnteredValue(), getProperty().getDisplayName());
204
205                     iae = new IllegalArgumentException JavaDoc(msg);
206                     UIException.annotateUser(iae,
207                                              "Cannot set value to " +
208                                              getEnteredValue(), msg, e, null); //NOI18N
209

210                     /* if (e instanceof InvocationTargetException || e instanceof IllegalAccessException) {
211                                             ErrorManager.getDefault().notify(e);
212                                         }
213                      */

214                     throw iae;
215                 }
216
217                 try {
218                     //restore a good value so the env will have the correct state
219
editor.setValue(getProperty().getValue());
220                 } catch (Exception JavaDoc ex) {
221                     //do nothing
222
}
223
224                 throw iae;
225             }
226
227             success = Boolean.TRUE.equals(result);
228
229             if (success) {
230                 fireStateChanged();
231             } else {
232                 InplaceEditor ed = getInplaceEditor();
233
234                 //#43980 - if change causes the component to be synchronously
235
//hidden, we may have disposed our state before we get here.
236
if (ed != null) {
237                     getInplaceEditor().reset();
238                 }
239             }
240
241             return success;
242         } finally {
243
244             if ((env != null) && (editor != null)) {
245                 attachToEnv(env);
246
247                 if (editor instanceof ExPropertyEditor) {
248                     ((ExPropertyEditor) editor).attachEnv(env);
249                 }
250             }
251         }
252     }
253
254     public Object JavaDoc getEnteredValue() {
255         Object JavaDoc result;
256
257         if (getInplaceEditor() != null) {
258             result = getInplaceEditor().getValue();
259         } else {
260             if (cachedInitialValue != NO_VALUE) {
261                 result = cachedInitialValue;
262             } else {
263                 PropertyEditor JavaDoc ed = PropUtils.getPropertyEditor(getProperty());
264
265                 try {
266                     result = ed.getAsText();
267                 } catch (ProxyNode.DifferentValuesException dve) {
268                     result = null;
269                 }
270             }
271         }
272
273         return result;
274     }
275
276     PropertyEditor JavaDoc getPropertyEditor() { //package private for unit tests
277

278         PropertyEditor JavaDoc result;
279
280         if (editor != null) {
281             return editor;
282         }
283
284         if (getInplaceEditor() != null) {
285             result = getInplaceEditor().getPropertyEditor();
286         } else {
287             result = PropUtils.getPropertyEditor(getProperty());
288         }
289
290         editor = result;
291
292         return result;
293     }
294
295     public String JavaDoc isModifiedValueLegal() {
296         //Fetch the editor - we don't want any events triggered (none should
297
//be) to rip it out from under us
298
PropertyEditor JavaDoc editor = getPropertyEditor();
299
300         //A new property env we'll create and use for checking the state
301
PropertyEnv env = null;
302
303         //Get the new value we'll test
304
Object JavaDoc newValue = getEnteredValue();
305
306         //Get the current property env we're using to test things
307
PropertyEnv myEnv = getPropertyEnv();
308
309         //To hold the exception that might be thrown
310
Exception JavaDoc exception = null;
311
312         //To hold the env state, for comparing with the state when the value
313
//is the one really held by the property
314
Object JavaDoc envState = null;
315
316         if ((myEnv != null) && PropertyEnv.STATE_NEEDS_VALIDATION.equals(myEnv.getState())) {
317             String JavaDoc msg = myEnv.silentlySetState(myEnv.STATE_VALID, newValue);
318
319             //something vetoed the change
320
if ((msg != null) && !PropertyEnv.STATE_VALID.equals(myEnv.getState())) {
321                 return msg;
322             }
323         }
324
325         try {
326             //If it's an ExPropertyEditor, we also want to see if the env state
327
//will be STATE_VALID, so create an env and attach it
328
if (editor instanceof ExPropertyEditor) {
329                 if (myEnv != null) {
330                     detachFromEnv(myEnv);
331                 }
332
333                 env = new PropertyEnv();
334                 env.setFeatureDescriptor(findFeatureDescriptor(this));
335                 ((ExPropertyEditor) editor).attachEnv(env);
336             }
337
338             //Put the entered value into the property editor, and fetch the
339
//exception thrown, if any
340
exception = PropUtils.updatePropertyEditor(editor, newValue);
341
342             //check the state
343
envState = (env == null) ? null : env.getState();
344         } finally {
345             //Reattach the env we're listening on
346
if (editor instanceof ExPropertyEditor && (myEnv != null)) {
347                 //put things back the way they were
348
try {
349                     editor.setValue(getProperty().getValue());
350                 } catch (Exception JavaDoc e) {
351                     //well, we can't solve everything
352
Logger.getLogger(EditablePropertyDisplayer.class.getName()).log(Level.WARNING, null, e);
353                 }
354
355                 //Now attach the env back to the property editor, so it will
356
//get notified of state changes
357
((ExPropertyEditor) editor).attachEnv(myEnv);
358
359                 //And attach our listeners back to the env
360
attachToEnv(myEnv);
361             }
362         }
363
364         String JavaDoc result = null;
365
366         if (exception != null) {
367             //find the localized exception to return
368
result = PropUtils.findLocalizedMessage(exception, getEnteredValue(), getProperty().getDisplayName());
369         } else if (PropertyEnv.STATE_INVALID.equals(envState)) {
370             //create a generic message if state is invalid but we don't know why
371
result = MessageFormat.format(
372                     NbBundle.getMessage(EditablePropertyDisplayer.class, "FMT_CannotUpdateProperty"),
373                     new Object JavaDoc[] { newValue, getProperty().getDisplayName() }
374                 ); //NOI18N
375
}
376
377         return result;
378     }
379
380     public boolean isValueModified() {
381         boolean result = false;
382         PropertyEditor JavaDoc peditor = getPropertyEditor();
383
384         Object JavaDoc enteredValue = getEnteredValue();
385         Object JavaDoc realValue = null;
386
387         //Get the value from the editor to make sure getAsText() does not lie
388
Object JavaDoc editorValue = null;
389
390         try {
391             editorValue = peditor.getValue();
392         } catch (ProxyNode.DifferentValuesException dve) {
393             return false;
394         }
395
396         //some editors provide a single from getTags()
397
//but the value is null by default
398
if ((enteredValue == null) != (editorValue == null)) {
399             return true;
400         }
401
402         if (realValue == null) {
403             //try to check the editor value if the editor does not support
404
//getAsText
405
realValue = editorValue;
406         }
407
408         if ((realValue == null) != (enteredValue == null)) {
409             result = true;
410         } else if (realValue == enteredValue) {
411             result = false;
412         } else if (realValue != null) {
413             result = !realValue.equals(enteredValue);
414         } else {
415             result = false;
416         }
417
418         return result;
419     }
420
421     public void reset() {
422         if (getInplaceEditor() != null) {
423             getInplaceEditor().reset();
424         }
425     }
426
427     public void setEnteredValue(Object JavaDoc o) {
428         if (getInplaceEditor() != null) {
429             getInplaceEditor().setValue(o);
430         } else {
431             storeCachedInitialValue(o);
432         }
433     }
434
435     protected void setPropertyEnv(PropertyEnv env) {
436         if (getPropertyEnv() != null) {
437             detachFromEnv(getPropertyEnv());
438         }
439
440         super.setPropertyEnv(env);
441
442         if (env != null) {
443             env.setChangeImmediate(getUpdatePolicy() != UPDATE_ON_EXPLICIT_REQUEST);
444             attachToEnv(getPropertyEnv());
445         }
446     }
447
448     protected void setInplaceEditor(InplaceEditor ed) {
449         if (getInplaceEditor() != null) {
450             detachFromInplaceEditor(getInplaceEditor());
451         }
452
453         super.setInplaceEditor(ed);
454
455         if ((ed == null) && (getPropertyEnv() != null)) {
456             detachFromEnv(getPropertyEnv());
457         }
458
459         if (getInplaceEditor() != null) {
460             attachToInplaceEditor(getInplaceEditor());
461         }
462     }
463
464     public int getUpdatePolicy() {
465         return updatePolicy;
466     }
467
468     public void setUpdatePolicy(int i) {
469         if ((i != UPDATE_ON_FOCUS_LOST) && (i != UPDATE_ON_EXPLICIT_REQUEST) && (i != UPDATE_ON_CONFIRMATION)) {
470             throw new IllegalArgumentException JavaDoc("Bad update policy: " + i); //NOI18N
471
}
472
473         updatePolicy = i;
474
475         PropertyEnv env = getPropertyEnv();
476
477         if (env != null) {
478             env.setChangeImmediate(i != UPDATE_ON_EXPLICIT_REQUEST);
479         }
480     }
481
482     /** Transmits escape sequence to dialog */
483     private void trySendEscToDialog() {
484         if (isTableUI()) {
485             //let the table decide, don't be preemptive
486
return;
487         }
488
489         // System.err.println("SendEscToDialog");
490
EventObject JavaDoc ev = EventQueue.getCurrentEvent();
491
492         if (ev instanceof KeyEvent JavaDoc && (((KeyEvent JavaDoc) ev).getKeyCode() == KeyEvent.VK_ESCAPE)) {
493             if (ev.getSource() instanceof JComboBox JavaDoc && ((JComboBox JavaDoc) ev.getSource()).isPopupVisible()) {
494                 return;
495             }
496
497             if (
498                 ev.getSource() instanceof JTextComponent JavaDoc &&
499                     ((JTextComponent JavaDoc) ev.getSource()).getParent() instanceof JComboBox JavaDoc &&
500                     ((JComboBox JavaDoc) ((JTextComponent JavaDoc) ev.getSource()).getParent()).isPopupVisible()
501             ) {
502                 return;
503             }
504
505             InputMap JavaDoc imp = getRootPane().getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
506             ActionMap JavaDoc am = getRootPane().getActionMap();
507
508             KeyStroke JavaDoc escape = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false);
509             Object JavaDoc key = imp.get(escape);
510
511             if (key != null) {
512                 Action JavaDoc a = am.get(key);
513
514                 if (a != null) {
515                     if (Boolean.getBoolean("netbeans.proppanel.logDialogActions")) { //NOI18N
516
System.err.println("Action bound to escape key is " + a); //NOI18N
517
}
518
519                     String JavaDoc commandKey = (String JavaDoc) a.getValue(Action.ACTION_COMMAND_KEY);
520
521                     if (commandKey == null) {
522                         commandKey = "cancel"; //NOI18N
523
}
524
525                     a.actionPerformed(new ActionEvent JavaDoc(this, ActionEvent.ACTION_PERFORMED, commandKey)); //NOI18N
526
}
527             }
528         }
529     }
530
531     private void trySendEnterToDialog() {
532         // System.err.println("SendEnterToDialog");
533
EventObject JavaDoc ev = EventQueue.getCurrentEvent();
534
535         if (ev instanceof KeyEvent JavaDoc && (((KeyEvent JavaDoc) ev).getKeyCode() == KeyEvent.VK_ENTER)) {
536             if (ev.getSource() instanceof JComboBox JavaDoc && ((JComboBox JavaDoc) ev.getSource()).isPopupVisible()) {
537                 return;
538             }
539
540             if (
541                 ev.getSource() instanceof JTextComponent JavaDoc &&
542                     ((JTextComponent JavaDoc) ev.getSource()).getParent() instanceof JComboBox JavaDoc &&
543                     ((JComboBox JavaDoc) ((JTextComponent JavaDoc) ev.getSource()).getParent()).isPopupVisible()
544             ) {
545                 return;
546             }
547
548             JRootPane JavaDoc jrp = getRootPane();
549
550             if (jrp != null) {
551                 JButton JavaDoc b = jrp.getDefaultButton();
552
553                 if ((b != null) && b.isEnabled()) {
554                     b.doClick();
555                 }
556             }
557         }
558     }
559
560     private void attachToEnv(PropertyEnv env) {
561         if (attachedEnv == env) {
562             return;
563         }
564
565         // System.err.println(" attachToEnv - " + env);
566
env.addVetoableChangeListener(getEnvListener());
567         env.addPropertyChangeListener(getEnvListener());
568         env.setBeans(findBeans(this));
569     }
570
571     private void detachFromEnv(PropertyEnv env) {
572         // System.err.println(" detachFromEnv - " + env);
573
env.removeVetoableChangeListener(getEnvListener());
574         env.addPropertyChangeListener(getEnvListener());
575         env.setBeans(null);
576         attachedEnv = null;
577     }
578
579     private void attachToInplaceEditor(InplaceEditor ed) {
580         Object JavaDoc o = fetchCachedInitialValue();
581
582         if (o != NO_VALUE) {
583             ed.setValue(o);
584         }
585
586         ed.addActionListener(getInplaceEditorListener());
587         ed.getComponent().addFocusListener(getInplaceEditorListener());
588     }
589
590     private void detachFromInplaceEditor(InplaceEditor ed) {
591         ed.removeActionListener(getInplaceEditorListener());
592         ed.getComponent().removeFocusListener(getInplaceEditorListener());
593     }
594
595     private void storeCachedInitialValue(Object JavaDoc o) {
596         cachedInitialValue = o;
597     }
598
599     private Object JavaDoc fetchCachedInitialValue() {
600         Object JavaDoc result = cachedInitialValue;
601         cachedInitialValue = NO_VALUE;
602
603         return result;
604     }
605
606     private InplaceEditorListener getInplaceEditorListener() {
607         if (ieListener == null) {
608             ieListener = new InplaceEditorListener();
609         }
610
611         return ieListener;
612     }
613
614     private EnvListener getEnvListener() {
615         if (envListener == null) {
616             envListener = new EnvListener();
617         }
618
619         return envListener;
620     }
621
622     private boolean hasActionListeners() {
623         return actionListenerCount > 0;
624     }
625
626     /**
627      * Registers ActionListener to receive events.
628      * @param listener The listener to register.
629      */

630     public synchronized void addActionListener(ActionListener JavaDoc listener) {
631         if (listenerList == null) {
632             listenerList = new EventListenerList JavaDoc();
633         }
634
635         listenerList.add(ActionListener JavaDoc.class, listener);
636         actionListenerCount++;
637     }
638
639     /**
640      * Removes ActionListener from the list of listeners.
641      * @param listener The listener to remove.
642      */

643     public synchronized void removeActionListener(ActionListener JavaDoc listener) {
644         listenerList.remove(ActionListener JavaDoc.class, listener);
645         actionListenerCount = Math.max(0, actionListenerCount--);
646     }
647
648     /**
649      * Notifies all registered listeners about the event.
650      *
651      * @param event The event to be fired
652      */

653     private void fireActionPerformed() {
654         if (listenerList == null) {
655             return;
656         }
657
658         ActionEvent JavaDoc event = new ActionEvent JavaDoc(this, ActionEvent.ACTION_PERFORMED, getActionCommand());
659
660         Object JavaDoc[] listeners = listenerList.getListenerList();
661
662         for (int i = listeners.length - 2; i >= 0; i -= 2) {
663             if (listeners[i] == ActionListener JavaDoc.class) {
664                 ((ActionListener JavaDoc) listeners[i + 1]).actionPerformed(event);
665             }
666         }
667     }
668
669     /**
670      * Registers ChangeListener to receive events.
671      * @param listener The listener to register.
672      */

673     public synchronized void addChangeListener(ChangeListener JavaDoc listener) {
674         if (listenerList == null) {
675             listenerList = new EventListenerList JavaDoc();
676         }
677
678         listenerList.add(ChangeListener JavaDoc.class, listener);
679     }
680
681     /**
682      * Removes ChangeListener from the list of listeners.
683      * @param listener The listener to remove.
684      */

685     public synchronized void removeChangeListener(ChangeListener JavaDoc listener) {
686         listenerList.remove(ChangeListener JavaDoc.class, listener);
687     }
688
689     /**
690      * Notifies all registered listeners about the event.
691      *
692      * @param event The event to be fired
693      */

694     private void fireStateChanged() {
695         if (listenerList == null) {
696             return;
697         }
698
699         Object JavaDoc[] listeners = listenerList.getListenerList();
700         ChangeEvent JavaDoc event = new ChangeEvent JavaDoc(this);
701
702         for (int i = listeners.length - 2; i >= 0; i -= 2) {
703             if (listeners[i] == ChangeListener JavaDoc.class) {
704                 ((ChangeListener JavaDoc) listeners[i + 1]).stateChanged(event);
705             }
706         }
707     }
708
709     public String JavaDoc getActionCommand() {
710         return actionCommand;
711     }
712
713     public void setActionCommand(String JavaDoc val) {
714         actionCommand = val;
715     }
716
717     private boolean shouldIgnoreFocusEvents() {
718         return customEditorIsOpening || inReplaceInner;
719     }
720
721     protected void configureButtonPanel(ButtonPanel bp) {
722         bp.setButtonAction(getCustomEditorAction());
723     }
724
725     Action JavaDoc getCustomEditorAction() {
726         if (customEditorAction == null) {
727             PropertyModel mdl = null;
728
729             if (modelRef != null) {
730                 mdl = modelRef.get();
731             }
732
733             customEditorAction = new CustomEditorAction(new Invoker(), mdl);
734
735             getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
736                 KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, KeyEvent.CTRL_DOWN_MASK, false), "invokeCustomEditor"
737             ); //NOI18N
738

739             //XXX this could be done lazily
740
getActionMap().put("invokeCustomEditor", customEditorAction); //NOI18N
741

742             // System.err.println("Installed custom editor action");
743
}
744
745         return customEditorAction;
746     }
747
748     public String JavaDoc toString() {
749         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("Inline editor for property "); //NOI18N
750
sb.append(getProperty().getDisplayName());
751         sb.append(" = "); //NOI18N
752
sb.append(getProperty());
753         sb.append(" inplace editor="); //NOI18N
754
sb.append(getInplaceEditor());
755
756         return sb.toString();
757     }
758
759     void setRemoteEnvListener(PropertyChangeListener JavaDoc l) {
760         remoteEnvListener = l;
761     }
762
763     void setRemoteEnvVetoListener(VetoableChangeListener JavaDoc vl) {
764         remotevEnvListener = vl;
765     }
766
767     public synchronized void dispose() {
768         setPropertyEnv(null);
769         setInplaceEditor(null);
770         remotevEnvListener = null;
771         remoteEnvListener = null;
772         cachedInitialValue = null;
773         editor = null;
774     }
775
776     public ReusablePropertyEnv getReusablePropertyEnv() {
777         return null; //To change body of implemented methods use File | Settings | File Templates.
778
}
779
780     private class InplaceEditorListener implements ActionListener JavaDoc, FocusListener JavaDoc {
781         public void actionPerformed(ActionEvent JavaDoc e) {
782             // System.err.println("\n\nGot action from inplace editor for " + getProperty().getDisplayName() + " - " + e.getActionCommand());
783
//See if it was enter or escape
784
boolean isSuccess = InplaceEditor.COMMAND_SUCCESS.equals(e.getActionCommand()) ||
785                 "comboBoxEdited".equals(e.getActionCommand()); //NOI18N
786

787             //if the value should get updated, do something
788
if (isSuccess) {
789                 if ((getUpdatePolicy() == UPDATE_ON_CONFIRMATION) || (getUpdatePolicy() == UPDATE_ON_FOCUS_LOST)) { //XXX needed by property panel, but breaks API def. Fine while this is not API.
790
commit();
791                 }
792
793                 //JTextField style behavior - fire a change unless there are
794
//action listeners attached
795
if (hasActionListeners()) {
796                     fireActionPerformed();
797                 } else {
798                     //Try to close the dialog, if any on enter - this method
799
//will make sure we're really processing an enter-key event
800
trySendEnterToDialog();
801                 }
802             } else if (!hasActionListeners()) {
803                 //Try to close the dialog, if any, and if we're really processing
804
//an escape key event
805
trySendEscToDialog();
806             }
807         }
808
809         public void focusGained(java.awt.event.FocusEvent JavaDoc e) {
810             if (shouldIgnoreFocusEvents()) {
811                 return;
812             }
813
814             // System.err.println("Focus gained by editor " + e.getComponent());
815
}
816
817         public void focusLost(java.awt.event.FocusEvent JavaDoc e) {
818             //don't let spurious focus changes while replacing the inner component
819
//trigger additional work
820
if (shouldIgnoreFocusEvents()) {
821                 return;
822             }
823
824             if (
825                 !e.isTemporary() && (getUpdatePolicy() == UPDATE_ON_FOCUS_LOST) &&
826                     !getInplaceEditor().isKnownComponent(e.getOppositeComponent()) && isValueModified()
827             ) {
828                 commit();
829             }
830         }
831     }
832
833     private class Invoker implements CustomEditorAction.Invoker {
834         boolean failed = false;
835
836         public boolean allowInvoke() {
837             return true;
838         }
839
840         public void editorClosed() {
841             if (failed) {
842                 requestFocus();
843             }
844
845             customEditorIsOpening = false;
846         }
847
848         public void editorOpened() {
849             customEditorIsOpening = false;
850             repaint();
851         }
852
853         public void editorOpening() {
854             customEditorIsOpening = true;
855         }
856
857         public void failed() {
858             failed = true;
859
860             if (getInplaceEditor() != null) {
861                 getInplaceEditor().reset();
862             }
863         }
864
865         public String JavaDoc getBeanName() {
866             if (modelRef != null) {
867                 PropertyModel pm = (PropertyModel) modelRef.get();
868
869                 if (pm instanceof NodePropertyModel) {
870                     return ((NodePropertyModel) pm).getBeanName();
871                 }
872             }
873
874             if (getProperty() instanceof ModelProperty.DPMWrapper) {
875                 return ((ModelProperty.DPMWrapper) getProperty()).getBeanName();
876             }
877
878             return findFeatureDescriptor(EditablePropertyDisplayer.this).getDisplayName();
879         }
880
881         public java.awt.Component JavaDoc getCursorChangeComponent() {
882             return EditablePropertyDisplayer.this;
883         }
884
885         public Object JavaDoc getPartialValue() {
886             return getEnteredValue();
887         }
888
889         public java.beans.FeatureDescriptor JavaDoc getSelection() {
890             return getProperty();
891         }
892
893         public void valueChanged(PropertyEditor JavaDoc editor) {
894             failed = false;
895
896             try {
897                 // System.err.println("ValueChanged - new value " + editor.getValue());
898
if (getInplaceEditor() != null) {
899                     setEnteredValue(getProperty().getValue());
900                 } else {
901                     //Handle case where our parent PropertyPanel is no longer showing, but
902
//the custom editor we invoked still is. Issue 38004
903
PropertyModel mdl = (modelRef != null) ? modelRef.get() : null;
904
905                     if (mdl != null) {
906                         FeatureDescriptor JavaDoc fd = null;
907
908                         if (mdl instanceof ExPropertyModel) {
909                             fd = ((ExPropertyModel) mdl).getFeatureDescriptor();
910                         }
911
912                         String JavaDoc title = null;
913
914                         if (fd != null) {
915                             title = fd.getDisplayName();
916                         }
917
918                         failed = PropUtils.updateProp(mdl, editor, title); //XXX
919
}
920                 }
921             } catch (Exception JavaDoc e) {
922                 throw (IllegalStateException JavaDoc) new IllegalStateException JavaDoc("Problem setting entered value from custom editor").initCause(e);
923             }
924         }
925
926         public boolean wantAllChanges() {
927             return true;
928         }
929
930         public ReusablePropertyEnv getReusablePropertyEnv() {
931             return EditablePropertyDisplayer.this.getReusablePropertyEnv();
932         }
933     }
934
935     private class EnvListener implements VetoableChangeListener JavaDoc, PropertyChangeListener JavaDoc {
936         private boolean wantNextChange = false;
937
938         public void vetoableChange(PropertyChangeEvent JavaDoc evt)
939         throws PropertyVetoException JavaDoc {
940             // if (evt.getSource() != attachedEnv) {
941
// return;
942
// }
943
// System.err.println("Got vetoable change: " + evt + " oldvalue=" + evt.getOldValue() + " newvalue=" + evt.getNewValue());
944
if (PropertyEnv.PROP_STATE.equals(evt.getPropertyName())) {
945                 wantNextChange = ((evt.getNewValue() != getPropertyEnv().getState()) &&
946                     (getPropertyEnv().getState() != null)) &&
947                     ((evt.getNewValue() != PropertyEnv.STATE_NEEDS_VALIDATION) ||
948                     ((evt.getNewValue() == PropertyEnv.STATE_NEEDS_VALIDATION) &&
949                     (evt.getOldValue() == PropertyEnv.STATE_VALID)));
950             }
951
952             if (!inReplaceInner && (remotevEnvListener != null)) {
953                 remotevEnvListener.vetoableChange(evt);
954             }
955         }
956
957         public void propertyChange(PropertyChangeEvent JavaDoc evt) {
958             if (inReplaceInner) {
959                 // wantNextChange=false;
960
return;
961             }
962
963             if (
964                 wantNextChange ||
965                     ((evt.getNewValue() == PropertyEnv.STATE_VALID) && (evt.getNewValue() != lastKnownState))
966             ) {
967                 wantNextChange = false;
968                 replaceInner();
969                 lastKnownState = ((PropertyEnv) evt.getSource()).getState();
970             }
971
972             if (remoteEnvListener != null) {
973                 remoteEnvListener.propertyChange(evt);
974             }
975         }
976     }
977 }
978
Popular Tags