private volatile long myModificationStamp;
private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this);
- private DocumentListener[] myCachedDocumentListeners;
+ private final Ref<DocumentListener[]> myCachedDocumentListeners = Ref.create(null);
private final List<EditReadOnlyListener> myReadOnlyListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private int myCheckGuardedBlocks = 0;
@Override
public void addDocumentListener(@NotNull DocumentListener listener) {
- myCachedDocumentListeners = null;
+ if (myCachedDocumentListeners != null) {
+ myCachedDocumentListeners.set(null);
+ }
+
LOG.assertTrue(!myDocumentListeners.contains(listener), "Already registered: " + listener);
boolean added = myDocumentListeners.add(listener);
LOG.assertTrue(added, listener);
});
}
+ private static class DocumentListenerDisposable implements Disposable {
+
+ private DocumentListener myListener;
+ private Ref<DocumentListener[]> myCachedDocumentListenersRef;
+ private List<DocumentListener> myDocumentListeners;
+
+ public DocumentListenerDisposable(DocumentListener listener, Ref<DocumentListener[]> cachedDocumentListenersRef, List<DocumentListener> documentListeners) {
+ myListener = listener;
+ myCachedDocumentListenersRef = cachedDocumentListenersRef;
+ myDocumentListeners = documentListeners;
+ }
+
+ @Override
+ public void dispose() {
+ doRemoveDocumentListener(myListener, myCachedDocumentListenersRef, myDocumentListeners);
+ }
+ }
+
@Override
public void removeDocumentListener(@NotNull DocumentListener listener) {
- myCachedDocumentListeners = null;
- boolean success = myDocumentListeners.remove(listener);
+ doRemoveDocumentListener(listener, myCachedDocumentListeners, myDocumentListeners);
+ }
+
+ private static void doRemoveDocumentListener(DocumentListener listener,
+ Ref<DocumentListener[]> cachedDocumentListenersRef,
+ List<DocumentListener> documentListeners) {
+ if (cachedDocumentListenersRef != null) {
+ cachedDocumentListenersRef.set(null);
+ }
+ boolean success = documentListeners.remove(listener);
if (!success) {
- LOG.error("Can't remove document listener (" + listener + "). Registered listeners: " + myDocumentListeners);
+ LOG.error("Can't remove document listener (" + listener + "). Registered cachedDocumentListenersRef: " + documentListeners);
}
}
@NotNull
private DocumentListener[] getCachedListeners() {
- DocumentListener[] cachedListeners = myCachedDocumentListeners;
+ DocumentListener[] cachedListeners = myCachedDocumentListeners.get();
if (cachedListeners == null) {
DocumentListener[] listeners = myDocumentListeners.toArray(new DocumentListener[myDocumentListeners.size()]);
Arrays.sort(listeners, PrioritizedDocumentListener.COMPARATOR);
- myCachedDocumentListeners = cachedListeners = listeners;
+ cachedListeners = listeners;
+ myCachedDocumentListeners.set(cachedListeners);
}
return cachedListeners;