A "Rich" Alternative for System i GUI Development
Typically a rich client does not have console output. The classes brought over from Java data queue 211 write their output to stdout. They were designed for a Java command line or console application. RCP DtaQ Demo will be modified to eliminate the console output and use the rich client user interface (UI) and log file. When finished the application would look like this:

- No console output
- The messages are written to the View (think subfile).
- The status line is used to alert the user (no alerts yet).
- Errors are written to the log file.
Notice the scroll bars at the bottom and the top. Those are automatically generated, they would disappear is the window were just a little larger.
The status line was used to display messages sent by the model in the initial version of RCP DtaQ Demo for the sake of brevity, to postpone the work described here. Those messages should be displayed in the UI. In this version the message will be moved to the View, replacing the constants "One", "Two" and "Three." Alerts will be displayed in the status line. Errors will be logged. The console output will be removed.
You should continue to develop on the project that you created in Java data queues 301.
The source is in the CVS. The project is info.billblalock.eclipsercp.dtaqdemo2_302. I renamed the project so that this version would remain as it is, and be seperate from the code of the prior and future versions. The completed source code for each step in RCP DtaQ Demo can be accessed by version.
Changes to the View class.
Define an ArrayList, a type of Collection, as a class variable. Think of it as a dynamic array. It will hold the lines that are displayed on the view.
private ArrayList tableArray;
Change the getElements() method to return an array of the contents of the ArrayList instead of a String[] of "One", "Two", "Three".
public Object[] getElements(Object parent) {
// return new String[] { "One", "Two", "Three" };
return tableArray.toArray();
}
Instantiate the ArrayList variable in the constructor and add the value of the data queue key to the list.
/**
* The constructor.
*/
public View() {
plugin = this;
tableArray = new ArrayList();
addTableEntry("The key generated for this client is: " +
IpDtaQKey.getDqKey()); }
Create a method to add an entry to the ArrayList. Think of this object as a dynamically allocated array. The parameter passed to the method will add the String as the next element of the array.
/**
* Add a String to ArrayList to be displayed in View.
* @param entry String to add to ArrayList which is displayed in View.
*/
public void addTableEntry( String entry ) {
tableArray.add( entry );
view.refresh();
}
This method is called by a class that adds an element to the View, passing the method a String of what is to be added to the view. After adding the String to the array that is display, the View is refreshed or reconstructed.
A new classes, Messages:
Every class in the dataqueue package which writes to the console, System.out.print() or Exception.printStackTrace(), has to be changed. We could add methods like setStatusLine() plus a logging method to each class. A lot of cut and paste.
setStatusLine() doesn't use anything from ModelDemoOutputDqListener so it can be moved to someplace that makes it easier to reuse. This is similar to putting a RPG procedure into a separate program or a service program instead of cut and pasting it as a sub-routine or sub-proceedure..
Create Messages class in the dataqueue package.
Messages.java is a convenience class to make it easy to write messages to the status line and log. It is set up so the methods can be accessed statically. For example
Messages.setStatusline("Hello, I am the status line.");
from any class in the project. It is the first new class that has been created for RCP DtaQ Demo, that is why the link.
Move setStatusline() method from ModelDemoOutputDqListener into Messages class and change from private to static public. The message method can be called anywhere by Messages.setStatusline(message). This eliminates cut and pasting the same method into each class which uses it.
The Messages class needs two more methods. One method writes an error message to the status line. The other writes a log entry.
This writes an error status to the status line. An error status will stay on the status line until it is removed by another setErrorStatus().
/**
* Set error status line of RCP with this message.
* @param message String to be placed on status line, set to
* null to clear status message.
*/
public static void setErrorStatusline(final String message) {
Activator.getDefault().getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
View.getDefault().getViewSite().getActionBars()
.getStatusLineManager().setErrorMessage(message);
}
});
}
The RCP wizard generate code to log errors. Right now the program uses it to record its start up data and any fatal errors. Think of it as a job log. This method enables your classes to write to it.
/**
* Write message to log.
* @param severity
* IStatus.OK
* IStatus.INFO
* IStatus.WARNING
* IStatus.ERROR
* IStatus.CANCEL
* @param pluginId Identify plugin or class which wrote the log entry.
* @param message Message to log.
* @param exception Thowable if applicable otherwise null
*/
public static void logEntry(int severity, String pluginId, String message,
Throwable exception) {
Activator.getDefault().getLog().log((IStatus)new Status(severity,
pluginId, 0, message, exception));
}
The About action in the File menu will display the log, at least if anything has been written to it. Press the Configuration Details button. View Error Log button is on the bottom left, it will be grayed out if there are no log entries. The log, if present, will be openned by an OS application you choose, for Windows that would usually be Notepad.

