Monday, March 30, 2009
Are you interested in Agile and UX together...
Friday, March 27, 2009
Domino Unit Framework Q&A - Part 1
Question 1.
"So now my query is i need to get the document context of this..then only i
can test or compare or what ever it is..Can i run the tests of domino unit
frame work independently with out tieing to the Application data base."
Answer 1.
Yes, you can run the unit tests independent of the Domino Unit Framework database.
You will need to copy the Domino Unit Framework Script libraries into your application and build a place where you want to execute the tests (Agents, Action Buttons - Your choice). The results of the tests (pass/failures) are then sent to the domino unit framework database that you specify. You can send the documents to any database but you'll need to see the results.
Set OutputStream = New NotesDatabaseOutputStream(session, "", "DUFResults.nsf")
When you are migrating to production/uat, remove the script libraries and agents.
Question 2.
"Is there a way to test them independently with out tieing to application database is my Question or As per ur inputs is this only the best way to test.(copying)"
Answer 2.
Nope....
It's a bit like trying to compile a java program and not having the jar file on the path....the database is the project, therefore - like jUnit you need to allow the objects that you are testing to be in scope.
Question 3.
"I don't find any assertion for comparing two arrays of type Variant..that is Variant array or list in Domino Unit Framework.Is there any solution for that or do we need to manually write some class for that in the script library."
Answer 3.
Equality of Arrays, especially arrays of variants is particularly tricky - mostly because the rules of equality can vary, and there is a large combination of possible rules that may or may not be relevant in your particular instance. Is order important for equality ? or perhaps number of elements ?
Therefore, asserting equality between arrays (and arrays of variants) is not (and perhaps never will be) included in Domino Unit Framework.
My suggestions is to either write your own custom assertions as you have access to the source code, or unit test at the array element like so;
Call Test101.AssertEqual(array_a(0),array)b(0))
Wednesday, March 25, 2009
Scius PDF library - what is in the next version.
1. Changing the page orientation on the fly,2. Inline images that you can scale,
3. Bullet lists.
The code has been written and I'm using it, but the release is not done. That is, I haven't met my personal 'definition of done', which include examples and documentation.
I've been a bit busy of late and getting it ready has fallen down the backlog.
Dojo Drawing Tools and Charting
Dojo, Now with Drawing Tools.
The article has a fairly detailed explanation of the dojo gfx library and a preview of the charting API.
Monday, March 16, 2009
An introduction to Scrum (plus some interesting case studies)
Abstract.
This guide explains how to use Scrum to build products. In doing so, it will describe how the framework and its artifacts, time-boxes, roles and rules work together. Scrum does not include techniques and processes for building products; however, it will point out the efficacy and flaws of these techniques and processes.
Scrum is a framework for developing complex products and systems. It is grounded in empirical process control theory*. Scrum employs an iterative, incremental approach to optimize predictability and control risk. Within each iteration, Scrum employs self-organizing, cross functional Teams to optimize flexibility and productivity.
Have a look at some of the case studies that were presented at the 2009 Scrum Gathering (in Orlando, FL.). It makes for some interesting reading.
Case Studies:
Scrum But
Scrum Games
Bootstrapping Scrum
Tuesday, March 10, 2009
Agile what is it and should I care ?
I've been learning as much as I can about Agile and, in particular, Scrum. I'm a certified project manager (based on PMBok), so I was interested to understand the implications of managing software projects in an Agile way. Did I need to throw away all I knew about the PMBok. How do you manage the same things that the stakeholders need to know about risks, schedule and budget but in the Agile way.
I am also interested to find out how others tackle software development in the context of the Lotus platform. It doesn't seem to be a topic that is talked about much within our community.
There is a rising ground swell of interest and adoption of Agile software development, which is gaining credibility. Agile is now a widely accepted and valid method for managing software development. IBM Lotus Software Group and the Lotus Notes Development Team are using Agile and the fourth edition of the PMBok guide is being influenced by agile projects.
Should the Lotus community be interested ?
Is Agile (and Scrum) something that, as professional software developers, we should be interested in ? or interested enough to find out more ? We take toolkits and ideas from other technology areas and reuse them for our own purpose, so why not a development method ?
I don't need Agile, I'm using a RAD tool.
Lotus Notes has always been on the agile side of the spectrum and is often referred to a rapid application development (RAD) environment. Of course, just because you are using a RAD tool does not necessarily mean that you are developing software in a RAD way. In the same way that you can still write Java code in a procedural way and shun any form of Object Oriented techniques. I've seen the waterfall, big document up front, approach for Notes development and you end up spending more time on the document than actually writing the software.
For me developing solutions in Notes has been somewhat Agile. I started with Joint Application Design (JAD) and then Accelerate Value Method (AVM). AVM, for those who have not heard of it, was the Lotus consulting methodology from 1995 which embraced a collaborative development style with stakeholders and team. The aim was also to deliver value to the customer at the earliest opportunity through short iterations.
In fact if you did business with Lotus Consulting in Australia you would have come across a project flexibility matrix in our statements of work. I saw the same matrix recently while reading 'The Software Project Managers bridge to Agility'. We even used a documentation formatting methodology that favoured brevity and efficiency in communications.
So why should I care if I'm using Agile or Scrum ?
Simply, it gives you a common language that you can talk to other developers, clients and managers when they ask what is it that you are doing. You can point to a wealth of credible experience online and in books and say, yes we are using a software development methodology. A methodology favoured by highly respected experts, and by the way, they have produced high quality software that the users want quicker. Make no mistake, there are pit falls and traps which you will need to look out for. You will also need to assess if your team and organistion is ready and willing to try Agile.
There are also lot if misconceptions around Agile methods that have the potential to strike fear into managers and the PMO alike. "No documentation", "you'll get it when you get it" and "Agile doesn't scale" are some of the common ones. If you take the time to understand, like I have recently, you will realise that Agile has structure for dealing with the processes and disciplines that the PMBok describe. The PMBok is very general and, as the title describes, and only provides a guide to manage projects from building bridges to software development. Agile fills in the 'how' for software development and so the two can exist happily together.
I really would like to use Agile, how can I explain the benefits between Agile and Waterfall in a simple way ?
I recently attended the Sydney Scrum User Group and we worked through an exercise, which was an analogy for one of the difference between a waterfall approach and a scrum/agile approach. Rather than pinch the idea, here is my contrived story to explain the difference. Think of sandwiches in terms of software features, and a tray as a release or increment, and it might all make sense - then again maybe not.
Scenario 1. Making sandwiches the waterfall way.
Requirements.
Customer sends a fax at 9:00 am in the morning he needs vegemite sandwiches for 100 people for an event at lunch. Deliver to the office at 11:30.
Development.
You get a production line started, one person buttering and spreading the vegemite, the next person slicing and arranging on a platter. By 10:30 you've spread 75 sandwiches with vegemite, when the customer calls in to check on progress.
The customer suddenly remembers that, not everyone likes vegemite. So ask for half to be roast beef. Rather than 25 vegemite sandwiches end up in the bin the client agree to increase his order by 25 sandwiches to get the 50 roast beef sandwiches.
User Acceptance.
You turn up at the customers office, he looks at the platter and it looks a little plain then remembers that he has some vegetarians turning up who don't like vegemite! You quickly call the guys at the cafe and get them to quickly make another 25 sandwiches, this time cucumber.
Sign Off.
The customer is happy, but it cost him 150 sandwiches and you've expended 150 sandwich making effort. There is only 100 people so there is a lot of sandwiches left over that are not used.
Scenario 2. Making sandwiches the agile way.
Requirements.
Sometime later the same customer faxes another order, this time you try a different approach.
You invite him to come to the cafe and tell him he can use the wi-fi and he'll get a coffee on the house while he waits. You sit down with him and ask your usual catering questions. How many people ? are there any vegetarians ? The barista overhears - and suggests that to cater for vegans and wheat intolerance and through your many years of experience you estimate that 75 sandwiches should be enough for 100 people.
Development.
You start making sandwiches one at a time. As each tray of sandwiches is made you show the customer. You have made 50 sandwiches (two trays). When you overhear the customer exclaim - bugger!
He's just got an email. The meeting has been rescheduled until the afternoon. You suggest to him that for an afternoon meeting cakes might be more appropriate and so decide that 50 sandwiches and 25 cakes would be plenty. You stop making any more sandwiches and the and start slicing cake.
User Acceptance
The customer has seen the first tray of sandwiches as they have been made. He quickly checks the cakes as they are being arrange - all is looking good.
Sign Off. The customer is happy and pays. You suggest that he takes one tray of sandwiches to put in the fridge on the off chance that some of the attendees didn't get the rescheduled meeting notice. After all they are already made - he might as well take them.
Let me explain the difference
Scenario 1 - the customer didn't really understand what he wanted until he started thinking more about his needs when he saw the entire finished platter. He ended up with more food than he actually needed and there was a certain amount of waste. The sandwiches were all produced in great big block so there is little flexibility in changing the fillings during the making of the platter.
Scenario 2 - the customer also did not understand what he wanted, but as he was available in the coffee shop he could actively participate and give the sandwich makes feedback as his requirements changed, like when the meeting was rescheduled. There was little to no waste in the construction and as the platter was made in smaller, fully complete, chunks. In fact, so complete that the customer could actually take part of the order with him and realise that value earlier.
Summary.
You can see for the examples that when the customer is involved more closely with the production of the sandwiches that the whole team is more able to quickly adapt to the changing situation. Have smaller, fully complete, increments allowed for the customer to start using the end product quicker. The customer only paid for what he actually needed.
The trade off.
The customer/product owner has to commit to spend time working with the team. If the product owner, the person with ultimate responsibility to steer the results of the software development effort, doesn't have the time or inclination to work in an agile way then waterfall my still be the most appropriate method for your situation.
There is a lot more to agile than one post. Hopefully this post has given you a small insight and taster into Agile. Let me leave you with one last thought.
Image you have two project, one waterfall and one agile. Imagine a time of economic uncertainty. Imagine both projects are canceled half way through. Which project will be able deliver value to the customer in the form of working software.
Answers on a postcard...(or comments)
Tuesday, February 24, 2009
should I or shouldn't I ?
If anyone is wondering what a scam email looks like, here is one.
From Mr Benson Karim
Auditing Manager,
Bank of Africa(B.O.A)
Ouagadougou Burkina Faso.
West Africa.
ATTN,
Sorry to distract your attention, I am Mr Benson Karim the Auditing manager
in the bank of Africa Ouagadougou Burkina Faso West Africa.
In my department, I found the deposited fund amounted ($12.5 MILLION US
DOLLARS) belonging to a customer who died in the air crash with his entire
family.
However, I shall detail you with the full information as soon as I hear from
you.
Can you be able and capable to assist me provide your receiving bank account
where this fund will lodge in your favour?
I shall give you 35% of the total sum as soon as this fund hits your account
and I shall visit you in your country for the shearing of the fund.
Please this is very confidential. If you are interested, please forward to me
the bellow information's;
Your name:............................
Your country:.........................
Your phone Number:......................
Your tel/fax:...........................
Your age:...............................
Your occupation:.......................
Thank for your anticipated co-peration.
Your's Faithfully.
Mr Benson Karim
Friday, February 13, 2009
Web UI Patterns
You should also checkout the 15 Common Component Patterns.
Lots of inspiration, eye candy and general UI tips for the Domino developers out there.
Thursday, January 15, 2009
2008 retrospective
However, next week I'll be mostly reading. I hope that all the LS09 attendees enjoy next week and I'm looking forward to keeping up with all the latest news.
Thursday, December 18, 2008
Vista UI gaffe : Why users delete the recycle bin
why people delete the recycle bin

