Main | [Article] A Multiple Find Technique »
September 01, 2004
[Article] Introduction to Beans
by Maarten BerkenboschServoy
http://www.servoy.com/
What Are Beans?
A Java Bean is a reusable software component that works with Java. You can drop a bean as an element into a Servoy form, just like you can add Tab panels, Portals, Buttons etc.
Once you select the bean in the form, a set of properties will come available to you in the Servoy property editor. Which properties of course depends on the kind of bean you are using. You may set these properties by hand (for instance: setting height and width of a bean), but you can also set them dynamically through scripting, using methods.
There’s a wide variety of beans available on the internet (Calendars, spreadsheets, word processors , charts, calculators, clocks, tickertapes etc.) as freeware, shareware, commercial etc.
In this article I will show you an example of how to implement a clock bean and a chart bean.
All we have to do is drop our beans inside the beans folder. This folder can be found inside the main Servoy folder. After that, start Servoy. That’s it.
I’ve downloaded the two beans from http://www.alphaworks.com but unfortunately they’re not available there anymore. The so called ‘Bean bag project‘, has been retired.
You can download them here.
[You're allowed to freely use/distribute them in your applications, but nevertheless please read the IBM license agreement.]
The Clock Bean
1) Create a form in your Servoy solution and open the designer.
2) Click on the coffee bean in the toolbar and select the "IClock" bean.
3) This is the result (See the properties of the selected clock bean on the right of the image below).

If we go into the data mode again the clock initially looks like this:

When we go back into designer and change the property "analogNumeralColor" like this:

...notice the change of colors.

This is in a nutshell the basis of how to use beans in Servoy. But there's more, you can also change properties of a bean dynamically.
Changing Properties of a Bean Through a Method
1) Go into designer and enter “myClock” in the “name”-property.

2) Go back to data mode.
3) Open the Method editor and create a method named “changeClockAppearance” as shown in the next picture.

Notice that the name property "myClock" appears in the elements tree of the form (clock) where I’ve put the clock Bean.
By clicking on “myClock” in the elements tree, all its properties become available in the outline column.
Now you can build a method that can change the look of the clock in various ways.
In this case I’ve made a method that:
- shows an analog clock whenever the country value in the database(!) equals "USA"
- shows a digital clock with AM/PM notation, in short notation.
The possible settings of properties can be found in the documentation that normally comes with a bean (if you're lucky ;o)).
4) Go back to the form Designer and attach this method to "onRecordSelection" property.
The method will execute each time you select another record. (browsing)
As meaningless as this example may be, you can see the possibilities of interacting with beans via event driven scripts. Let's take a look at a more interesting exampleshowing charts that are build on data in real time.
The Chart Bean
Example 1:
This is an overview of the top 10 customers with most nr of orders being Ernst Handel with 20 orders.

Here's the script that creates the chart:
- controller.loadAllRecords() //load all records in the table
- forms.charts.controller.sort('ordercount desc') // sort on nr of orders desc
- //fill chart with values
- for( var i=0 ; i<= 9; i++) //for 10 customers
- {
- forms.charts.controller.recordIndex = i+1 //Servoy recordindex starts counting at 1.
- elements.ordersPerCustomer.setLegends(i, companyname) //set the legends > pos0="..." pos1="..." etc
- var nrOfOrders = forms.charts.ordercount //get nr of orders from the selectedrecord and put in in a Javascriptvariable. (you can also directly set the value in line 16 with "forms.charts.ordercount"
- elements.ordersPerCustomer.setLabels(i,customerid) //sets the labels that are horizontally shown under the x axis
- elements.ordersPerCustomer.setValues(0, i, nrOfOrders)
//The 3 parameters are:
-range > which position within the current x position should be set
-x position > which x position should be set
-value > in this case , nr of orders.
in this example we only show one value(customer total) per x position.
However, in the next example we compare 3 products per x position.
This means setValues would go like this:
setValues(0,2,value) //goto 1st spot of 3rd x position and set value of product 1
setValues(1,2,value) //goto 2nd spot of 3rd x position and set value of product 2
setValues(3,2,value) //goto 3rd spot of 3rd x position and set value of product 3
etc.... - }
Example 2:
This chart shows the revenue of 3 products compared to each other over a three years period.

The script basicly comes down to 3 loops:
1st loop over the years (shown over x axis). The input comes form the array "years". //line 9-27
2nd loop over the products (3 product revenues shown per x position). The input comes from the array "products". //line 12-26
3rd loop over foundset of order_items based on year and product_id. This loop summarizes the revenue per product. // line 19-24
- var years = new Array
(
'01-01-1996...31-12-1996|dd-MM-yyyy',
'01-01-1997...31-12-1997|dd-MM-yyyy',
'01-01-1998...31-12-1998|dd-MM-yyyy'
)
//In javascript you can store data in Arrays like this:
var myArray = new Array('text1','text2',text3',etc...)
to get information out of arrays, do this:
var x = myArray[0] // returns "text1"
var y = myArray[2]// returns "text3" - var products = new Array('7','40','51') //create an array of product_id's you want to compare
- //fill chart with values
- for(var i=0 ; i<years.length ; i++) //loop(nr1) through the years array (3 values)
- {
- elements.parallelChart.setLabels(i,i+1996) //set the labels that are horizontally shown under the x axis
- for(var j=0 ; j < products.length ; j++) //loop(nr2) through the product id's(3 values)
- {
- controller.find() //start a find request
- order_details_to_orders.orderdate = years[i] //search for orderdate via relation to orders table
- productid = products[j] //AND search for product_id in orderdetails table
- controller.search() //perform search
- var totalSold = 0 //create a variable that stores totalRevenue in next loop
- for(var k = 0 ; k< controller.getMaxRecordIndex() ; k++) //loop(nr3) through the foundset of orderdetails
- {
- controller.recordIndex = k+1 //start at first record. Servord recordindex starts at 1
- elements.parallelChart.setLegends(j,order_details_to_products.productname) //set the legends of the chart with current product
- totalSold = totalSold + (quantity * unitprice) //store (quantity * price) in the totalSold variable
- } //close loop nr3
- elements.parallelChart.setValues(j,i,totalSold ) //set the value in the chart:
j = current spot within x position (products)
i = current x position (years)
totalSold = value - } //close loop nr2
- } //close loop nr1
Example 3:
This example will show the same result using an SQL statement to retrieve data.
Benefits:
- Much, much faster.
- More flexible.
- No need to fill your solution with dozens of relations and forms just for the sake of reporting.
- Results can be shown anywhere in your solution because the SQL statement isn't linked to a form.
For those of you who aren't familiar with SQL, in one of our next articles we will do a tutorial on SQL, using an SQL generator build in Servoy.
[It's really worth the (small) effort to understand the basics of SQL.]
- var years = new Array
(
" '01-01-1996'AND'12-31-1996' ",
" '01-01-1997'AND'12-31-1997' ",
" '01-01-1998'AND'12-31-1998' "
)
//store the strings needed to find a certain year in an array.
You can retrieve them in a loop again with years[i]. - for(var i=0 ; i<years.length ; i++) //start loop
- {
- elements.parallelChart.setLabels(i,i+1996 ) //set the labels that are horizontally shown under the x axis
- var query = "select products.productname,"+
" SUM(order_details.quantity * order_details.unitprice)"+
" from orders, order_details, products"+
" where orders.orderid = order_details.orderid"+
" and order_details.productid = products.productid"+
" and products.productid IN (7,40,51)"+
" and orders.orderdate BETWEEN "+ years[i] +
" group by products.productname"+
" order by products.productid asc"
//This query basically gets the following information per loop(year):
productName1 | totalRevenue
productName2 | totalRevenue
productName3 | totalRevenue
Notice that with SQL, you don't have to do another loop to summarize the revenue per product - var dataset = databaseManager.getDataSetByQuery(controller.getServerName(), query, null, 10000);
//puts the query into the variable dataset.
parameters:
1) server to connect to
2) query as defined
3) you can set an array here if you're query looks like this
"select * from table where id = ?
If you're array is ('12','34','56') the databaseManager will actually query for all ids that contain the values in the aray.
4) maximum returning records
____________dataset[1]__ |__dataset[2]__
rowIndex1= productName1 | totalRevenue
rowIndex2= productName2 | totalRevenue
rowIndex3= productName3 | totalRevenue - for( var j = 1 ; j <= dataset.getMaxRowIndex() ; j++ ) //start the loop through the dataset
- {
- dataset.rowIndex = j; //set the rowIndex
- elements.parallelChart.setLegends(j-1,dataset[1]) //set the legends with productname
- elements.parallelChart.setValues(j-1,i,dataset[2] ) //set the value with totalRevenue
- }
- }
One last remark about the chart bean. Be aware of the fact that when you're browsing through records using a chart, you might want to clear it first, before putting new data into it. Here's an example:
Suppose you are in record nr1 showing a chart with 8 columns and you're about to browse to the second record. If the second record only has data for filling the first 6 columns, the last 2 columns will still show results from the previous record. To avoid this, you should empty the chart, by doing a loop first that sets all values to empty ("").
As we have seen in this article, JavaBeans are very well integrated with Servoy and extremely easy to use.
Thanks to the support of JavaBeans it is possible to extend the functionality of servoy very easily.
There are thousands of opensource and commercial beans available on the internet.
A few starting points:
| Posted by David Workman on September 1, 2004 at 03:24 PM in Articles | Permalink
TrackBack
TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8341c8d8153ef00d83472e39369e2
Listed below are links to weblogs that reference [Article] Introduction to Beans:
Comments
Are these links broken?www.javashareware.com
www.techemployment.com
www.jfind.com
www.freewarejava.com
www.freedownloadscenter.com
www.jars.com
Posted by: John Pollard | Dec 2, 2004 5:51:26 PM
Those URL's work, but yes...the links are dodgy.
Seems David made a typo along the line somewhere.
Just copy/paste the URL and they'll work.
Posted by: Robert J.C. Ivens | Dec 12, 2004 6:40:04 AM