Tuesday Feb 28, 2006

Displaying Multiple Fields in a Drop-Down List

The tutorials show how to display a database column in a drop-down list. But what if you want to show multiple database columns in the list. For example, the VIR database table that comes bundled with the product has a FIRSTNAME column and a LASTNAME column. You might want the drop-down list to show both fields, such as "Jane Doe".

One solution is to add an alias to the database query. Using the VIR database table as an example, you drop the VIR database table on the page, and use the Query Editor to add VIR.EMPLOYEE.FIRSTNAME || ' ' || VIR.EMPLOYEE.LASTNAME AS FULLNAME to the query statement, as shown below.

SELECT ALL VIR.EMPLOYEE.ID,
                    VIR.EMPLOYEE.FIRSTNAME,
                    VIR.EMPLOYEE.LASTNAME,
                    VIR.EMPLOYEE.EMAIL,
VIR.EMPLOYEE.FIRSTNAME || ' ' || VIR.EMPLOYEE.LASTNAME AS FULLNAME
FROM VIR.EMPLOYEE    

To test the statement, right-click in the query pane of the Query Editor and choose Run Query. A dialog pops up explaining that the the IDE's parser only knows a small subset of common SQL syntax. Click continue and the Query Editor should output the query results.

You will also see that the the visual panes in the Query Editor for this particular rowset no longer work. This is because of the same reason that the IDE's parser only knows a small subset of common SQL syntax. This problem only affects the Query Editor.

To see the query in action, drop a Drop Down List component on the page, right-click the component and choose Bind to Data. Click the Bind to Data Provider tab, choose employeeDataProvider, select EMPLOYEE.ID for the Value Field, and select FULLNAME for the Display Field.

Click OK. Test and Run.

The above query works with the bundled database. You have to adjust based on the syntax of your database. For example, for MySQL, use something like select concat(member.lastname, ", ", member.firstname).

Wednesday Feb 22, 2006

Simple Form Tutorial

Here is a very basic tutorial on creating a simple input form to add a record to a database. It leaves a lot to the reader. For example, you would want to have nicer messages for duplicate ids and you wouldn't want your error messages to display internal database information such as table names and column names. If the record was added sucessfully, you would probably want the page to navigate elsewhere.

1. Drop three Label components on the left side of the page, one under the other. Set the label text to ID:, Name:, and Description: respectively.

2. Drop three Text Field components on the page, one next to each label. Set the ids for the components to idTF, nameTF, and descriptionTF respectively.

4. Set the required property to true for each Text Field component.

6. Drop three Message components on the page, one next to each text field.

7. Ctrl-Shift-Drag from each Text Field component to its associated label.

8. Ctrl-Shift-Drag from each Text Field component to its associated message.

9. Drop a Button component on the page, under the text fields. Set its text to Add. Set its id to addButton.

10. Drop a Message Group component on the page to the right of the button. Set its showGlobalOnly property to true.

11. Access the Servers window. Drag Data Sources > Travel > Tables > TRIPTYPE and drop it on a blank spot on the page.