ModelDemoOutputDqListener
Comment out System.out.println() output of the data queue entry read.
Add method to call View.addTableEntry with the message received from the data queue.
/**
* Add this message to the ArrayList which is displayed by the
* View and refresh the TableViewer.
* @param message String to be added to the table in View.
*/
private void addTableEntry(final String message) {
Activator.getDefault().getWorkbench().getDisplay().
asyncExec(new Runnable() {
public void run() {
View.getDefault().addTableEntry(message);
}
});
}
Comment out the line to set the status line with the message read from the data queue and replace it with call to addTableEntry(). The message read from the data queue will now appear in the view and not the status line.
// send output message to status line
// setStatusline( mdloMessage.trim());
// add output message to View
addTableEntry(mdloMessage.trim());
Define a constant to identify this class for the error log.
static final String classId =
"info.billblalock.eclipsercp.dtaqdemo2.dataqueue.ModelDemoOutputDqListener";
In the exception handler replace the stack trace with calls to Messages.logEntry() and setErrorStatusline(). The log will have the trace information and indicate what plugin or class wrote the log entry. The status line indicates to the user that a handled error occurred.
} catch (Exception e) {
// e.printStackTrace();
Messages.logEntry(IStatus.ERROR, classId,
"Error converting DataQueueEntry to model " +
"output dtaq record format", e );
Messages.setErrorStatusline(
"See log -- Error converting DataQueueEntry " +
"to model output dtaq record format");
}
Remove console output from ModelOutputDataQueue
The View class puts the data queue key as the first line of the table it displays. ModelOutputDataQueue no longer needs to write the data queue to the console.
Comment out
// System.out.println("Key used is: " + dqKey);
Remove the console output from the other classes in the dataqueue package. Have some fun and make your own output to the View, Statusline and/or Log.
Replace printStackTrace() with logEntry() and errorStatusline()
The ModelInputDataQueue.java and ModelOutputDataQueue.java classes report errors with printStackTrace() in one method. Modify the reportException() method of these two classes to write a log entry and set the error Statusline. Hint: This is a general reporting method, use e.getMessage() to get the description of the Exception for the log message and status line. Don't forget to add a constant to identify the class for the logEntry().
The method Activator uses both System.out.print() and Exception.printStackTrace(). This class can only write to the log because the UI is not established. In the start() method, where this error reporting is found, the UI has not yet been started. In the end() method the UI is probably closed. Replace this console output with Messages.logEntry().
Get creative.
You can clear the status line or error status line by calling the corresponding method in Messages with a null parameter.
You can write anything you want to the log. It is frequently used for debugging information. To separate your entries set the severity to OK, INFO or WARN.
Posted by Bill Blalock at May 13, 2007 11:00 PM

| Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
Our blogs are editorial content of System iNetwork. We welcome your comments and opinions and encourage lively debate on the issues, and we reserve the right to edit all postings for clarity, length, civility of tone, and appropriateness to the topic under discussion. Comments consisting of product or job solicitations and other spam, profanity, and extreme rudeness will be deleted. We also reserve the right to publish excerpts from the blogs in our e-mail newsletters and print magazine.