Thursday Jan 03, 2008
Thursday Jan 03, 2008
Here is a mini-tutorial for creating a Popup window for the user to lookup values. One scenario that you might use this for is when the page visitor needs more information then can be displayed in a drop-down list.
This is a rewrite of a previous blog entry that was written for the Sun Java Studio Creator IDE. I have modified the steps so that it works for the NetBeans 6.0 IDE.
Popup.onClick property to doSave('#{currentRow.value['STATE.STATEID']}')
<webuijsf:script binding="#{Popup.script1}" id="script1">
<![CDATA[
function doSave(val) {
window.opener.setVal(val);
window.close();
}]]>
</webuijsf:script>
|
Form1. Make it be the start page. text property to State Code.url property to /faces/Popup.jsp.onClick property to doPopup('form1:textField1_field')popup. Click OK and click OK again.target property value is still blank, select popup from the value from the combobox for that property.
<webuijsf:script binding="#{Form1.script1}" id="script1">
<![CDATA[
function doPopup(destination) {
popup = window.open("", "popup",
"height=300,width=200,toolbar=no, menubar=no,scrollbars=yes");
destinationElement=document.getElementById(destination);
popup.focus();
}
function setVal(val){
destinationElement.value=val;
}]]></webuijsf:script>
|
Thursday Sep 06, 2007
I migrated the sample tutorial project that I created for the Sun Java Studio Creator IDE into a NetBeans IDE 6.0 web application that uses the Visual Web Java Server Faces framework. You can download this NetBeans IDE project from here. If the pages do not display in the Visual Designer (and you get an error page instead), do a clean build, then close and reopen the IDE.
Note that this project uses the JSF 1.4 versions of the Web UI components, and not the newer versions.
This sample project:
When you click a detail button, the button's action method uses a tableRowGroup method to get the row key for the row that the button is in. The method then uses the row key to get the value for the foodId column, which it saves in the request bean for use by the detail page.
public String showDetailBtn_action() {
// Find out what row was clicked
RowKey rowKey = tableRowGroup1.getRowKey();
// Save food id so detail page knows what food item to show
// provide detail info for
getRequestBean1().setFoodId(
getSessionBean1().getFoodListDataProvider().
getValue("foodId", rowKey).toString());
return "detail";
}
|
The checkbox column is not bound to any column in the dataprovider, but is instead bound to a page property named selected. The getter and setter use a TablePhaseListener object to manage which checkboxes are selected.
public void setSelected(Object object) {
RowKey rowKey = tableRowGroup1.getRowKey();
if (rowKey != null) {
tablePhaseListener.setSelected(rowKey, object);
}
}
/**
* Getter for selected.
* @return Object value for the current row's checkbox
*/
public Object getSelected() {
RowKey rowKey = tableRowGroup1.getRowKey();
return tablePhaseListener.getSelected(rowKey);
}
|
Winston explains how to do this as well as how to highlight the rows that are selected in his How to Create Muli-Row Selectable Table Component blog.
To calculate calories, the Calculate Calories button's action method calls a method that iterates over the tableRowGroup object's selectedRowKeys to accumulate the total calories for the selected rows.
public String calculateCaloriesBtn_action() {
getSessionBean1().setTotalCalories(getTotalCalories());
return null;
}
public String getTotalCalories() {
int total = 0;
// Go through the list of selected rows
Integer calories;
Integer nbrServings;
FoodListDataProvider foodListDP =
getSessionBean1().getFoodListDataProvider();
RowKey[] selectedRowKeys =
getTableRowGroup1().getSelectedRowKeys();
for (int i = 0; i < selectedRowKeys.length; i++) {
String rowId = selectedRowKeys[i].getRowId();
RowKey rowKey = foodListDP.getRowKey(rowId);
// get serving size
String size = (String)
getSessionBean1().getServingSizeMap().get(rowId);
// get calories for serving size
calories = (Integer) foodListDP.getValue(size, rowKey);
// get number of servings
nbrServings = (Integer)
getSessionBean1().getNbrServingsMap().get(rowId);
// add to total
total += calories.intValue() * nbrServings.intValue();
}
return Integer.toString(total);
}
|
The Nbr Servings text field and Serving Size drop down list are also not bound to the underlying data provider. I created Map objects to store the values for each row and bound the components to session bean properties.
/**
* Getter for property nbrServings.
* @return Value of nbrServings for current row
* defaults to 1
*/
public Integer getNbrServings() {
TableRowDataProvider rowData =
(TableRowDataProvider) getBean("currentRow");
if (rowData == null) {
return new Integer(1);
} else {
String rowId =
rowData.getTableRow().getRowId();
Integer nbrServingsValue =
(Integer) this.getNbrServingsMap().get(rowId);
if (nbrServingsValue == null) {
return new Integer(1);
} else {
return nbrServingsValue;
}
}
}
/**
* Setter for nbrServings for current row
* @param nbrServings New value of nbrServings.
*/
public void setNbrServings(Integer nbrServings) {
TableRowDataProvider rowData =
(TableRowDataProvider) getBean("currentRow");
if (rowData != null) {
String rowId = rowData.getTableRow().getRowId();
this.getNbrServingsMap().put(rowId, nbrServings);
}
}
/**
* Getter for servingSize.
* @return Value servingSize for current row
* Defaults to cup
*/
public String getServingSize() {
TableRowDataProvider rowData =
(TableRowDataProvider) getBean("currentRow");
if (rowData == null) {
return "cupCalories";
} else {
String rowId = rowData.getTableRow().getRowId();
String servingSize =
(String) this.getServingSizeMap().get(rowId);
if (servingSize == null) {
return "cupCalories";
} else {
return servingSize;
}
}
}
/**
* Setter for servingSize for current row
* @param servingSize New value of property servingSize.
*/
public void setServingSize(String servingSize) {
TableRowDataProvider rowData =
(TableRowDataProvider) getBean("currentRow");
if (rowData != null) {
String rowId = rowData.getTableRow().getRowId();
this.getServingSizeMap().put(rowId, servingSize);
}
}
/**
* Holds value of property nbrServingsMap.
*/
private Map nbrServingsMap = new HashMap();
/**
* Getter for property nbrServingsMap.
* @return Value of property nbrServingsMap.
*/
public Map getNbrServingsMap() {
return this.nbrServingsMap;
}
/**
* Setter for property nbrServingsMap.
* @param nbrServingsMap New value of property nbrServingsMap.
*/
public void setNbrServingsMap(Map nbrServingsMap) {
this.nbrServingsMap = nbrServingsMap;
}
/**
* Holds value of property servingSizeMap.
*/
private Map servingSizeMap = new HashMap();
/**
* Getter for property servingSizeMap.
* @return Value of property servingSizeMap.
*/
public Map getServingSizeMap() {
return this.servingSizeMap;
}
/**
* Setter for property servingSizeMap.
* @param servingSizeMap New value of property servingSizeMap.
*/
public void setServingSizeMap(Map servingSizeMap) {
this.servingSizeMap = servingSizeMap;
}
|
Monday Jul 02, 2007