11. Double-click the button to access its addButton_action() method. Replace the method's body with the following code shown in bold.

    public String addButton_action() {
        if ( triptypeDataProvider.canAppendRow() ) {
            try {
                RowKey rowKey = triptypeDataProvider.appendRow();
                triptypeDataProvider.setCursorRow(rowKey);
                triptypeDataProvider.setValue("TRIPTYPE.TRIPTYPEID",
                        rowKey,  idTF.getText());
                triptypeDataProvider.setValue("TRIPTYPE.NAME",
                        rowKey, nameTF.getText());
                triptypeDataProvider.setValue("TRIPTYPE.DESCRIPTION",
                        rowKey, descriptionTF.getText());               
                triptypeDataProvider.commitChanges();

            } catch (Exception e) {
                error("Cannot append new trip type: " + e);
                triptypeDataProvider.refresh();
                return null;
            }
        } else {
            error("Cannot append trip types");
            return null;
        }
        //clear fields
        idTF.setText(null);
        nameTF.setText(null);  
        descriptionTF.setText(null);        
        return null;

12. Fix imports.

13. Run and test. It will reject existing IDs (1 through 10).

14. To see the database updates, right-click on the TRIPTYPE node in the Servers window and choose View Data.

Deployment Tutorials on the Loose

In the past two weeks, we published three new deployment tutorials. These tutorials include:

The tutorials describe how to create a web application archive (WAR) file for your application using the IDE, how to configure settings in the server, and how to deploy the WAR file on the server.

Our next theme for tutorial deliverables will center around AJAX components. And speaking of themes, our Themes tutorial is also near completion and will be published soon.

Turning an Input Component into an Action Component

A new tutorial writer, Joe, recently joined the Creator Tutorials team. While working on the Tabset tutorial, he came up with this useful tidbit: how to make a selection from a drop-down list navigate to a different page.

1. Right-click the Drop Down List component and select Auto-Submit on Change.

2. Use the Page Navigation Editor to create links from the page with the drop-down list to the other pages. The rest of the steps assume that you have 3 links -- case1, case2, and case3.

3. Close the Page Navigation editor and return to the page with the Drop Down List component in the Visual Designer. Right-click the Drop Down List component and choose Configure Default Options. (The Delving into Components tutorial shows how to set the list items programmatically.)

4. Make the Value for each option be one of the link names that you added in the Page Navigation editor, such as case1, case2, and case3.

5. In the Visual Designer, double-click the Drop Down List component. The Java Source editor opens up on the process value change event handler for the compnent.

6. Make the body of the method similar to the following code that is shown in bold (using the correct id for your Drop Down List component).

    public void dropDown1_processValueChange(ValueChangeEvent event) {
        Application application = getApplication();
        NavigationHandler navigator = application.getNavigationHandler();
        FacesContext facesContext = getFacesContext();
        try {
            navigator.handleNavigation(facesContext, null,(String) getDropDown1().getSelected());
        } catch (Exception e) {
            log("can't navigate to " + (String) getDropDown1().getSelected());
        }
    }

7. Fix imports.

8. Run and test. You will see that the process value change doesn't get called if you try to select the first item when the page is first displayed. One way to fix that is to make the first item's Display value be something like "Choose One" and have its Value be something like "none." Then wrap the body of the process value change method in an if statement something like this.

if (!"none".equals(getDropDown2().getSelected()))

Wednesday Feb 15, 2006

Calendar Component Tips

Gail (Diva 1) is working on a Using the Calendar Component tutorial. It will be awhile until it gets published (she has lots of irons in the fire) so here are some excerpts from the tutorial.

If you don't set a minimum date, the component defaults to a minimum date of the day after tomorrow. To set your own minimum date you can add code like the following and bind the minDate and maxDate properties to these page bean properties.


private long MILLISECONDS_PER_DAY = 86400000;
private Date today = new Date();

private Date minCalDate;
    
    public Date getMinCalDate() {
        minCalDate = new Date(this.today.getTime()-MILLISECONDS_PER_DAY);
        return minCalDate;
    }
    
    private Date maxCalDate;
    
    public Date getMaxCalDate() {
        Date today = new Date();
        today.setTime(this.today.getTime());
        maxCalDate = new Date(today.getTime() + MILLISECONDS_PER_DAY \* 30);
        return maxCalDate;
    }

If you want to set a default date, you can put code like the following in the prerender method.

public void prerender() {
        // Default start date to today
        if (startCalendar.getSelectedDate() == null) {
            startCalendar.setSelectedDate(this.today);
        }   
    }

If you want to validate starting and ending dates, you can use code like the following (make these be validate event handlers for the Calendar components).

public void endCalendar_validate(FacesContext context, UIComponent component, Object value) {
        Date endDate = (Date)value;
        Date startDate = startCalendar.getSelectedDate();
        if (startDate != null) {
            if (startDate.after(endDate)) {
                throw new ValidatorException(new FacesMessage
                        ("End date must be after start date."));
            } else {
                long nbrDays =
                        ((endDate.getTime() - startDate.getTime()) /
                        MILLISECONDS_PER_DAY) + 1;
                if (nbrDays < 8 ) {
                    throw new ValidatorException(new FacesMessage
("End date must be at least one week after the start date."));
                }
            }
        }
    }

public String validateButton_action() {
            validationMsgTextField.setText(
            (String)DateFormat.getDateInstance(DateFormat.MEDIUM).format(startCalendar.getSelectedDate())
                +
                " - "
                +
                (String)DateFormat.getDateInstance(DateFormat.MEDIUM).format(endCalendar.getSelectedDate())
                + " is a valid date range."); 
        return null;
    }

Friday Feb 10, 2006

About a Page's Lifecycle and Some Tutorials Announcements

When you create a page from Creator's IDE, the IDE inserts several lifecycle methods into the Java source. These methods have Javadoc comments that explain when to use them. Unfortunately, the comments require an indepth knowledge of the JSF lifecycle.

A writer is working on an article about Creator's application model. In the meantime, here is a quick and dirty explanation of what to put in the lifecycle methods.

init. Use this method to initialize resources, such as constants and bean properties. Do not use this method to get or set component values (such as getText() and setText()). When init is called, the page's components may have values, but these values can be stale. If the page is being displayed after submission, the values will not reflect the submitted values. Therefore, the init method is not a good place to reference component values. Nor is it a good place to set component properties. This is because the values can get overwritten after the init method completes.

preprocess. If doing a postback, this method gets called after init. A postback happens when a page is submitted, such as by clicking a button or changing a value in a component for which Auto-Submit on Change is true. This method is where you can initialize stuff needed for conversions, validations, and action handling (such as a button action method). David Botteril shows a good preprocess example in his blog about conditional validation in Java Studio Creator 2. Just as with init, do not get component values in this method as they can be stale, and do not set the values because your setting can get overwritten.

prerender. The prerender method is called after conversions, validations, and action event handling happens, and after the components have been updated with all the submitted values that passed conversions and validations. Now it is finally safe to get and set component values. This method only gets called if the page is actually going to be rendered. If it is a postback where, after the form submission, the application goes to another page, this method doesn't get called. Note: The action event handlers are another place where it is safe to get and set component values.

destroy. This is called after the page is rendered. You can use it to free up resources that were necessary just for the rendering of the page. If your page uses data providers, the IDE sticks code to close the data providers in the destroy method. When a page submission redirects to a different page, there is no guarantee which page's destroy method gets called first. This is not a good place to store away values that are based on user input into request, session, or application beans. The action event methods are better places for doing that.

New and Updated Tutorials Next Week

Hopefully, by the middle of the week, you will see the following new tutorials:

  • Delving Into Components
  • Using the Page Alert Component
  • Working With Data Providers
  • Deploying to Sun Java System Application Server
  • Deploying to a BEA WebLogic Server

We also updated the following tutorials based on user feedback. These should get posted sometime next week as well.

  • Using Tree Components
  • Using Message Components
  • Using Databound Components to Access Databases
  • Using Page Fragments

We are working on tutorials about using the Calendar component about about creating a theme. If you are anxious to learn about creating themes, check out Gregory Murphy's Rough Guide: Editing Themes for Creator 2.0. We are also working on a hands-on lab proposal for JavaOne about using AJAX technology in Creator applications.

Monday Feb 06, 2006

Adding Your Own Tables to the Bundled Database

Today, we received a request via our Creator tutorials feedback alias for information on how to add your own tables to Creator's bundled database. As this bundled database is not meant for production, we suggest that you use your own database. You can use any database that provides a JDBC 3.0 compliant driver. (See http://developers.sun.com/product/jdbc/drivers.) Our Creating Database Server Types and Data Sources tutorial gives an example of how to do this using MySQL.

However, if you want to use the IDE's bundled database for prototyping or what have you, here is how to add your own tables to the bundled database.

1. Create the SQL script and save it in a file, for example:

CREATE USER dbuser PASSWORD dbpassword;
drop schema mySchema;
create schema mySchema AUTHORIZATION dbuser;


create table mySchema.category (
    catid char(20) not null,
    locale varchar(10) not null,
    name varchar(80) null,
    description varchar(255) null,
    constraint pk_category primary key (catid, locale)
)
;


INSERT INTO mySchema.category VALUES (
  'ID1', 'en_US', 'Category 1', 'Description of Category 1')
;

2. In the Servers window, scroll to the bottom of the window and check whether the Bundled Database Server is running. If a red badge appears next to the node's icon, then right-click the node and choose Start Bundled Database from the pop-up menu.

3. Create the schema by completing the following steps.

A. In the Servers window, right-click the Data Sources > Order node and choose View Data from the pop-up menu. A Query tab opens in the editing area.

B. In the Query Editor, click the Import File Containing SQL Commands button (the folder icon), navigate to your SQL script, and click Open.

C. In the Query Editor, click the Configure Run Options button (the grid icon). A Run Query Options dialog box opens.

D. Select the ";" (Semicolon) at End of Line radio button.

E. Click Run Query. The IDE runs the SQL script.

F. Close the Query tab.

4. Add the schema as a data source to the IDE by completing the following steps.

A. In the Servers window, right-click Data Sources and choose Add Data Source from the pop-up menu.

B. Choose the bundled database as the Server Type and enter a data source name, user ID, password, and validation table (choose a small table from your schema). For example, using the example script above, you would enter

Data Source Name: MySchema
User ID: dbuser
Password: dbpassword
Database URL: (Leave the default value)
Validation Table: MYSCHEMA.CATEGORY

C. Click Test to verify your settings.

D. Click Add. An entry appears under Data Sources using the name that you entered for the Data Source Name.

Friday Feb 03, 2006

Disabling a Button After it is Clicked

Sometimes, after an end user submits a form, it takes awhile for the response. In the meantime, you don't want the end user to keep clicking the submit button. The trick is to disable the button from the client side. However, you don't want to disable the button until the client has submitted the form. In our Early Access forum, a Creator user by the name of Faraz submitted the following solution. He used the setTimeout function to delay disabling the button until after the form is sent to the server.

First you add JavaScript LIKE the following to the page's JSP file (you have to replace button1 with whatever the id is for your button). I add it just before the </ui:head> tag.

<script type="text/javascript"><![CDATA[                                          
function disableButton()
{
document.getElementById('form1:button1').disabled = true;
}]]></script>

Next, in the Visual Designer, select the button and, in the Properties window, set the onClick property to the following:

setTimeout('disableButton()', 1)

Creator 2 has been out over a week and we are seeing some problems with people accessing the wrong tutorials for the Creator version that they are using. Here is a cheat sheet.

Creator 2 Tutorials can be accessed from http://developers.sun.com/prodtech/javatools/jscreator/learning/tutorials/index.jsp. The tutorials have a URL that begins with http://developers.sun.com/prodtech/javatools/jscreator/learning/tutorials/2 (note the 2). Creator 2 tutorials have the words Creator 2 in red to the right of the table of contents.

Creator 1 Tutorials (2004Q2) are available from http://developers.sun.com/prodtech/javatools/jscreator/overview/previous/index.html. The revision number under the tutorial heading contains "2004Q2."

Creator 2 EA Tutorials are no longer available.

Wednesday Feb 01, 2006

Tutorials in PDF Format and What's Coming Next

The results of our mini HTML/PDF survey are overwhelming. You would like to see our tutorials in PDF as well as HTML format. We are looking into ways to make this happen and hope to have PDF versions of the tutorials sometime in the spring. In the meantime, along with the release of Creator 2, Sun Microsystems has made available the Java Studio Creator 2 Field Guide in PDF format. You can download it from http://developers.sun.com/prodtech/javatools/jscreator/learning/bookshelf/index.html.

Last week, we released 29 tutorials with the release of Creator 2. We wish we could say we are taking a two-week Hawaiian vacation to celebrate the release (Oh wait! Chris already lives in Hawaii!) but we have more tutorials to write. In fact, two tutorials are coming soon: Working With Data Providers and Delving into Components.

You can easily identify a new tutorial because it will be marked with the New! icon on the tutorials index page.

Since the release of Creator 2, we've received lots of tutorial requests--Page Alerts and Internationalization to name a few. We will be prioritizing these requests in the next week or so. If there is a tutorial that is a priority for you, please email us your request. As always, we appreciate your feedback.

Tuesday Jan 24, 2006

New and Updated Creator Tutorials

A new release of Sun Java Studio Creator is now available, and we've updated all the tutorials for this release except for Delving Into Components, and that will be available next week. As with writing tutorials in the past, we worked closely with engineering to ensure that the updated tutorials show best practices for using Creator. You can easily identify an updated tutorial because it includes the big red Java Studio Creator 2 icon shown here on the top right side of each tutorial.

Among the highlights:

  • Adding Style to Components, a new tutorial, describes how to add styles to both a single component and several instances of the component. The tutorial also describes how to create a new style class and how to create and apply a new style sheet to your project.
  • Referencing Class Libraries, another new tutorial, shows how to add a library reference and use it in your project.
  • Using Tree Components has two new sections: how to add tree nodes that link to web pages and how to dynamically add new tree nodes.
  • Accessing Web Services has been completely redesigned and goes into more detail on how to work with web services.
  • Using Virtual Forms describes the new feature of how virtual forms retain and discard submitted values.

Greg Zieblod, a Sun engineer who works on portlet tools, expands on the GoogleSearch Portlet tutorial in his blog. He writes about how to use the search feature of the Google APIs (doSearch). For those interested, you can view Greg's blog at: http://blogs.sun.com/roller/page/gregz?entry=googlesearch_portlet.

Today's release of Creator also makes all the online help topics included in the product available on the website. This should help make your search for information seamless, whether you are looking for a quick answer to question in a help topic or a more detailed example in a tutorial. The help is at http://developers.sun.com/prodtech/javatools/jscreator/reference/docs/help/

We have numerous more tutorials that we are working on so check back either here or on the tutorials index page to see what's new. As always, if you have a request for a tutorial, please send us feedback at CreatorDocsfeedback@sun.com.

Another Page Fragment Tip and a Question About Perferred Tutorial Formats

In our last blog, Gail showed you how to access page fragment properties. Sometimes, you might want a page fragment to determine what page it is being shown in. To do that, you ask the current view for the view identifier, like this:

String viewId = getFacesContext().getViewRoot().getViewId();

This returns something like "/Page1.jsp" or "/foo/Bar.jsp", and can be used to choose conditional logic based on what page you are in.

For a simple test, add a staticText component to the page fragment, and put the following in the page fragment's init method (which gets called after the prerender() method of the page that contains the page fragment).

 staticText1.setText(getFacesContext().getViewRoot().getViewId());

We have a question for you. Currently our tutorials are in HTML format. However, we have had several customer requests for the tutorials to be in PDF format. If you prefer that the tutorials are in PDF, please send us an email at CreatorDocsFeedback@Sun.Com. If we receive a sizable number of requests for PDF, then we will consider delivering future tutorial releases in both HTML and PDF.

Friday Jan 20, 2006

Aloha, Discovering via Code Completion, and a Page Fragment Tip

Chris: I love the Internet. Not only does it let me work with teams all over the world, such as when I worked with the NetBeans team in Prague, the Internet also enables me to work from anywhere. Today I am on the Big Island in Hawaii. It is a relief getting away from the constant rain and flooding in northern California. On the west side of the Big Island we have the opposite problem -- a severe drought.

I want to talk a bit about discovering how to use Creator's editing features to figure out how to solve your programming tasks on the fly. For example, someone asked in the EA forum how to figure out what column a component is in. I wasn't sure whether the person was asking about a Table component column or a database column so I answered both questions. I didn't really know the answer, so I opened the Java editor on a page that had a Table component, which was bound to a database table. To figure out how to get the Table Column that a component is in, I typed "hyperlink1.get" (where hyperlink1 is the id of a hyperlink component in a table column in my Table component) and pressed Ctrl+Space to raise the code completion box. In the list that appeared was getParent(). This seemed a likely candidate, so I chose that one. I typed ".get" and pressed Ctrl+Space again. In the list was getId(), and I chose that one.

I used the same process to discover how to get the database column associated with a component: hyperlink1.getValueBinding("text").getExpressionString().

It is kind of a bassackwards methodology, but sometimes I find the code completion method to be quicker than reading the Javadoc. If I want to learn more about a method that I have discovered using code completion, then I can look in the little Javadoc pop-up that appears above the code completion box, and I can open the various API references that are available from the Dynamic Help window. If you want to learn more, see the Using the Java Editor tutorial at http://developers.sun.com/prodtech/javatools/jscreator/ea/jsc2/learning /tutorials/javaeditor.html. My other friends for discovering and exploring are the Message Group component (where I use info(string) to send diagnostic messages at rendering time), and the server log (where I use log(string) to send lifecycle and event handling messages to the log).

Gail: This week a customer asked if he could use templates in Creator to create pages with the same header, footer and side menu. Page fragments are the perfect solution for this and the Page Fragment Box component is documented in our tutorial Using Page Fragments at http://developers.sun.com/prodtech/javatools/jscreator/ea/jsc2/learning/tutorials/pagefragments.html.

An updated version of this tutorial is coming out Wednesday, 1/25. The tutorial includes a page fragment that holds links for navigating between the pages in the application. While writing this tutorial, I discovered how to disable the link on the current page. Here are the instructions:

1. Create a new project.

2. Put a page fragment on the page (Page1). Name the page fragment Navigation.

3. Add a Hyperlink component to the page fragment. Set the hyperlink's id property to homeLink, text property to Home, and the url property to /faces/Page1.jsp.

4. Open the Java source code for Page1.

5. Add the following code to the prerender method:

public void prerender() { 
    Navigation navigationFragmentBean = (    
      Navigation)getBean("Navigation");
    Hyperlink homeLink = navigationFragmentBean.getHomeLink();
    homeLink.setDisabled(true);
 }

6. Right-click in the Java Editor and choose Fix Imports.

7. Run the application and verify that the link is disabled.

Saturday Jan 14, 2006

Links in Tables

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.

  1. Drop a Table component on the page. Bind it to the Order > Tables > PRODUCT_TBL database table.

  2. Right-click on on the table and choose Table Layout.

  3. Have the table display the PRODUCT_NUM, PRODUCT_CODE, and DESCRIPTION.

  4. Select the PRODUCT_TBL.PRODUCT_CODE item in the Selected listbox.

  5. Choose Hyperlink from the drop-down list for the Component Type.

  6. Click OK.

  7. Double-click one of the abc text strings that appears in the column for the PRODUCT_CODE. The IDE adds a hyperlink1_action() method and opens the Java source at that method.

  8. Replace the method's body with the following code:
      return hyperlink1.getText().toString();  
    
  9. Click Design to switch to the Visual Designer.

  10. Right-click and choose Page Navigation.

  11. In the Page Navigation editor, right-click and choose New Page. Accept the default page name. Repeat until you have 6 pages in all.

  12. Drag from Page1.jsp to Page2.jsp. Type HW (name the link HW) and press Enter. Repeat for pages 3 through 7, naming the links SW, FW, BK, CB, and MS respectively (these are the product codes that the hyperlink's action method returns). You can cheat and just add pages 2 and 3. Just don't expect the other links to work.

  13. Go back to the source for Page1 and make sure the action method is still the same.

  14. Run the project and see if the links work. You might want to put values in the title property for each page convince yourself that the links are going to the right pages.

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.

  1. First add a String property to the request bean and name it productNum. (Right-click on Request Bean in the Projects window and choose Add > Property to open the dialog box for adding a property).

  2. In the Visual Designer for Page 1, right-click on the table and choose Table Layout.

  3. Select PRODUCT_TBL.PRODUCT_CODE and click the < button to move the product code from Selected to Available. This action removes that column from the Table component.
  4. Select PRODUCT_TBL.DESCRIPTION.

  5. Choose Hyperlink from the drop-down list for the Component Type.

  6. Click OK.

  7. Double-click one of the abc text strings that appears in the column for the PRODUCT_DESCRIPTION. The IDE adds a hyperlink action method and opens the Java source at that method. (While you are here, check to make sure the IDE removed the old hyperlink action method.)

  8. Replace the body of the method with this code:
           // 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();
    
  9. 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.

  1. Add this code to the Java source for Page1:
        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;
            }
        }
    
  2. In the Properties window for the hyperlink, click the (...) button for the disabled property.

  3. Click Use Binding. Click the Bind to an Object tab. Select Page1 > linkDisabled.

  4. Click OK.

  5. Run and Test.

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.

