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:
While quick enough to write, the actual message box looks rather ugly:
And it can easily get you in trouble:
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
The code is only slightly more involved:
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:
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.