BACKSID
I was recently perusing the Notes 6 forum over at the Lotus Developer Domain, as is my wont, and I came across a post entitled, Database access from another class -. Java Now, normally, I would never post a "complete solution" as I Did With this Thread, But it Pique My Interest. It Took Me A Little Time In Terms of Coding, Experimenting, And Research Java in Domino, SO I Thought i'd Summarise What i Learned In A Wee Article.
Domino & Java
Whilst I've tinkered a fair bit with Java, one thing I do not have much experience of is creating Java agents. The nearest I got to a Java agent "in production" was a simple implementation of part of the Trackback specification. I Did this for fun, butfound no fish No User Interface To Speak of - WHEREAS THIS Little Thing Required A Front-End That Would IT.
The Code & The Problem
The original poster in the thread wanted to invoke a simple GUI from a Java agent, collect input via user this GUI, and then do stuff back in the agent. He was using Java because he had a dependency in his code in the form of the JavaMail API. The Issue He WAS EXPERIENCING Concerned The SEPARA Agent Plus a Simple Awt-based Class In That The Two Wern't Talking to Each Other.
My starting point was to take the code he had, dump it into a dummy database, and get cracking. I called the main agent "DomGUIJavaAgent" and the class it uses for the GUI, "DomGUI". The poster had complained that his code did not work on two fronts. First, his ViewEntryCollection object came up with inconsistent entry counts. that was easily solved, in that his for loop was not properly constructed. The rest of it was harder though ... The problem was that the standard NotesMain method happily instantiated a Database object and all the rest, but could not seem to pass these objects over to the default constructor of the GUI class. This meant a lot of head-scratching for me, although I knew it just had to be related to scope Clearly, the Session and AgentContext classes were key:. if they "died" *, then any objects derived with their help were not going to survive either I pondered this, and tinkered with different ways of somehow creating. "new" AgentContext / session Objects in the GUI CODE : Not good. Eventually, My Sorry Excuse for a Brain Had An Epiphany: We're getting into threads!
* - the Domino Java classes and interfaces are "wrappers" around core C functionality in Notes As such, standard Java garbage collection does not work A good Java coder needs to explicitly "recycle" Document objects and so forth I gather that... The Exceptions To this rule area. for The Sake of Brevity In The Source Code, All Recycle Calls Have Been omitted.
Yup, Threads
I'VE Always Been A Bit Leered Of Thieads, Along with Bit-Signing and Inner Classes, That i Seem to Have A bit of blind spot with (getting better wegh!). Now, as i looked more and more into the Domino Java implementation, I discovered that AgentBase, the base class for all Java agents, is a sub-class of the NotesThread class, which makes sense. So, returning to our code, how about running the second GUI ?. object in its own thread That should work But we still need to keep the "trigger" - the AgentBase object - alive.They key to this is getting one thread to "sleep" until the other one is done So here's my implementation. :
In the constructor for the GUI object, I pass through a reference to the Database object we're playing with. The key thing though, is that the method in the DomGUI class that uses this Database object fires off in its own thread and that the Java agent's NotesMain method waits for it. This waiting is accomplished by making the Java agent thread "sleep" for as long as a public boolean variable, belonging to DomGUI, is set to "false." Whilst the thread is alive DomGUI can happily work WITH THE THINGH DATABASE Object. Only Two Things can change the "isclosed" Variable to "true": overce the relevant button has closed by the user. SplendId.
So, Here's The Agent Code in Full (It's Very BRIEF):
Public class domguijavaagent extends agentbase {
Private AgentContext ac;
Private Database DB;
Private domgui mywin;
Public void notesmain () {
Try {
ac = session.getagentContext ();
DB = ac.getcurrentdatabase ();
MYWIN = New Domgui (DB);
While (! mywin.isclosed) {threeRead.sleep (250);
}
} catch (exception e) {
E.PrintStackTrace ();
}
}
}
And here's a snippet of the action listener method in the DomGUI class which manipulates "isClosed", the crucial public boolean which holds this all together (sendToAll () is a simple demo method, as you'll see in the full source):
Public Void ActionPerformed (ActionEvent E) {
IF (E.getsource () == btnsend) {
Sendtoall ();
Dispose ();
isclosed = true;
}
}
THREADS
If you look at the full source, you'll NOTICE THAT A Method in The Domgui Code (Sendtoall ()) Initialises ITS OWN Thread. This Thread isn't Terminated Until The Whole Window Is Closed.
Summary
I hope this is useful to any beginning Java coders out there like me ... it's the fruit of a fair bit of playing, testing, and actually reading the Domino Designer help .... Hopefully, it will act as a good starting point For Any Domino-Based Java You Need to Write That Requires A UI. I Appreciate That this isn't The Prettiest Gui, But It's Really Just To Show What Can Be Done ... And It's Also R5-Compliant!
My thanks to Joseph Millar of Brightline Technology for making a really useful observation concerning thread termination which I took on board in this code Additional comments from those more experienced than I are more than welcome Attachment (s):.! DomGUIJavaAgent.java (0 KB ) DOMGUI.JAVA (4 KB)