logo

Using Java to Create Rich GUI Interfaces in the Notes Client

This last couple of weeks I've made what I hope to be a brief return to developing for the Notes client. One of the requirements I had was to "add a form" to an existing Notes database, which allowed the user to input a few parameters and do a simple search of a remote SQL database, present the results to the user for their review before letting them import the resulting data in to the Notes database.

It goes without saying that I'd forgotten how to program in the Notes client. Having had such a long absence from Notes I came at it assuming that I could use Java code in the client (maybe you can and I missed something?).

For example, I'd assumed that, by now, I'd be able to write Java code in the Click event of a Button. As you can see below, this isn't an option.

image

I'm sure there's good reasons why we can't (is there?) but it left me a bit stuck. Was LotusScript my only option? I didn't relish the idea of fudging my way through getting LotusScript to do what I needed to do. It's not that I don't think it could. I'm sure it can, but it was a problem that really needed Java as the solution.

Not wanting to learn client development all over again or struggle trying to get LotusScript to do it I opted to write a Java Swing-based interface.

You can see an example below:

image

In the above example the user has clicked the Action button on the view and up popped the interface you can see. After entering some data and clicking a button the results table is populated from the SQL data. Then, when the Import button is pressed the data is saved in Notes -- a new document for each row of the table.

How does it work?

It's quite simple. The View's Action button looks like this:

image

This runs a Java Agent called "Import". Inside this agent the Java code simply creates an instance of a JFrame, adds all the components to it and then displays it. As far as the user's concerned it's just a part of Notes - when in fact it's a "standalone" Java application running inside Notes' JVM.

Powerful

The more I got in to this approach the more powerful I realised it was. Not only because the Java code is all self-contained in an Agent; meaning there are no installers or separate executable files to mange or distribute. But also because the app gets updated at the same time as the database design. Even the icons used in the buttons are stored as Resource files in the Agent itself. It's win win.

And because it's written in pure Java it's uses true OO patterns and a rich GUI. There are endless possibilities and pretty much no limit as to what you can do inside that popup window. I even managed to use a Thread to add and update a progress bar during the import process, which made me feel all geeky going multi-threaded (easier than it may sound!).

It also used a Data Access Layer (DAL) and data-modelling classes to abstract away from the SQL database. I had to do this as it's schema is subject to change. Also, at some point, the system will be moved off of Notes. At that point it will be easier to migrate this pure OO Java-based solution than it would be a Notes one.

It's worth noting that it runs inside the Notes JVM as the current user, meaning there's no need to store or ask for their password.

Gotchas

The one thing I don't like about using these Java windows is there's no way to open them as modal to the Notes client. It's all to easy for them to slip under the Notes client and the user to lose track of where it's gone.

However, they can be made to run (and stay) on top of all other windows, but that's a bit annoying. To do that would involve editing the java.policy file (found in <Notes Folder>\JVM\lib\security) on the user's machine and adding this permission:

permission java.awt.AWTPermission "setWindowAlwaysOnTop";

Then in the code itself you can set the Swing frame to stay on top, like so:

try{
  frame.setAlwaysOnTop(true);
} catch (SecurityException sex){ }

Also, I've I've yet to work out how to limit it to only showing one window at a time. If the windows pops below others and the user presses the View Action button again they end up with two of them. I'd rather it brought the first back in to focus.

The other gotcha I found was that any button click (or other event) handlers in the popup window had no access to the Agent's Session object. That's because the Agent itself has completed running and all the session-based object have been recycled. If you want the Java code to interact with Notes then you need to create a new session.

To do this I wrote the basis of the Agent like this:

public class JavaAgent extends AgentBase {

 private static String databaseServer;
 private static String databasePath;

 public void NotesMain() {
  try {
   Session session = getSession();
   
   //So that later any session/threads can access this database
   databaseServer = session.getCurrentDatabase().getServer();
   databasePath = session.getCurrentDatabase().getFilePath();
   
   //Launch the dialog/form for user input
   //initializeUI();

 } catch(Exception e) {
   e.printStackTrace();
 }
}


 private static void calledFromSwingUIAfterAgentIsDone(){
  try{
   NotesThread.sinitThread();
   Session session = NotesFactory.createSession();

   Database db = session.getDatabase(databaseServer, databasePath);
   Document doc = dc.createDocument();

   //etc

  } catch (Exception e){
   //report error
  } finally {
   NotesThread.stermThread();
  }
 }
}

Note that I stored the database's server name and file path in two Strings that we can refer to later when we create our own Session object and re-open the database.

Summary

All in all it's an approach I'm happy with and it's got the job done. Some of you may think it's crazy overkill but, for me, it was the best (if not only) solution.

If there's any interest I can package up a downloadable example?

