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 09, 2007

If you would like the components to remain centered on a page when the browser is resized, try this trick.
.ctrFirstColumn { |
Tuesday Jun 19, 2007
Tuesday Jun 05, 2007
In an earlier blog, we showed how to build coordinated drop down lists in a NetBeans Visual Web application. One problem with the techniques in that blog you is that you have to submit the whole page whenever a new selection is made from any of the drop down lists. If you have other components that get validated on page submission, it gets a bit messy, as you have to distinguish between when the page is submitted because of a new list selection and when the user is actually submitting the form.
The Dynamic Faces component library provides a solution to this problem. You can put the Drop Down List components in a Dynamic Faces Ajax Zone so that only the input from those components is sent to the server (as part of an Ajax request) when the user makes a new drop down selection. You can also specify which components to rerender when the server returns the Ajax response.
The following steps show how to do this using the tables from the sample Travel database. This example involves a coordinated person-trip-flight selection and the detail data for the selected flight. When you select a new person, the trip drop-down list shows all the person's trips and pre-selects the first trip on the list. The flight drop-down list shows all the flights for the selected trip, and pre-selects the first flight on the list. The page also redisplays the detail data for the selected flight. All other fields are not touched unless the whole page is submitted.
If you haven't already done so, you need to install the Dynamic Faces component library into the NetBeans IDE. Follow the steps in the Installing the Dynamic Faces Component Library section of the Installing the Currency Trader Sample Application tutorial.
Dynamic Faces provides a custom Lifecycle object that enables the
JavaServer Faces lifecycle to handle Ajax transactions and to re-render portions
of a component tree without requiring a full-page refresh.
To make the runtime
aware of the custom Lifecycle object:
The Ajax Zone component arms its children with the capability of sending Ajax requests. In this example, you add the three Drop Down List components to an Ajax Zone. The default behavior for an Ajax Zone component is to submit, execute, and rerender all the components in the zone whenever there is an onclick event for an input component within the zone.
You next add a Property List component to display the flight details, and you configure the Ajax Zone to render the Property List in addition to the components in the Ajax Zone.
Now, add a Text Field and a Button component to the page. By doing this, you can see for yourself how the Ajax Zone is a partial page submit, whereas, when the button is clicked, the whole page is submitted.
Add the following code to the backing bean for coordinating the drop-down lists and flight detail data. (See http://blogs.sun.com/divas/entry/coordinated_drop_down_lists for more information about coordinated drop-down lists).
public void initFlightDropDown() {
try {
tripDataProvider.cursorFirst();
getSessionBean1().getFlightRowSet().setObject(
1, tripDataProvider.getValue("TRIP.TRIPID"));
flightDataProvider.refresh();
tripDD.setSelected(tripDataProvider.getValue("TRIP.TRIPID"));
} catch (Exception e) {
error("Cannot switch trips");
log("Cannot switch trips", e);
}
}
public void initFlightDetail() {
try {
flightDataProvider.cursorFirst();
// detail data is in the page bean
flightRowSet.setObject(
1, flightDataProvider.getValue("FLIGHT.FLIGHTID"));
detailFlightDataProvider.refresh();
flightDD.setSelected(flightDataProvider.getValue("FLIGHT.FLIGHTID"));
} catch (Exception e) {
error("Cannot switch flights");
log("Cannot switch flights", e);
}
}
|
public void prerender() {
if ( personDD.getSelected() == null ) {
try {
personDataProvider.cursorFirst();
getSessionBean1().getTripRowSet().setObject(
1, personDataProvider.getValue("PERSON.PERSONID"));
tripDataProvider.refresh();
personDD.setSelected(
personDataProvider.getValue("PERSON.PERSONID"));
} catch (Exception e) {
error("Cannot switch to selections");
log("Cannot switch to selections", e);
}
initFlightDropDown();
initFlightDetail();
} else {
try {
// Synchronize data providers with current selections
personDataProvider.setCursorRow(
personDataProvider.findFirst(
"PERSON.PERSONID", personDD.getSelected()));
tripDataProvider.setCursorRow(
tripDataProvider.findFirst(
"TRIP.TRIPID", tripDD.getSelected()));
flightDataProvider.setCursorRow(
flightDataProvider.findFirst(
"FLIGHT.FLIGHTID", flightDD.getSelected()));
// rowset for the detail flight is in the page bean
flightRowSet.setObject(
1, flightDD.getSelected());
detailFlightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch to selections");
log("Cannot switch to selections", e);
}
}
}
|
public void personDD_processValueChange(ValueChangeEvent event) {
try {
getSessionBean1().getTripRowSet().setObject(
1, personDD.getSelected());
tripDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch person id");
log("Cannot switch person id", e);
}
initFlightDropDown();
initFlightDetail();
}
|
public void tripDD_processValueChange(ValueChangeEvent event) {
try {
getSessionBean1().getFlightRowSet().setObject(
1, tripDD.getSelected());
flightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch trips");
log("Cannot switch to trips", e);
}
initFlightDetail();
}
|
public void flightDD_processValueChange(ValueChangeEvent event) {
try {
flightRowSet.setObject(
1, flightDD.getSelected());
detailFlightDataProvider.refresh();
} catch (Exception e) {
error("Cannot switch flights");
log("Cannot switch flights", e);
}
}
|
Click the Run Main Project button to test out the web application. Select different people, trips, and flights to see the partial form updates. Notice how even though the text field is required, you do not see any validation errors, because the Text Field component is not part of the partial page submission. However, if you submit the form by clicking the Submit button, an error message appears in the Message Group component if the text field is blank.
Friday May 11, 2007
I saw one of the best sessions on Thursday, Using Ajax With POJC (TS-9511). Craig talked about the various ways to Ajaxify plain old JavaServer Faces components and discussed the various challenges. One important point that he made is that you need to consider whether it is necessary to keep the client state and server state synchronized. The answer to this question can make a difference on what technology you choose. Jayashri followed with a quick demo on how easy it is to use Ajax4jsf to dynamically update one field based on the input in another, and then Matt did the same using Dynamic Faces. The session ended with a kick-butt demo by Matt, who built the Currency Trader application in 3 minutes 10 seconds, with music no less! (Note: I am extremely biased because these three are among my favorite engineers to work with).
They are redoing the talk on Friday, so don't miss it.
The AJax and JavaServer faces panel was another great session (TS-6713) because they were very interactive with the audience and answered some hard questions. The key takeaway for me was that you should not expect interoperability from the various Ajax JavaServer faces frameworks due to some issues with JavaScript, especially if the framework doesn't utilize namespaces well. At least not now. JSF 2.0, whenever that comes out, will include some Ajax features which hopefully will make it easier for these frameworks to play together.
Both of these talks discussed why you would want to use JSF components in your Ajax apps. The both mentioned that JSF offers accessibility, security, validation, conversion, and localization.
Thursday May 10, 2007
How many people does it take to make a hands-on lab? A whole lot! I want to thank everyone in this picture for their contribution to Lab 4460: Building Ajax-Enabled JavaServer Faces Web Applications With jMaki, Dynamic Faces, and the NetBeans IDE.. Winston gives links in his blog to this lab and other NetBeans labs that you can download now.
One of the sessions that I got a lot from was TS-6590 Killer JavaScript Technology Frameworks for Java Platform Developers. This session made Carla's earlier session on jMaki (TS-6375) more compelling. jMaki enables you to use different JavaScript frameworks without having to learn the various particulars of each framework.
Daniel McWeeny did a talk on using Ruby on Rails in a real-world application (TS-9144). He talked about how his company used Ruby to make a modern front end to legacy applications using limited resources and time. As I mentioned before, Gail is working on Ruby on NetBeans docs so I am looking forward to talking to her about this technology.
Wednesday Apr 04, 2007
A customer recently sent email that he was having trouble migrating the Movie Administration Sample Application, originally written for Sun Java Studio Creator, into NetBeans Visual Web Pack. When he opened the project in VWP, he resolved the missing server error by setting the target server to the Bundled Tomcat server. Upon running the application, he received the following error message:
package javax.faces does not exist
This error indicates that the J2EE packages are not available to the Tomcat web server. The fix is to add the JSF 1.1 library to the project as follows:
A second problem, an HTTP 500 Status error, occurred when deploying the application. The server log included this error:
java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/ConfigThis is because the
standard.jar/jstl.jar are needed for deploying to the Tomcat server. Here's the fix:
For more information on migrating projects, see Importing a Sun Java Studio Creator 2 Project in NetBeans Visual Web Pack 5.5.
Wednesday Mar 28, 2007
Our newest Visual Web Pack tutorial, Using the Ajax Text Completion Component shows how build a web application that contains a text field component created using Java BluePrints Ajax technology. As you type in the text field, auto-completion is attempted based on a list of possible expansions provided by a 180,000-word English dictionary.
This tutorial is significant in that it not only provides a good use case for working with the Ajax Text Completion component, but also discusses how to work with a web service. The dictionary that the application uses is provide by a web service. To access the dictionary service client, you must download the Dictionary Service, deploy the DictionaryService.war to your application server, and then add the web service to your application. When you exercise the tutorial, however, note that there are minor differences in the web service code, depending on whether you are working with a Java EE 5 or J2EE 1.4 project.
This tutorial is tailored for use with the Sun Java Application Server PE 9.0 Update Release 1.
Wednesday Mar 21, 2007
If you take a look at the tutorials on our VWP tutorials index page, you'll note that the tutorials are organized by category. On this page, we've organized those same tutorials into four learning trails to help you find a tutorial based on your skill level. The first trail covers the basics of creating a visual web application. From there, you move onto more advanced (and quicker-paced) trails on components, databases, and Ajax.
If you are new to visual web application development, follow this trail through the tutorials. These tutorials cover the basics of web application and do not require any prior experience working with an integrated development environment (IDE). After you complete these tutorials, you should be able to create your own working application that accesses a database.
These tutorials go into the nitty-gritty details about components and databases and require a bit more programming knowledge. The final tutorial takes a little more time to complete as it covers the common (albeit advanced) scenario of creating a CRUD application. By the time you have completed this trail, you should be able to create a more sophisticated web application.
If you've come this far, you're ready to work with the Ajax components. These components can make your web application appear more responsive (due to asynchronous refreshes of the page).
This trail is for you if you want to extend outside the bounds of Visual Web Pack and work with either the Hibernate or JasperReports frameworks.
Tuesday Mar 13, 2007
The Sun Java Studio Creator community page has been live for several months, with some great user contributions. Now the VWP users have a place to contribute as well. The NetBeans Community Docs Wiki Page enables community members to submit tutorials, white papers, FAQs, tips and tricks, Flash demos, and blogs. The wiki page includes easy-to-follow instructions for submitting content. In addition, James Branam, the Community Docs Manager, includes tips for submitting content in his blog.
Thanks to Sapan Parikh, there is already a community-written VWP tutorial, Component Creation at Runtime Tutorial. This tutorial shows users how to create components, such as command buttons and input text, at run time. James has also written a nice spotlight on Sapan Parikh in his blog.
On a similar note, don't forget the Feedback buttons at the bottom of our tutorials. You can continue to send suggestions and questions on our VWP tutorials by clicking the button and filling out the form. All writers who work on the VWP tutorials receive the feedback. We try to respond as soon as possible, but sometimes it takes us a while to dig up the answer. We especially appreciate the thank yous you send us--it makes our day.
If you have technical questions outside the documentation, you can find more information from the the NetBeans Users alias, nbusers@netbeans.org. To subscribe to the alias, go to this page: http://www.netbeans.org/community/index.html.
Tuesday Feb 27, 2007
We have yet another new tutorial, this one titled Building a Tree From Database Data. This tutorial shows how to build a two-page application, the first page of which includes a Tree component. You populate the first-level nodes in the Tree with names from a database, and the second-level nodes with the trips for that person. The trip nodes are links to a second page, which displays the details for that trip.
Wednesday Feb 21, 2007
Our newest tutorial, Using the Calendar Component, describes how to work with the built-in Calendar component in the Basic section of the Palette. This tutorial provides good use cases for working with the Calendar component, including how to set the the minimum and maximum calendar date, how to verify that a date that the user selects falls within a range, and how to change the calendar style.
Another option for you to try is the Popup Calendar component in the BluePrints Ajax Component Library. The Popup Calendar component was designed to fix the limitations in the built-in Calendar. However, the Popup Calendar component is a prototype and might not fit seamlessly with the other components built into the IDE. For instructions on accessing the Popup Calendar component, see Downloading and Importing Ajax and Other Components.
Monday Feb 12, 2007
A couple of months ago, JB blogged about how to use the Sun Java Studio Creator tutorial to learn about using Hibernate with the Visual Web Pack. We are happy to announce that there is now a Using Hibernate With the Visual Web Pack tutorial. Not only does this show how to use the Hibernate framework in a Visual Web application, it also shows how to use ObjectListDataProvider objects and how to fill an Options array for list-type components.
hibernate vwp dataprovider
Wednesday Jan 31, 2007

We just published a new Visual Web Pack tutorial, Generating Reports and PDFs From a Web Application that shows how use JasperReports to generate HTML and PDF reports from a data source. JasperReports is a reporting tool that outputs reports in HTML, PDF, XLS, CSV, and XML formats. This tutorial provides code, which you can copy to any project's application bean, that fills a report with the same query result that you use to populate the JavaServer Faces components on a page. The tutorial also shows how to modify the build script to compile the JasperReport templates.
Thanks to Craig Conover and Marina Sum who forged the trail with their tutorial on using JasperReports with the NetBeans IDE, and to Craig McClanahan who made sure my sample code followed the "best practices".
Geertjan just blogged on a JasperReports Visual Designer for the NetBeans IDE. I look forward to exploring this designer and finding out how this designer integrates with Visual Web applications.
Friday Jan 26, 2007
We've published two new tutorials since our initial release on December 6.
Thank you for the many good suggestions and comments that you have provided us via the Feedback button at the bottom of our tutorials. Your input is important to us.