public abstract class TransactionGuard
extends java.lang.Object
SwingUtilities.invokeLater(java.lang.Runnable)
or analogs while a dialog is shown.
See more details in ModalityState
documentation.
Write actions that modify model are only allowed inside write-safe contexts. These are:
Application.invokeLater(Runnable, ModalityState)
calls with a modality state that's either non-modal
or was started inside a write-safe contextinvokeLater
, action update, renderers etc.
Even if user activity happens in such context
(e.g. someone clicks a button in a dialog shown from SwingUtilities.invokeLater(Runnable)
),
this will result in an exception.
If you've got "Model changes are allowed from write-safe contexts only"
or "Cannot run synchronous submitTransactionAndWait" exception, then
you're likely inside a Swing's "invokeLater" or "invokeAndWait"-like call.
PsiDocumentManager.performLaterWhenAllCommitted(Runnable)
.
You can also try to get rid of them at all, by making your code work only with VFS and PSI and assuming
they're refreshed/committed often enough by some other code.
If you still have "invokeAndWaitIfNeeded" call with model-changing activity inside, replace it with Application.invokeAndWait(java.lang.Runnable, com.intellij.openapi.application.ModalityState)
.
You might still get assertions after that, that would mean that some caller down the stack is also using "invokeLater"-like call and needs to be fixed as well.
If you still absolutely need "invokeLater", use Application.invokeLater(java.lang.Runnable)
or GuiUtils.invokeLaterIfNeeded(java.lang.Runnable, com.intellij.openapi.application.ModalityState)
),
and pass a modality state that appeared in a write-safe context (e.g. a background progress started in an action).
Most likely ModalityState.defaultModalityState()
will do.
Don't forget to check inside the "later" runnable that it's still actual, that the model haven't been changed by someone else since its scheduling.
ModalityState
Constructor and Description |
---|
TransactionGuard() |
Modifier and Type | Method and Description |
---|---|
abstract void |
assertWriteSafeContext(ModalityState modality)
Logs an error if the given modality state was created in a write-unsafe context.
|
abstract TransactionId |
getContextTransaction()
Deprecated.
replace with
ModalityState.defaultModalityState() and use the result for "invokeLater" when replacing "submitTransaction" calls. |
static TransactionGuard |
getInstance() |
abstract boolean |
isWriteSafeModality(ModalityState state)
Checks whether a given modality is write-safe.
|
abstract boolean |
isWritingAllowed()
Checks whether the current state allows for writing the model.
|
static void |
submitTransaction(Disposable parentDisposable,
java.lang.Runnable transaction)
Deprecated.
in a definitely write-safe context, just replace this call with
transaction contents.
Otherwise, replace with Application.invokeLater(java.lang.Runnable) and take care that the default or explicitly passed modality state is write-safe.
When in doubt, use ModalityState.NON_MODAL . |
abstract void |
submitTransaction(Disposable parentDisposable,
TransactionId expectedContext,
java.lang.Runnable transaction)
Deprecated.
|
abstract void |
submitTransactionAndWait(java.lang.Runnable transaction)
Deprecated.
if called on Swing thread, just replace this call with
transaction contents.
Otherwise, replace with Application.invokeAndWait(java.lang.Runnable, com.intellij.openapi.application.ModalityState) and take care that the default or explicitly passed modality state is write-safe.
When in doubt, use ModalityState.NON_MODAL . |
abstract void |
submitTransactionLater(Disposable parentDisposable,
java.lang.Runnable transaction)
Deprecated.
Replace with
Application.invokeLater(java.lang.Runnable) and take care that the default or explicitly passed modality state is write-safe.
When in doubt, use ModalityState.NON_MODAL . |
public static TransactionGuard getInstance()
@Deprecated public static void submitTransaction(Disposable parentDisposable, java.lang.Runnable transaction)
transaction
contents.
Otherwise, replace with Application.invokeLater(java.lang.Runnable)
and take care that the default or explicitly passed modality state is write-safe.
When in doubt, use ModalityState.NON_MODAL
.public abstract void assertWriteSafeContext(ModalityState modality)
Application.invokeLater(Runnable, ModalityState)
and similar calls will be guaranteed to also run in a write-safe context.
ModalityState.NON_MODAL
is always write-safe, ModalityState.any()
is always write-unsafe.public abstract boolean isWritingAllowed()
true
is current context is write-safe, false
otherwisepublic abstract boolean isWriteSafeModality(ModalityState state)
state
- modality to checktrue
if a given modality is write-safe, false
otherwise@Deprecated public abstract void submitTransactionLater(Disposable parentDisposable, java.lang.Runnable transaction)
Application.invokeLater(java.lang.Runnable)
and take care that the default or explicitly passed modality state is write-safe.
When in doubt, use ModalityState.NON_MODAL
.@Deprecated public abstract void submitTransactionAndWait(java.lang.Runnable transaction) throws ProcessCanceledException
transaction
contents.
Otherwise, replace with Application.invokeAndWait(java.lang.Runnable, com.intellij.openapi.application.ModalityState)
and take care that the default or explicitly passed modality state is write-safe.
When in doubt, use ModalityState.NON_MODAL
.ProcessCanceledException
@Deprecated public abstract void submitTransaction(Disposable parentDisposable, TransactionId expectedContext, java.lang.Runnable transaction)
submitTransaction(Disposable, Runnable)
.@Deprecated public abstract TransactionId getContextTransaction()
ModalityState.defaultModalityState()
and use the result for "invokeLater" when replacing "submitTransaction" calls.