I would have thought that using "Remove Recycle Bin" or even "Delete Recycle Bin" rather than "Delete" would have been a better option.
I guess that MS didn't pass round the "Don't make me think" book.
Friday, November 28, 2008
Dojo Domino Applications : Performance Tips
In my last dojo app, I only used a few controls and as such performance was 'good enough'. However, it was niggling me that I should look into the dojo custom build system. I'm currently building a new audit and I need to use additional controls. It was enough of a reason for me to take a peek.
The two things that I wanted to find out were;
- How easy is the dojo custom build system ?
- How much difference will this make to the performance ?
The Dojo Build System - Creating your own custom build.
As Tim has already blogged about, using Dojo in its vanilla state means that you will have a whole bunch of seperate HTTP requests - which affects performance. In addition, the files haven't been optimized for downloading quickly. The dojo build system optimise the files by interning, removing whitespace, removing some comments, shortens variable names and rationalising the dojo layers.
I was quite surprised just how easy the build system was to set up and use. Here is what to do.
1. Download the source code files - I used the dojo-release-1.2.2-src.zip
2. You then need to create a profile. This tells the build system what bits of dojo you use. Its pretty much the dojo.requires entries. This is what my scius-profile.js looks like and you need to put this in the util\buildscripts directory.
dependencies = {
layers: [ {
name: "scius-dojo.js",
dependencies: [
"dojo.parser",
"dijit.Dialog",
"dijit.form.Button",
"dijit.form.DateTextBox",
"dijit.form.NumberTextBox",
"dijit.form.CheckBox",
"dijit.ProgressBar",
"dijit.layout.ContentPane",
"dijit.layout.StackContainer"
] },
],
prefixes: [ [ "dijit", "../dijit" ], [ "dojox", "../dojox" ] ] }
3. You then need to run the build script, you can do this from the command line - or from a batch file in the buildscript directory. My scius-build.bat looks like this
build.bat
profile=scius
action=release
profileFile=scius-profile.js
releaseName=scius-dojo-122
optimize=shrinksafe
layerOptimize=shrinksafe
copyTests=false
localeList=en,en-us,en-au
I've chosen to use the dojo version in my release, so that I can keep track of which dojo version it contains (you can also include your own version attributes). I've also decided to use a custom list of locales rather than the default, the audit is only available to Australians, so I wanted to cover most language settings that might be used.
After about 85 seconds, the build system is finished and you then have your own custom build waiting for you in the release directory.
How to use the custom build in your page ?
Now that you have your own compacted build you'll need to use it in your web app. In your pages that use dojo, you will need to update the dojo references to the new build and also include a reference to your custom build js.
I update the head tags to include /dojo/scius-dojo.js as well as the reference to the /dojo/dojo.js. My new script links look like this;
<script type="text/javascript" src="https://website/scius-dojo-122/dojo/dojo.js" djconfig="isDebug: false, parseOnLoad: true"></script>
<script type="text/javascript" src="https://website/scius-dojo-122/dojo/scius-dojo.js"></script>
When the pages loaded, the number of http requests is reduced from 80 to 59 requests and even though the number of Kb increased, this changed the initial load time from 12.98 seconds to 4.21 seconds and the cached time from 6.98 to 2.185.
Where should I store the dojo files ?You may have noticed that the path to the dojo files did not include a database. That's right, I've placed the files directly under the servers data directory. On my linux server that is /local/notesdata/domino/html/scius-dojo-122. Putting commonly used web files under the html directory is a well known performance technique. However, sometimes it's not always possible or desirable. For example, I'm quite happy to put my compacted versions of the standard dojo implementation there as I don't have a lot of applications or dojo variations to manage. I also have easy access. If you want out-and-out performance, that's the way to go.
Can you reduce the number of requests further ?
Maybe not for the original request but for further requests, yes you can. You need to set the expires header. If you follow the teachings of Yahoo, YSlow will give you a report on the files that don't have the expires headers set. Chris Linfoot and Chris Brandlehner have both blogged about setting the expires header for domino applications in more detail.
So exactly how do you do that ? It's a server config thing. You can specify rules for a website where domino will set the expires date. I set mine to cache any of my database theme files, all the scius dojo files and one rogue js file in the design. Just remember, don't set this as a global setting - it's a bad idea.