Friday Jan 06, 2006

Tabbing Thru the Tulips

We have received quite a few requests for a tab tutorial. We are working with the engineers to come up with a good sample application. It will be awhile before we publish that tutorial, so here is a quick bare-bones mini-tutorial of how to use a TabSet component to set up page navigation.

  1. In the Projects window, right-click Web Pages and choose New > Page Fragement. Name the page fragment BannerPF.

  2. Drag a TabSet from the Layout section of the Palette and drop it on the upper-left corner of the page fragment. Resize as desired.

  3. In the Outline window, right-click the TabSet and choose Add Tab.

  4. Set the text for the tabs to A and B.

  5. In the Layout section, expand the TabSet node to see the Tab node.

  6. Drag a Tab component from the Palette and drop it on tab1 in the Outline window. Drag another and drop it on tab1 too. Set the text for these tabs to Page 1 and Page 2.

  7. Drag 2 tabs and drop them on tab2. Set the text for these tabs to Page 3 and Page 4.

    You should now have tab3 and tab4 under tab1 and tab5 and tab6 under tab2.



  8. For each of these tabs set the immediate property to true (check the checkbox). Whether you do this or not depends on whether you want people to be able to tab to another page without validating the page that they are on. Setting the immediate property to true means that the pages won't go through validation when the user clicks a tab. The pages will still go through validation when the user submits the page by clicking a button or changing a value in an Auto-Submit on Change component.

  9. In the Outline window, right-click tab1 and choose Edit Action Event Handler. The IDE switches to the Java source and adds the tab1_action method.

  10. Make the code look like this:
      
        public String tab1_action() {
            tabSet1.setSelected("tab3");
            return "case1";
        }
    
  11. Paste the code below into the Java source under the tab1_action() method. Then, in the Outline window, select tab3. In the Properties window, click the ellipsis button (...) for the action property, choose tab3_action from the drop-down list, and click ok. Repeat for every tab and subtab. When you are done, the action property for each tab must name its action handler.
        public String tab2_action() {
            tabSet1.setSelected("tab5");
            return "case3";
        }
          
        public String tab3_action() {
            return "case1";
        }
        
        public String tab4_action() {
            return "case2";
        }
        
        public String tab5_action() {
            return "case3";
        }
        
        public String tab6_action() {
            return "case4";
        }    
    
  12. Open Page1. In the Layout section of the Palette, double-click the Page Fragment Box. Click Close. The page fragment appears at the top of the page.

  13. Create Page2, Page3, and Page4. Add the BannerPF to each of them using the same method.

    You might want to add a Static Text component to each page to label that page, such as "Page 1". Doing so makes it easier to test.

  14. Right-click on a blank spot on one of the pages and choose Page Navigation. In the Page Navigation editor, click Source. Add the following after <faces-config>:
        <navigation-rule>
            <from-view-id>/\*</from-view-id>
            <navigation-case>
                <from-outcome>case1</from-outcome>
                <to-view-id>/Page1.jsp</to-view-id>
            </navigation-case>
        </navigation-rule>
        <navigation-rule>
            <from-view-id>/\*</from-view-id>
            <navigation-case>
                <from-outcome>case2</from-outcome>
                <to-view-id>/Page2.jsp</to-view-id>
            </navigation-case>
        </navigation-rule>
        <navigation-rule>
            <from-view-id>/\*</from-view-id>
            <navigation-case>
                <from-outcome>case3</from-outcome>
                <to-view-id>/Page3.jsp</to-view-id>
            </navigation-case>
        </navigation-rule>
        <navigation-rule>
            <from-view-id>/\*</from-view-id>
            <navigation-case>
                <from-outcome>case4</from-outcome>
                <to-view-id>/Page4.jsp</to-view-id>
            </navigation-case>
        </navigation-rule> 
    
  15. Close the Page Navigation editor and click Save.

  16. Open BannerPF in the Visual Designer. Click JSP to view the JSP source.

  17. Look for this line:
    <ui:tabSet binding="#{BannerPF.tabSet1}" id="tabSet1" selected="tab6" style="position: absolute; left: 0px; top: 0px">
    
    Delete the selected="tabn" parameter. This is important. If you don't do that, then the current tab doesn't always highlight correctly because this JSP code is resetting the current selected value.

    Important: Every time you edit the page fragment, you have to remember to remove the selected parameter from the JSP code. The IDE will keep sticking it in whenever you click on one of the tabs in the Visual Designer. So, if your tabs look like they aren't working, this is the first place to look (the selected parameter in the JSP).

  18. Run and test.

    Notice that the URL doesn't match page displayed. This is because of the forward dispatching mechanism which Winston explains in this blog entry.

As with any quick and dirty write-up, I am sure I left something out, wasn't detailed enough when I needed to be, or didn't take into consideration a common scenario that most people want to do. Post questions and frustrations to the comments.

Sept 2006 Update: SDN member MWH@Keystroke pointed out in the Sun Java Studio Creator forum a common scenario that this doesn't cover. I updated the tab1 and tab2 actions to better handle switching back to the major tabs. MWH replied as follows with some good points to remember:

"Of course there is still the issue that if you select tab 'B', then 'Page 4' within tab B; then select tab 'A'; then return to tab 'B' by selecting 'B' you return to 'Page 3' not 'Page 4'. The developer must maintain the state of each level 1 tab, say via a session bean and restore the proper state when the level 1 tab is selected. When tab 'B' 'Page 4' is selected, set the value in the session. When tab 'B' is selected, retrieve the last level 2 sub tab selected and set it via the tabset1.setSelected('xxx') method. That way the system returns the user to the proper state relative to tab 'B'. Of course the same holds for tab 'A'.

The key is that developers need to understand they are explicitly responsible for keeping the tab state and navigation state in synch if they are using tabsets for navigation from within a page fragment. Which is quite different from using the tabset object from within a single page."

Thursday Dec 22, 2005

Portlets - To Request or Not to Request

