RuntimeComponentCreation

Component Creation at Runtime

by Sapankumar Parikh


Introduction

Often programmers come across a situation where they have to create components on the fly (at run time). Components can be anything, from layout panels to command buttons to input components. One way to do this is to use the JSF table component which is simple to implement, but enforces adherence to the table component by taking away the freedom to come up with one's own layouts.

In this tutorial, we will create some components like command buttons and input text at run time. The main idea is to understand the process of creating components and their action events at run time.

This tutorial works with the following technologies and resources:

  • Tomcat Server 5.X
  • NetBeans IDE
  • Visual Web Pack

For any kind of JSF development, NetBeans comes as a natural choice because it not only lets you do basic things very easily, such as providing drag and drop, but it also empowers you to do advance things by directly going into JSP and Java code.

  1. Start with a new project and name it Tutorial.
  2. Drag and drop a GridPanel component from the palette and name it parentPanel, then drop a StaticText component and name it resultTxt as shown here.
  3. Now switch to the Java code of the page, find the method called getParentPanel() and add the following code to the method:
try{
            FacesContext context = FacesContext.getCurrentInstance();
            UIComponent parent = parentPanel;
            TextField text1 = new TextField();
            TextField text2 = new TextField();
            Button btn1 = new Button();
            Button btn2 = new Button();
            btn1.setId("mult");
            btn2.setId("add");
            btn1.setText("Multiply them");
            btn2.setText("Add them");
            Class[] parameterList = { Class.forName("javax.faces.event.ActionEvent")};
            MethodBinding mb = (MethodBinding) 	
            context.getApplication().createMethodBinding("#{Page1.operations}", parameterList);
	    btn1.setActionListener(mb);
            btn2.setActionListener(mb);
	    parent.getChildren().add(text1);	
            parent.getChildren().add(text2);	
            parent.getChildren().add(btn1);	
            parent.getChildren().add(btn2);	
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
Initially, some lines will be underlined red to indicate errors. Right click in the code editor and click on the fix import option. The IDE will give two options for choosing certain packages; select com.sun.rave.web.ui.component.TextField and com.sun.rave.web.ui.component.Button from the drop down lists.

The fundamental concept here is that like every other class UI components can also be initialized and instantiated in the code. These classes offer their own set of methods. In the code above, we are using three of them: setId, setActionListner and setText.

  • setId(String id) sets the UI component's id.
  • setText(String text) sets the text that will appear on the button.
  • setActionListner(mb) sets the method binding of that UI component.

In a nutshell, we are telling the compiler that whenever btn1 or btn2 are pressed, to call the operations method of Page1.

Finally, in last four lines we are adding these objects (which are actually UI components) to the parent component, the parentPanel.

We are ready to test run the project. You will see something like this, but the buttons will still not work. We have to make a method called operations to make these buttons work.


Add the following method to Page1's Java code.

 public void operations(ActionEvent ae){
        String operation = ae.getComponent().getId();
        if (operation.equals("mult")){
            int a = Integer.parseInt(((TextField)parentPanel.getChildren().get(0)).getText().toString());
            int b = Integer.parseInt(((TextField)parentPanel.getChildren().get(1)).getText().toString());
            resultTxt.setText(new Integer(a*b));
        }
        else{
            
            int a = Integer.parseInt(((TextField)parentPanel.getChildren().get(0)).getText().toString());
            int b = Integer.parseInt(((TextField)parentPanel.getChildren().get(1)).getText().toString());
            resultTxt.setText(new Integer(a+b));
        }
    }

In the very first line, we are trying to get the name of the component that called this method: ae.getComponent().getId(). The method returns the ID of the component, which can be “mult” or “add” depending on the name of the component performing the operation.

Inside the if loop, Integer.parseInt(((TextField)parentPanel.getChildren().get(0)).getText().toString()); gets the number from the text box and converts it into int. If we analyze this line in detail we can see that we are getting all the children of parentPanel and then retrieving the first component that was added to it and then getting the text that was typed in.

In if {...} , we are multiplying the values typed in both of the text boxes, and in else{...} we are adding them. These values are then displayed on the resultTxt component by using method resultTxt.setText(new Integer(a+b)).

Note that we are assuming in the above code that users will only enter numbers in the input component. To prevent users from entering other values we can use validators. An explanation of validators is beyond the scope of this tutorial.

At the end of this, we are ready to run the program. Try typing in numbers in both of the input boxes and click on either button. The result will be displayed in the static text box.

This kind of programming is very useful when designing dynamic forms, for example, several surveys or questionnaires for a job application. This kind of work needs extensive usage of runtime component creation because UI components in a questionnaire might change depending on the job type or application type.

Not logged in. Log in, Register

By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2012, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo