Sometimes we need to display an error message to the user to let them know that something went wrong. Our first instinct in these cases is often to reach for a simple Swing message box:

Showing a Swing message box

While quick enough to write, the actual message box looks rather ugly:

Swing message box in action

And it can easily get you in trouble:

AWT events are not allowed inside write action

The reason for the above exception is that a message box is a modal dialog. Opening a modal dialog starts a nested event loop and processes AWT/Swing events until showMessageDialog() returns. If you are currently in a write action then the action cannot finish until the user closes the dialog. This may end up taking a long time if the user goes to fetch a coffee and discuss the error with their coworkers before clicking that ‘OK’ button. In the meantime, any IDE background work would be blocked. Therefore calling modal dialogs from a write action is disallowed for a good reason.

While this could be remedied using SwingUtilities.invokeLater(), a much better alternative is to use IDEA platform notifications.

The code is only slightly more involved:

Showing an IDEA notification

First, we get the current project, but unlike in the linked post this time we need the IDEA project, not the MPS one, so we use the CommonDataKeys.PROJECT data key.

Then, we send the notification using the IDEA Notifications.Bus#notify API. One additional piece of information we specify is the notification group, "MPS Notifications Example". This lets users customize how the notification is displayed. The default is to display the notification as a balloon:

The notification balloon

Overall, notifications have many advantages over simple message boxes:

  • Nicer appearance.
  • No more “AWT events not allowed” error.
  • The error you show is automatically logged in the MPS/IDEA Event Log window.
  • Using the notifications API it is possible to further customize the notification balloon: use HTML in the message text, include action links to fix the error or provide more information.
  • Users can customize how the notification is displayed, either hiding it or making it stick until dismissed.

There is one difference you need to be aware of: unlike the message boxes, notifications are asynchronous. Any code that runs after the call to notify may run before the notification gets displayed.