Discovering Notes 8: Showing dialogboxes from SWT in Notes 8


One of the big changes in Notes 8 is the move to a Java threading model which means that showing a messagebox is not something you can *just* do. This has implications for you if you’re developing (or thinking of developing) UI components in Java for Notes 8. These UI components (e.g. sidebar contributions) are developed in SWT and hence follow the SWT way of doing it.

Please note: Although the following may seem (overly) complex nothing of it is new when discussion UI development. The only difference between Notes 7.x and earlier and Notes 8 is that some of these aspects now rears their ugly head.

Now lets get to it…

Since only one thread can access the display and hence draw on the screen at any one time, requests to the display needs to be serialized. In Notes 8 and SWT this is done using the Eclipse Job API. This is done by encapsulating a piece of functionality and asking the platform (the “scheduler”) to execute it. The scheduler adds the job to a queue and and execute it once it is its turn. This may not happen right away though it mostly will.

To display stuff in the UI you use an UIJob instance as shown below. This example simply shows a messagebox with some static content.

new UIJob("Rectangle") {
   public IStatus runInUIThread(IProgressMonitor arg0) {
      MessageDialog.openInformation(
         this.getDisplay().getActiveShell(),
         "HelloWorld", "Hello SWT Job API World");
      return Status.OK_STATUS;
   }
}.schedule();

The second example will show you how to display some Notes data. Since access to the Notes API must be run in a specially initialized thread (remember NotesThread.sinitThread?) you have two options:

  • Manually initialize a thread using NotesThread / extend NotesThread.
  • Take the easy route and use NotesJob.

Using NotesJob is by far the easiest and will handle all the dirty details for you. When you do this you can also use the NotesPlatform class which is an (undocumented) way of getting a lotus.domino.Session instance inside Notes 8.

Using NotesJob will take care of getting at the data – to display it in the UI you still need an UIJob which is why I use two job instances in the example below. Since you can only access final variables from within inner classes I mark the name variable as final.

new NotesJob("Show messagebox") {
   protected IStatus runInNotesThread(IProgressMonitor arg0) throws NotesException {
      Session session = NotesPlatform.getInstance().getSession();
      Name n = session.createName(session.getUserName());
      final String name = n.getAbbreviated();
      new UIJob("My UI job") {
         public IStatus runInUIThread(IProgressMonitor arg0) {
            MessageDialog.openInformation(
               this.getDisplay().getActiveShell(),
               "Username", "Username: " + name);
            return Status.OK_STATUS;
         }
      }.schedule();
      return Status.OK_STATUS;
   }
}.schedule();

I hope this helps you.

2 thoughts on “Discovering Notes 8: Showing dialogboxes from SWT in Notes 8”

  1. This pattern seems decidedly non-OO, given that my inner class can only access final variables, rather than, say, properties of my outer class.  Or is there a way to accomplish that as well?

    When you just want to display a string in a message box, this seems pretty straightforward, but what if I wanted to display a string AND, say, image data from a rich-text field?  Would I have to locally declare my image data in that UIJob?

    As I try to understand this coding technique, I want to make sure I don’t dive right into some Java worst practices.  I know they’re just examples, but the examples you offer look frighteningly unscalable from a code maintenance standpoint.

    Like

  2. Hmm… In my mind it’s actually very much OO since it encapsulates the functionality in a class instance. Let me clarify . You can only access final variables in one inner class from another inner class (that was the point that was missing). You can always access enclosing class members and methods if you like without these being marked final. The following is fine (doWork is a method of the enclosing class):

    new UIJob("UIJob description") {

       public IStatus runInUIThread(IProgressMonitor pm) {

          doWork("HelloWorld");

          return Status.OK_STATUS;

       }

    }.schedule();

    In the following I need to access the data1 variable of the NotesJob anonymous inner class. In order to do this it needs to be final. If not the code will not compile.

    new NotesJob("NotesJob description") {

       protected IStatus runInNotesThread(IProgressMonitor arg0) throws NotesException {

          final String data1 = null;

          new UIJob("Job description") {

             public IStatus runInUIThread(IProgressMonitor pm) {

                String data2 = data1;

                doWork(data2);

                return Status.OK_STATUS;

             }

          }.schedule();

          return Status.OK_STATUS;

       }

    }.schedule();

    I hope that clarifies things.

    Like

Comments are closed.