The Building a GoogleSearch Web Service Portlet tutorial has been published for a week now. Here is an interesting tidbit from the tutorial:

While developing portlet applications is similar to developing regular web applications, there are some important differences. For example, in a regular web application, you can use a Request Bean to pass information from one web page to the next. However, because of differences in the portlet lifecycle, you must create a Session Bean or Application Bean property and use that property to pass information to another portlet web page.

We've had several requests for a tutorial on Creating a Theme. We are currently working on this tutorial and plan to publish it in January. If there is something specific you would like us to address in this tutorial, please send us email at CreatorDocsFeedback@sun.com. A companion to this tutorial is Adding Style to Components, which will also be available in January. If you would like to be an early reviewer of either the style or theme tutorial, please send us email.

A reader asked us when Creator 2 is coming out. Vaughn answered a similar question in a post in the EA forum. He said that it will probably be released in mid-January, with an emphasis on probably. Creator 2 is undergoing a final customer acceptance program, and the planned release date could slip if the customer acceptance program reveals any serious issues. For more details, check out his post.

Thursday Dec 15, 2005

Paging Master Detail

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.

Thursday Dec 01, 2005

Divas Dish on Creator Tutorials

Gail Chappell and Chris Kutler research and write tutorials for Sun Java Studio Creator. They work closely with Creator engineers and customers to ensure that they are presenting the best information possible.