Sunday Dec 17, 2006
A forum poster recently asked for the following information:
I have a table with 5 columns, (week_no, objective, date1, date2 and add report). How do I get the date for date1( example, today's date)? How do I set the week number as auto increment by 1( example, row 1, the week_no is 1, row 2, the week_no is 2 and so on)? Lastly, how to I set the add report button to link to another JavaServer Pages file?
This scenario gives me an excellent opportunity to show how to use an Object Array Data Provider (OADP). I usually use the Object List Data Provider (OLDP), but OLDPs take a bit more work. (See the Using Hibernate tutorial for an OLDP example.) If you have a simple array of data, the OADP might be the better choice, as in this case. The following steps create a table similar to the one requested in the forum.
/*
* WeekBean.java
*
*/
package arraytableexample;
public class WeekBean
extends Object implements Serializable {
private int weekNumber;
private Calendar startDate;
private Calendar endDate;
private int dayOfWeek;
public WeekBean(int weekNumber) {
this.weekNumber = weekNumber;
Calendar workingDate = Calendar.getInstance();
workingDate.set(java.util.Calendar.HOUR_OF_DAY, 0);
int offset = weekNumber - 1;
workingDate.add(
Calendar.DAY_OF_YEAR,
+ (offset * 7));
dayOfWeek = workingDate.get(Calendar.DAY_OF_WEEK);
startDate = (Calendar) workingDate.clone();
startDate.add(
Calendar.DAY_OF_YEAR, - (dayOfWeek - Calendar.SUNDAY));
endDate = (Calendar) workingDate.clone();
endDate.add(
Calendar.DAY_OF_YEAR,
+ (Calendar.SATURDAY - dayOfWeek));
}
public WeekBean() {
this(1);
}
public int getWeekNumber() {
return this.weekNumber;
}
public void setWeekNumber(int weekNumber) {
this.weekNumber = weekNumber;
}
public Calendar getStartDate() {
return this.startDate;
}
public void setStartDate(Calendar startDate) {
this.startDate = startDate;
}
public Calendar getEndDate() {
return endDate;
}
public void setEndDate(Calendar endDate) {
this.endDate = endDate;
}
}
/**
* Holds value of property weeks.
*/
WeekBean[] weeks = {
new WeekBean(1),
new WeekBean(2),
new WeekBean(3),
new WeekBean(4)
};
/**
* Getter for property weeks.
* @return Value of property weeks.
*/
public WeekBean[] getWeeks() {
return this.weeks;
}
/**
* Holds value of property reportStartDate.
*/
private Calendar reportStartDate;
/**
* Getter for property reportStartDate.
* @return Value of property reportStartDate.
*/
public Calendar getReportStartDate() {
return this.reportStartDate;
}
/**
* Setter for property reportStartDate.
* @param reportStartDate New value of property reportStartDate.
*/
public void setReportStartDate(Calendar reportStartDate) {
this.reportStartDate = reportStartDate;
}
/**
* Holds value of property reportEndDate.
*/
private Calendar reportEndDate;
/**
* Getter for property reportEndDate.
* @return Value of property reportEndDate.
*/
public Calendar getReportEndDate() {
return this.reportEndDate;
}
/**
* Setter for property reportEndDate.
* @param reportEndDate New value of property reportEndDate.
*/
public void setReportEndDate(Calendar reportEndDate) {
this.reportEndDate = reportEndDate;
}
weekNumber startDate endDate
public String button1_action() {
getSessionBean1().setReportStartDate(
(Calendar)getValue("#{currentRow.value['startDate']}"));
getSessionBean1().setReportEndDate(
(Calendar)getValue("#{currentRow.value['endDate']}"));
return null;
}
Winston has many blog entries about the dataprovider. A good place to start is his blog titled What is this Data Provider in Sun Java Studio Creator anyway?. Another good resource is Joel Brown's Weblog.
jsf netbeans creator dataprovider
Thursday Jun 15, 2006
After all these months, I am finally making progress on the tutorial for the Table component. It might be a long time before I document all the steps and get the tutorial through quality assurance, editorial, and production processes. So, for those who can learn by examining code, I have decided to post the project that you build by completing the tutorial.
Here are some of the project's features:
Of course, everything I learned, I learned from Winston. He has posted lots of good Table component tips in his blog, so be sure to go there for advanced Table component information.
You can download the project zip from here.
Monday Mar 27, 2006
Here is a one way to add a checkbox column to a table and determine which checkboxes have been checked.
selectedRows = new HashSet();
/**
* Getter for property selected
* @return true if checkbox in current row is selected
*/
public boolean isSelected() {
TableRowDataProvider rowData = (TableRowDataProvider) getBean("currentRow");
if (rowData == null) {
return false;
} else {
String rowId = rowData.getTableRow().getRowId();
if (this.getSelectedRows().contains(rowId)) {
return true;
} else {
return false;
}
}
}
/**
* Setter for property selected.
* @param boolean; true if checkbox is selected, false if checkbox is cleared.
*/
public void setSelected(boolean b) {
TableRowDataProvider rowData = (TableRowDataProvider) getBean("currentRow");
if (rowData != null) {
String rowId = rowData.getTableRow().getRowId();
if (b) {
this.getSelectedRows().add(rowId);
} else {
this.getSelectedRows().remove(rowId);
}
}
}
Iterator rows = getSessionBean1().getSelectedRows().iterator();
while (rows.hasNext()) {
String rowId = (String) rows.next();
RowKey rowKey = <your table's data provider>.getRowKey(rowId);
... use the row key to access the data in the data provider
}
Friday Mar 17, 2006
Let's say that you want to put a footer in a column to show the column's total. To do so, you could code like the following in a property's getter method and bind the column's footer to the getter method.
int total = 0;
try {
employeeDataProvider.cursorFirst();
do {
...
total += somevalue;
}
} while (employeeDataProvider.cursorNext());
} catch (Exception ex) {
error("put your message here" +
ex.getMessage());
log("put your message here: " +
ex.getMessage(), ex);
}
return total;
Sometimes, you might have some columns that are bound to the underlying data provider and some that are not. So, how do you iterate through the columns that are not bound to the data provider's fields. For those columns, you can create a hash map in the session bean that is keyed on the row id. Then you can create a getter and setter like the following and bind the column to the property (nbrServings in this example).
public Integer getNbrServings() {
TableRowDataProvider rowData =
(TableRowDataProvider) getBean("currentRow");
if (rowData == null) {
return new Integer(1);
} else {
String rowId = rowData.getTableRow().getRowId();
Integer nbrServingsValue =
(Integer) this.getNbrServingsMap().get(rowId);
if (nbrServingsValue == null) {
return new Integer(1);
} else {
return nbrServingsValue;
}
}
}
public void setNbrServings(Integer nbrServings) {
TableRowDataProvider rowData =
(TableRowDataProvider) getBean("currentRow");
if (rowData != null) {
String rowId = rowData.getTableRow().getRowId();
this.getNbrServingsMap().put(rowId, nbrServings);
}
}
Then add something like the following to the session bean's init method.
nbrServingsMap = new HashMap();
You can then iterate through the has map's set of values.
Friday Mar 03, 2006
Here is a quick hack for detecting what radio button was clicked in a Table component.
Use the Table Layout dialog to add a column to the table and set its Compnent Type be Radio Button.
Add this to the page bean:
public String getCurrentRow() {
return tableRowGroup1.getRowKey().getRowId();
}
public void setCurrentRow(int row) {
}
private Object lastSelected="0";
public Object getRBSelected() {
String sv = (String)radioButton1.getSelectedValue();
return sv.equals(lastSelected) ? sv : null;
}
public void setRBSelected(Object selected){
if (selected != null) {
lastSelected = selected;
}
}
In either the Outline window or the Visual Designer, select radioButton1.
In the Properties window for radioButton1, set the name property (in the Advanced section) to buttonGroup.
In the Data section for radioButton1, click the ... button for the selected property. A dialog box appears.
Select Use Binding, Click the Bind to an Object tab, select RBSelected, and click OK.
The application will now use the getRBSelected() and setRBSelected() methods to display and save user input for this component.
In the Advanced section of the Properties sheet, click the ... button for the selectedValue property.
Select Use Binding, Click the Bind to an Object tab, select currentRow, and click OK.
The application will now use the getCurrentRow() method to return the selected value for this component.
Now to find out what as been selected. In this example, the code is in a button action method:
String aRowId = (String)RadioButton.getSelected(
"buttonGroup");
RowKey aRowKey = stateDataProvider.getRowKey(aRowId);
selectedStateStaticText.setText("You Selected " +
stateDataProvider.getValue("STATE.STATENAME",aRowKey));
If you want the selection to remain for when the user returns to the page, then you can stick the properties in a session bean. But, then you need to consider what to do if the selected row doesn't exist anymore.
Saturday Jan 14, 2006