Comments

    • avatar
    • ChrisC
    • Fri 18 May 2012 06:06 AM

    Jake,

    Super stuff. Been talking with some of the yellow bubble guys on this VERY subject.

    Bit of a topic within some of the yellow bubble...but you should have a look at RCP development within Notes. Basically you are extending the Eclipse environment to customise things like right click menu options, popups, sidebar, dialogs the whole interface.

    You also have access to the Java / NOI objects and some Notes Java UI objects.

    Allows you to customise Notes, Designer, Symphony, Sametime...

    Some great UI building tools (see Bob Balfe - SWT drag and drop stuff). OpenNTF has loads of examples.

    Pig to setup (but mikkel heisterberg has great docs on it). Threading is also a thing to watch (UI and "back end" operations) - again there are classes that make it easier for you.

    The whole Java / Eclipse / XPages stuff is great (you knew I was going to start going there!).

    The great thing is its Eclipse so it can "stand alone" or integrate with the client / designer etc - giving you a load of options. Also the plugin architecture means that from an "admin perspective" deployment can be done centrally to your clients - just requires a re-boot. Properties can also be pushed out to your app centrally.. (whcih can be reset / managed / overridden in your client properties box)

    Anyway .... waffling. If you get a project that would benefit this I am sure you would produce some great stuff.

    Looks like a very useful tool as it stands!

      • avatar
      • Jake Howlett
      • Fri 18 May 2012 06:16 AM

      Hi Chris,

      Interesting. I might look in to RCP development as I would really like something more integrated in Notes - to avoid the issue I mentioned where the window could get lost under the others.

      However, I quite like how my approach means there's no install needed whatsoever and it feels to the user like a natural part of the database itself.

      Glad you mentioned SWT. I forgot to mention that I'd originally designed the interface shown above using the drag-n-drop after installing the SWT tools in pure Eclipse

      https://developers.google.com/web-toolkit/tools/gwtdesigner/index

      All very cool stuff.

      Show the rest of this thread

      • avatar
      • Jake Howlett
      • Fri 18 May 2012 06:18 AM

      Did a quick Google to see what RCP was. For any others curious, see here: http://www.eclipse.org/articles/Article-RCP-1/tutorial1.html

    • avatar
    • ChrisC
    • Fri 18 May 2012 06:45 AM

    Jake,

    Have a look at Bob Balfes blog and also Mikkel Heisterberg. Some great stuff there.

    Domino Designer wiki also has some downloadable examples that you pull into eclipse and play with (as well as documentation on the whole shebang).

    Eclipse RCP Redwiki (or something similar) its called.

      • avatar
      • ChrisC
      • Fri 18 May 2012 06:47 AM

      Also...vogella...

      http://www.vogella.com/eclipse.html

      Brilliant articles there on the RCP / SWT side

      You being an android guy will like that stuff there as well!

    • avatar
    • Brian Miller
    • Fri 18 May 2012 08:04 AM

    One clever way to deal with java permissions is to have a snippet of LostusScript (which isn't subject to java security policy) that finds and edits the java policy file. You generally have to restart the client for it to take effect, but it's an option.

    As for multiple windows, I know there's a way that you can put a reference to your original JFrame somewhere global, which then allows you to check whether it exists already before creating a new one. If it's there, you can just order it to go to the front of the screen.

      • avatar
      • Jake Howlett
      • Fri 18 May 2012 08:12 AM

      Hi Brian,

      Put the JFrame reference somewhere global? Inside the Agent's code you mean? It is already is global. But, as I understand it, when the user clicks the Action button again the Agent is running afresh and knows nothing of the objects created last time it ran. Is that not so?

    • avatar
    • Jasper
    • Fri 18 May 2012 12:00 PM

    It is possible to find the window that you have opened: http://stackoverflow.com/questions/9276871/share-a-gui-jframe-between-agent-calls

    "You can use Window class and iterate through all created instances"

    "public static Window[] getWindows() and"

    "public static Frame[] getFrames()"

      • avatar
      • Jake Howlett
      • Fri 18 May 2012 02:08 PM

      Brilliant. Thanks Jasper. I hadn't gotten as far as googling for the answer yet. I invoked the lazy Web instead :)

  1. It seems I am not the only one who is still being asked about (rich) client development simply based on the fact that companies still run a lot of those applications and many of them are mission critical.

    Unfortunately IBM's pockets in this area are quite empty but I do like your approach. Thank you for sharing.

  2. Welcome back Champ, great stuff!

    If you follow Mickels set of posts you should be able to follow how to implement this as a side bar plug-in which means it's always available to the user, and is pure java, with the added benefits of Notes Classes, session integration, modality, etc...

    Thanks, cool post!

    • avatar
    • Sam
    • Mon 21 May 2012 12:22 PM

    Please post a downloadable example.

  3. It would be very nice if you post your downloadable example. It would be nice starter for my new project :-)

    • avatar
    • ursus
    • Wed 23 May 2012 10:43 AM

    Just a quick question Jake, how did you get around the annoying wait that users get the FIRST time the click on your agent? We have written quite a bit of code in Java to add functionality that is missing in Notes - what bugs me (not the users funnily enough :o) is when they press the action button the need to wait for the JVM to start. Have you found a way around this (e.g. start the JVM in the background when Notes starts)?

      • avatar
      • Jake Howlett
      • Thu 24 May 2012 03:42 AM

      Aha. I wondered why it took longer first time ;-)

      It's not got as far as the user using it yet. Hoping they won't mind the wait. Doesn't seem unreasonably long to me.

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Fri 18 May 2012

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

More Content