Gail: The tutorials are such a cool part of Creator. Once a week, my co-worker brings me an update on the number of times each tutorial was hit the previous week. And every week, I'm delighted. I've been in the technical writing business for a while now--long enough to hear "Who reads the documentation anyway?" So it warms me to see that you're reading the tutorials and that you want more. Yep, we read your comments in the Rate and Review box at the end of each tutorial and on the Creator interest aliases.

Chris: We just published two new tutorials, Delving Into Components and Using the File Upload Component.

Gail: We've collected a lot of statistics on the tutorials so we can determine what is important to you. Using an AJAX Text Completion Component is currently our most popular tutorial. Developing a Portlet Application and Performing Inserts, Updates, and Deletes are also very popular. Our tutorials have been viewed in more than 127 countries.

Chris: I'm working on a tutorial on how to use the Table Component. I posted a forum topic asking what you want to see in this tutorial. If there is something that you want me to cover, please post to that thread. Here's a tip that's coming up in one of our tutorials.

How to Dynamically Turn Off a Column's Sort Button:

To turn off a column's sort button at runtime, set the column's sort property to null, like this:
tableColumn1.setSort(null);
To turn it back on, set the sort property to the FieldKey id or the SortCriteria used to define criteria for sorting. That is, whatever the value of the sort property is at design time when the column's sort button is enabled. For example:
tableColumn1.setSort("TRIPTYPE.TRIPTYPEID");
When you enable sorting on more than one column, you should add a Clear Sort Button to the table. Right-click the table and choose Table Layout from the pop-up menu. Click the Options tab and select Show Clear Sort Button.