The Table tutorial will not be available for awhile, so here is a mini-tutorial on putting links in tables. It is another quick and dirty tutorial that assumes you know how to do things like bind to database tables and add bean properties.
return hyperlink1.getText().toString();
Let's say that you do not want to show the product code in the table, but you instead want the descriptions to be links to the detail pages and the detail page for a product still be different depending on the product code. Here is how you would do that.
// Find out what row was clicked
RowKey rowkey = tableRowGroup1.getRowKey();
// Save product number so detail page knows what product to
// provide detail info for
getRequestBean1().setProductNum(
product_tblDataProvider.getValue(
"PRODUCT_TBL.PRODUCT_NUM", rowkey).toString());
// Go to the detail page for that product's type
return product_tblDataProvider.getValue(
"PRODUCT_TBL.PRODUCT_CODE",
rowkey).toString();
Right-click and choose Fix Imports. You might see a red squiggly line under the statement that calls getProductNum. This should go away after you build the application. Sometimes the synchronizer doesn't notice changes to the request bean until you compile all the files.
Run and test.
Now, let's say that you only want people to go to detail pages for HW and SW.
Here is how to disable the links for all other product codes.
private boolean linkDisabled;
public boolean isLinkDisabled() {
String productCode = product_tblDataProvider.getValue(
"PRODUCT_TBL.PRODUCT_CODE",
tableRowGroup1.getRowKey()).toString();
if (productCode.equals("HW") ||
productCode.equals("SW")) {
return false;
} else {
return true;
}
}
What if you only had two types of detail pages, one detail page for HW, SW, and FW and one detail page for all the other product codes. How would you do that? See if you can make it happen.
Thanks to Felix and Fredrik who motivated me to write this blog entry.
Thursday Dec 15, 2005
I just finished upgrading the
Using Databound Components to Access Databases
for the final release of the product. Because this upgraded tutorial won't be published until after the final Creator 2 release comes out, I thought I would share the following piece of information that I added to the tutorial. I have seen several posts on the EA forum where people are asking how to reposition the cursor to a different table row. The answer is to call tableRowGroup1.setFirst(zero-based-index-value);.
If you use the table paging feature on a master detail page that is like the one in the tutorial (a drop-down list for the master data and a table for the detail data), you will see that when the user selects a different choice from the dropdown list, the table displays new data, but stays on the current page. For example, if the user switches to page 2 and then chooses a new item from the dropdown list, the table shows the second page of data for the new selection. To fix the problem, add the following code after the tripDataProvider.refresh() statement in the master component's value change event handler: tableRowGroup1.setFirst(0);. This ensures that the first page is always displayed when a new name is selected from the drop-down list.
A new tutorial, GoogleSearch Web Service Portlet, will be added to the EA tutorials page, hopefully today or tomorrow.
The upgrading of the Referencing Class Libraries tutorial from Creator 1 to Creator 2 was low on our priority list. However, several people sent a request for this tutorial to the CreatorDocsFeedback@Sun.Com alias. So, we have upgraded this tutorial and it is going through the engineering review process. Your input matters to us, so please continue to submit tutorial suggestions.