So now, subsequent page loads are very snappy. Down from 2.1 to under 1 second. You can see for the subsequent load only the html is needed. Everything else has been cached. 515kb to 39k and 59 requests down to 1 request.
Of course, YSlow is still give me rating of F. I still need to move CSS at the top, GZip my files, use a CDN and reduce the initial number of HTTP requests. However, now that the page loads have been reduced, I'm not going to sweat it.;-)
Of course, the last bit is reducing the time taken to download the HTML. If your application generates this dynamically through agents, views or forms, and it's this part that takes a long time, then you might need to consider performance improvements in the Notes application too.
Summary.
Was the custom build system easy to use ?
Yes. It didn't take too long to figure out my profile. Running a batch file and copying a directory doesn't take much effort either. Heck, you could probably automate that whole thing with ANT, including copying the custom build to your server by FTP - if you really wanted to.
How much difference did this make to performance ?
Using a custom build reduced both the initial and cached load time by half, setting the expires date reduced the cached loaded page by half again.
It terms of effort versus gain, it's well worth using the dojo custom build, maybe not for development. Maybe as a last step before promoting your application into your test and production environments.
Additional Notes about the Set up:
The environment I used was my development 8.0 server, running in a bridged VM with 512mb ram. The browser is on the host machine. I've noted in the past that this is slower than the response time I get on my production servers. However, it's a good control environment.
Tuesday, October 21, 2008
Taking the View to PDF example to the next step.
The example agent enclosed improves on the previous version by;
- handling a view with one category or a flat view
- handling a view that has hidden, icon and total detail columns
- adding a header image (from SuperNTF)
- adding a footer with page numbers
Remember, if you have complicated reports or want fine grained control then write directly to iText. I also wanted to demonstrate that the PDF generation side is the easy bit. This means that you can spend more time writing the domino parts and tweeking for your formats than writing the PDF stuff.
The code is attached here and extracts below.
// get the date time for the report
DateTime dt = session.createDateTime("Today");
dt.setNow();
// the generic data object
PdfData data = new PdfData();
// where to put the file
PdfDocumentConfig config = new PdfDocumentConfig("Text",
"ViewByTitle.pdf", "c:\\pdfs");
/*
* Set up some of the styles that
* we will use in the pdf document.
*/
// the style for the database and view title
Style styleViewTitle = new Style("viewTitle", Style.TYPEFACE_HELVETICA,
18);
styleViewTitle.setDecoration(Style.DECORATION_BOLD);
styleViewTitle.setAlign(Style.ALIGN_CENTER);
styleViewTitle.setBackgroundColour(232, 232, 232);
styleViewTitle.setColor(0, 94, 187);
// the style for the date stamp
Style styleDate = new Style("date", Style.TYPEFACE_HELVETICA, 10);
styleDate.setAlign(Style.ALIGN_RIGHT);
styleDate.setBackgroundColour(Color.RED);
// the style for the view column titles
Style styleColumnTitle = new Style("columnsTitle",
Style.TYPEFACE_HELVETICA, 12);
styleColumnTitle.setDecoration(Style.DECORATION_BOLD);
styleColumnTitle.setBackgroundColour(232, 232, 232);
styleColumnTitle.setColor(0, 94, 187);
// the style for the column categories
Style styleColumnCat = new Style("columnsCat", Style.TYPEFACE_HELVETICA,
12);
styleColumnCat.setDecoration(Style.DECORATION_BOLD);
styleColumnCat.setBackgroundColour(247, 247, 247);
styleColumnCat.setColor(255, 153, 0);
// the default style for the view data
Style styleViewDefault = new Style("default", Style.TYPEFACE_HELVETICA,
10);
/*
* set header image - used the image from the superNTF nsf
*/
HeaderImage headerImage = new HeaderImage();
headerImage.addImage("c:\\pdfs\\BrandBanner.gif");
headerImage.setImageScale(HeaderImage.IMAGE_NO_SCALE, false);
// create a header to write the date into
HeaderTwoColumns header = new HeaderTwoColumns(50, 50);
header.setLeftColumn(new CellElement("", styleDate));
header.setRightColumn(new CellElement(dt.getDateOnly(), styleDate));
header.setStyle(styleDate);
header.setHeight(100);
// create a footer
FooterTwoColumns footer = new FooterTwoColumns(50, 50);
footer.setLeftColumn(new CellElement(
"http://palmerweb.blogspot.com - http://www.scius.com.au"));
footer.setRightColumn(new CellElement("", styleDate));
footer.setStyle(styleViewDefault);
footer.setPageNum(new PageNumbersElement(styleDate));
footer.includePageNumbers(true,
FooterTwoColumns.PAGE_NUMBERS_RIGHT);
// getting the notes handles
AgentContext ctx = session.getAgentContext();
Database db = ctx.getCurrentDatabase();
// this is the view
View viewMembers = db.getView("vw-docsbytitle");
// read the columns to get the report headings
Vector cols = viewMembers.getColumns();
// filter out the columns that we are not interested in
// such as icons, hidden, total details and categories
Vector colsToRead = new Vector();
for (int x = 0; x < cols.size(); x++) {
ViewColumn col = (ViewColumn) cols.get(x);
if (col.isIcon() == false && col.isCategory() == false
&& col.isHidden() == false
&& col.isHideDetail() == false) {
colsToRead.add(col);
}
}
// create a table based on the number of columns
TableElement tb = new TableElement(colsToRead.size());
/*
* create the heading (repeating) rows for the table.
*/
// database and view title
RowElement rw = new RowElement();
CellElement title = new CellElement(db.getTitle() + " - "
+ viewMembers.getName() + "\n\n", styleViewTitle);
title.setCellspan((colsToRead.size()));
rw.addCell(title);
rw.setTableHeading(true);
tb.AddRow(rw);
// column headings
rw = new RowElement();
for (int x = 0; x < colsToRead.size(); x++) {
ViewColumn col = (ViewColumn) colsToRead.get(x);
rw
.addCell(new CellElement(col.getTitle() + "\n\n",
styleColumnTitle));
}
rw.setTableHeading(true);
tb.AddRow(rw);
/*
* populate the table with the view data
*/
ViewNavigator viewNav = viewMembers.createViewNav();
ViewEntry rowData = viewNav.getFirst();
while (!(rowData == null)) {
rw = new RowElement();
Vector viewCol = rowData.getColumnValues();
// check to see if this is a category
if (rowData.isCategory()) {
CellElement catCell = new CellElement("\n"
+ viewCol.get(1).toString() + "\n\n", styleColumnCat);
catCell.setCellspan(colsToRead.size());
rw.addCell(catCell);
} else if (rowData.isDocument()) {
for (int x = 0; x < colsToRead.size(); x++) {
ViewColumn col = (ViewColumn) colsToRead.get(x);
int pos = col.getPosition() - 1;
rw.addCell(new CellElement(viewCol.get(pos).toString(),
styleViewDefault));
}
}
tb.AddRow(rw);
rowData = viewNav.getNext(rowData);
}
// add the table to the data object
data.add(tb);
// overide the default layout
LayoutElement layout = new LayoutElement(LayoutElement.PAGESIZE_A4,
LayoutElement.ORIENTATION_LANDSCAPE, 10, 10, 10, 10, 40, 50);
// add the image to the layout
layout.setHeaderImage(headerImage);
layout.setFooter(footer);
layout.setHeader(header);
// configure with the config, data and layout
PdfDocument pdf = new PdfDocument(config, data, layout);
// go
pdf.createDocument();
You should be able to take the agent code and just change the view name and you'll have a nicer looking PDF of your views - providing you like the colours and images. In the course of building this examples I made a few assumptions about the number of categories, and location of hidden columns. You might need to tweek the agent code if your views have more than one category or have totals and hidden columns in different locations. Its not just a drop in and works for every scenario.
What's next ?
I guess a notes document to PDF would be a nice example, so that's what will be in the pipeline. However, impending work commitments mean that it's highly likely that it won't be in the near future.
Monday, October 20, 2008
Notes View to PDF in 60 seconds
Watch the movie to see how to create a pdf of a view in 60 seconds.
I've produced a movie to demonstrate how easy it is to write an agent that creates a pdf of a view using my new library. I chose SuperNTF as it was the first database that had a flat view and a selection of documents. I copied and pasted enough entries to give me two pages so that you can see repeating headers. It's not quite as entertaining as 'Gone in 60 seconds' but does show you how quickly you can implement this in your own databases.
Below is the example code from the movie that simply dumps the content of a designated flat view to a table in a pdf. I've updated the library to Beta 7 to contain a minor enhancement to allow you to specify rows that are designated as headers. These header rows (yes you can specify more than one) are repeated on each page as the content forces a page break. Again, most of the heavy lifting is done by iText.
The Code
// the generic data object
PdfData data = new PdfData();
// where to put the file
PdfDocumentConfig config = new PdfDocumentConfig("Text",
"agent-test.pdf", "c:\\temp");
// getting the notes handles
AgentContext ctx = session.getAgentContext();
Database db = ctx.getCurrentDatabase();
// this is the view
View viewMembers = db.getView(" - insert your view alias here - ");
// get the column names for a header
Vector cols = viewMembers.getColumnNames();
// create a table based on the number of columns
TableElement tb = new TableElement(cols.size());
// start populating with the column names
RowElement rw = new RowElement();
for (int x = 0; x < cols.size(); x++) {
rw.addCell(new CellElement(cols.get(x).toString()));
}
// mark this as a table header to be repeated
rw.setTableHeading(true);
tb.AddRow(rw);
// start populating the table with the view data
ViewNavigator viewNav = viewMembers.createViewNav();
ViewEntry rowData = viewNav.getFirst();
while (!(rowData == null)) {
rw = new RowElement();
Vector viewCol = rowData.getColumnValues();
for (int y = 0; y < viewCol.size(); y++) {
rw.addCell(new CellElement(viewCol.get(y).toString()));
}
tb.AddRow(rw);
rowData = viewNav.getNext(rowData);
}
// add the table to the data object
data.add(tb);
// overide the default layout
LayoutElement layout =
new LayoutElement(LayoutElement.PAGESIZE_A4,
LayoutElement.ORIENTATION_LANDSCAPE,
10, 10, 10, 10, 10, 10);
// configure with the config, data and layout
PdfDocument pdf = new PdfDocument(config, data, layout);
// go
pdf.createDocument();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
I've seen the move so how can I use this ?
1. Download Beta 7, and extract the updated jar file to a directory c:\lib
2. Download The JavaAgentPdf code
3. Create a new Java agent in your database, add the iText-2.0.8 jar and the new scius-pdfdoc.beta7.jar
3. Replace the JavaAgent code with the downloaded version and update the view name, pdf filename and pdf directory.
Enhancing the example further.
To keep this example short and under 30 lines, I have skipped of some of the things that you should add in for a production implementation, such as dealing with exceptions and checking that the domino objects are not null. However, for a proof-of-concept - it might be adequate. You would also need to write a few more lines to account for a categorised views, hidden columns and possibly the final enhancement would be to make the report look nice with some styles.
Stay tuned because the next post might have an example that produces a pdf that is a bit nicer on the eyes.
Update : The link to the zip file has changed. I found a bug with Beta7 and ParagraphElements.