Gail: We try to keep the tutorials up-to-date as much as possible, and my main focus right now is to get the tutorials ready for the next release of Creator. I'm also working on a tutorial on how to use the Calendar component.

Chris: I enjoy corresponding with customers, so please feel free to provide us feedback on the tutorials. We are always looking for ways to improve the existing tutorials and suggestions for new topics. You can send us email at CreatorDocsFeedback@Sun.Com. You can also use the Rate and Review box at the end of each tutorial. If you submit questions, please don't forget to give your email address so that we can send you a reply.

Gail: You might hear from me as well, but Chris is more active with customers. I do a lot of behind-the-scenes work, such as coordinating engineering support and prioritizing your tutorial requests.

Chris: My writing passion is equal to my passion for new technology. One of the best parts about working on Sun Java Studio Creator is that I get to work with top-notch engineers who are cranking out bleeding edge stuff -- and I get to play with with the latest and greatest. My main passions are Hawaii, golf, and photography, which go perfectly well together. I am looking forward to my next snow-bird stint in Hawaii because the temperatures where I live are hitting the low 30s (farenheit).

Gail: Family is my first passion, writing is my second passion, and traveling is my third. At one time, my goal was to be a foreign correspondent, but that was before marriage and children. For now, I'm happy writing tutorials and traveling around the United States with my family. My new goal is to visit all 50 states-- so far I've been to 36 states. Hopefully someday I'll make it to Hawaii, which is one of Chris' favorite places to visit.

Chris: In 2007 I started playing the Photo Hunters game where I try to post a photo for each theme of the week. Here is the blog roll of all the players.

<script language="javascript" type="text/javascript" src="http://rpc.blogrolling.com/display.php?r=df9a721099dd884c6817b640d698b551"></script>
About

divas

Search

Categories
Archives
« July 2014
SunMonTueWedThuFriSat
  
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
  
       
Today