Programmer's Guide



Chapter 11   Advanced Page Topics

This chapter covers the following advanced page topics:

Adding applets   Top of page

HTML pages can embed Java applets. Java applets allow you to enhance your Web pages with graphical and interactive features that would be difficult or impossible to implement in pure HTML. Many newer browsers support Java applets.

Java applets are usually available in CAB files or JAR files. To use applets in the SilverStream environment, you must first install the files into the Media Store area of the SilverStream Designer.

Choose the Applet toolbar icon to drop an applet into the Page Designer. After you drop the applet, you will see a gray rectangle. Fill out its properties in the Property Inspector. At a minimum, you must specify the following properties.

In addition, you might need to set the applet's parameters. You can do this by clicking on the Edit HTML button in the Property Inspector and adding <PARAM> tags to the applet's HTML. Refer to your applet provider for documentation about its parameters.

Both CAB files and JAR files can be signed. Refer to the Microsoft Web site (www.microsoft.com) for more information on CAB file signing. Refer to the JavaSoft Web site (www.javasoft.com) for more information on JAR file signing.

You can make an applet programmable by giving it a name and checking the Programmable checkbox. This allows you to control some aspects of the applet from the Java code for the page. You can also access applets in JavaScript code.

Adding ActiveX objects   Top of page

HTML pages can embed ActiveX objects. ActiveX objects are compiled binaries and are platform-dependent.

ActiveX objects are available in CAB files. They are installed and used similarly to applets. See the previous section "Adding Applets" for instructions. You must specify a Class ID. Consult your ActiveX provider for the ClassID or CLSID information. You may also need to set its parameters by clicking on the Edit HTML button in the Property Inspector.

CAB files can be signed. Refer to the Microsoft Web site (www.microsoft.com) for more information on CAB file signing.

You can make an ActiveX object programmable by giving it a name and checking the Programmable checkbox. This allows you to control some aspects of the ActiveX object from the Java code for the page. You can also access ActiveX objects in JavaScript code.

Adding plug-ins   Top of page

Plug-ins represent an older way of enhancing HTML. You typically use plug-ins to specify viewers for special media types.

Unlike ActiveX objects and Java applets, most plug-ins need separate installation. It is common to place a text link on the page so that the user knows where to get the plug-in.

You can place the media that the plug-in uses into the Media Store area of the SilverStream Designer. Specify the location of the media through the Property Inspector. For example, to play an MP3 movie on your page, you would use an MP3 plug-in on the page, and store the .MP3 file movie file in the Media Store.

Specifying additional HTML   Top of page

If you are familiar with HTML, you may want to include arbitrary HTML code on a page. You can specify additional HTML in a number of ways. For most applications, you simply place an HTML data control (or a label control) on the page, and set its value to be the desired HTML.

You can also insert extra HTML information for a particular control using advanced properties, such as Body Attributes, Edit HTML, Extended Attributes, and through tags and style sheets. Experienced page designers may also want to add their own HTML tags by using the Insert Raw HTML toolbar icon, or use Raw HTML mode to edit the page.

You can also create a custom page control or inherit from one of the built-in controls to specify additional HTML.

Setting tags and attributes   Top of page

Many HTML tags have attributes that allow you to specify more information about the tag. Attributes often control the appearance of the control. An attribute consists of a name, an equals sign, and a value. For example, the following attributes set the amount of spacing in a table, hide the border, and make the table width fill the page.

  <TABLE CELLSPACING=0 CELLPADDING=0 BORDER=0 WIDTH=100%> 

Many of the properties of a SilverStream page control correspond directly to HTML attributes. By setting a property value for a control in the Property Inspector, you can indirectly modify the corresponding HTML attribute. In addition, you can click on the Extended Attributes button and the Edit HTML button, when shown in the Property Inspector, to open a window where you can type more information about the HTML tag.

You can change attributes that are not available through the Property Inspector by setting them programmatically. Attributes not available in the Property Inspector are typically browser-specific. For example, the READONLY attribute for text fields in MS Internet Explorer and the WRAP attribute for text areas in Netscape do not appear in the Property Inspector. The following steps illustrate how to access attributes programmatically.

  1. Give the control a name and check the Programmable checkbox.

  2. To get the value of an attribute at runtime, call the getProperty() method on the control, using the attribute name as the parameter. For non-String data types, you can also use the method that corresponds to the data type you are retrieving. For example, you could use getBoolProperty() to retrieve a Boolean value.

  3. To set the value of an attribute at runtime, call the setProperty() method and provide the attribute name and its value. For non-String data types, you can also use the method that corresponds to the data type you are setting. For example:

      Field1.setBoolProperty("READONLY", true); 

Changing the edit mode   Top of page

The Page Designer supports two editing modes. You can edit in What You See is What You Get (WYSIWYG) mode or Raw HTML mode. To switch between them at any time, click on the radio buttons at the bottom of the Page Designer.

Keep in mind that the Undo buffer clears when you switch from one mode to another.

Working in WYSIWYG mode

The Page Designer defaults to the WYSIWYG mode. In this mode, you can see and manipulate the content and controls visually as objects on the screen.

Working in Raw HTML mode

The Raw HTML mode provides a text interface for editing the page. You can copy and paste HTML code into the Page Designer in this mode.

Those who are familiar with HTML can use this mode to access HTML tags or attributes in tags that the WYSIWYG user interface does not expose. Use it only if you are very comfortable with HTML and have a clear understanding of how SilverStream is using HTML internally.

The Raw HTML mode only provides access to the underlying HTML. In this mode, you cannot change properties of the page itself or edit Java code.

When you switch back from Raw HTML mode to WYSIWYG mode, the Page Designer attempts to preserve the changes you made while in Raw HTML mode. The WYSIWYG mode needs to translate the newly typed HTML into its internal representation, so it might modify the tags that it needs. Specifically:

NOTE   Do not attempt to add, modify, or delete the <AGCONTROL...> tags that correspond to SilverStream page controls in Raw HTML mode. These tags are placeholders for specialized processing, and modifying them will break the page.

Formatting text   Top of page

In addition to formatting text directly in the Page Designer and Property Inspector, you can also specify style sheets to customize a page format, and you can programmatically change marked areas of text at runtime.

Using style sheets   Top of page

A style sheet provides declarative rules to customize a page format. You can define named text and paragraph styles and refer to them in the text of pages. That way, you only need to change the style sheets to affect multiple paragraphs or text blocks. Later browser versions support style sheets.

A style sheet might affect properties such as the default font, paragraph spacing, and margins.

You must define style sheets at the topmost page to avoid possible naming conflicts with controls on subpages.

You can define embedded style sheets in the SilverStream Page Designer. To add an embedded style sheet to a page, open the Property Inspector, select the Page tab, and click on the Style Sheet button in the Scripting section. SilverStream displays the Style Sheet editor window. You can begin defining styles for HTML tags in the editor window. For example, the following style sheet description sets the font face to be either Arial or Sans Serif, depending on which one is available on the user's system. The text color is set to red:

  H1 {font-family: Arial, Sans Serif; color: red} 

At runtime, the style sheet information is placed between the <STYLE> and </STYLE> tags inside the <HEAD> section of the page:

  <HEAD> 
<STYLE TYPE="text/css"><!--
H1 {font-family: Arial, Impact, Sans Serif; color: red}
-->
</STYLE>
...
...
</HEAD>

Changing text properties programmatically   Top of page

You can change the style of a particular piece of text dynamically by treating that text as a programmable object. Treating text programmatically works similarly to other programmable objects.

  1. Select a range of text.

  2. Give the selected text a name and check the Programmable checkbox.

  3. The text object appears in the Programming Editor.

Now you can set the properties of this text at runtime.

Adding JavaScript to a page   Top of page

JavaScript is a scripting language that works in the browser. Sometimes it is confused with Java, but it is quite different. JavaScript operates only in the browser. It does not communicate with the server, but it can communicate with Java applets.

The 4.0 versions of Netscape and MS Internet Explorer support JavaScript. JavaScript is usable in earlier versions, such as Netscape 3.0 and MS Internet Explorer 3.02, but these versions differ significantly from the 4.0 versions.

There are several ways JavaScript can enhance pages:

JavaScript can validate data without accessing the server. Thus, using JavaScript can speed up interaction and improve the visual appearance of your application.

There are some limitations of JavaScript.

JavaScript is case-sensitive. It has very simple variables of only one data type. A variable can be an integer, a string, or a character. JavaScript has its own set of functions. Some examples are alert(), confirm(), and prompt(). You can also create your own JavaScript functions.

SilverStream support for JavaScript   Top of page

SilverStream supports the ECMA standard JavaScript 1.1. If the server detects that the browser is not JavaScript 1.1-compatible, it will treat the browser as a non-JavaScript browser. In that case, any JavaScript-specific code, including user-written JavaScript and methods invoked on agScriptHelper, will have no effect.

In order to enhance the JavaScript programming model and make it similar to Java programming, SilverStream introduces methods, which are common to many programming languages but absent in JavaScript. When you write an event handler for a control in JavaScript in SilverStream, you write it as a method on the page object. The JavaScript is then added to the header of the generated HTML page.

To be sure that your JavaScript is added to the page, you need to add the JavaScript after SilverStream has begun generating HTML for the page (after the pageRequestBegin event fires), but before the HTML generation process is complete (before the pageRequestEnd event fires). The pageGenerateBegin event is the last opportunity you have to add JavaScript to the page.

If you create JavaScript in a page or page control event, either by using the agScriptHelper object or by calling writeScript(), keep in mind that the event must actually fire before the JavaScript will be sent to the browser. If the event is not fired, the JavaScript will not be included in the generated HTML page. Furthermore, if you redirect the browser to a different page by calling showPage(), any JavaScript you added to the page before calling showPage() is not sent to the browser.

SilverStream can generate certain animated navigation buttons for ECMA JavaScript-enabled browsers. In other browsers, SilverStream substitutes a static clickable button. The static buttons have the same functionality as the animated buttons.

Writing JavaScript functions in SilverStream   Top of page

To write a JavaScript event handler, first select the object for which you want to write code. Right-click the control and select JavaScript, then select from the available methods. When you select a method, the JavaScript editor opens and the cursor appears in the corresponding method. You can also bring up the JavaScript editor window by opening the Property Inspector, selecting the Page tab, and clicking on the JavaScript button.

The JavaScript editor displays an area for coding methods that will become JavaScript functions. You will see methods for different controls combined in the same editor window.

As in the Java programming environment, all the controls are member variables of the page object. This means you can change the value of another control by referencing it and setting it to the new value. For example:

  method handle_Button1_onclick() 
{
   this.TextField1.value = "Changed Value";
}

In the example, Button1 is the button name, and TextField1 is the control being changed. The method sets its text to a new string.

NOTE   When you refer to other controls in JavaScript from the Page Designer, you must add this. in front of the control name. This syntax differs from adding document.parent. as you might otherwise do in JavaScript, and it differs from just using the control name as you would in Java.

You can also write custom methods and functions in the JavaScript editor. Methods belong to the page object, whereas functions have a global scope. You invoke them differently. For example:

  method someMethod() 
{
   this.Button1.value = "Changed Value";
}
function someFunction()
{
   alert("Value changed");
}
method handle_Button1_onclick()
{
   this.someMethod();
   someFunction();
}

You can also include JavaScript in your application by calling the writeScript() method from the page's Java code. For example:

  writeScript("alert(\"Please enter a number.\")"); 

This method takes one parameter, which is a string of JavaScript code. Type a backslash before quotes that are to be passed to JavaScript. JavaScript that you add this way is executed as soon as the browser displays the page.

Accessing SilverStream elements from JavaScript   Top of page

SilverStream renames all of the JavaScript method names dynamically. If you write JavaScript on a subpage using methods only, you will not run into any name conflicts with the parent page.

You can invoke subpage methods from the parent page. For example:

  this.Subpage1.someMethod(); 

Functions are not renamed. They have global scope. This allows you to define nonmember helper functions in a subpage and call them from the parent page.

Using JavaScript to bring up dialogs and perform special tasks   Top of page

Following are some JavaScript examples. You may also want to examine the source for the help system files, since they implement many JavaScript techniques.

Bringing up message dialogs

Three common JavaScript message dialogs are the alert, confirm, and prompt dialogs.

The alert() function brings up a message dialog with an OK button.

  method handle_Button1_onclick() 
{
   alert("Welcome to our page!");
}

The confirm() function brings up a message dialog with OK and Cancel buttons.

  method handle_Button1_onclick() 
{
   var b = confirm("Are you sure?");
}

The prompt() function brings up a message dialog and prompts the user for text input, with a default reply string.

  method handle_Button1_onclick() 
{
   var userID = prompt("Please enter your ID", "0");
}

Sending a conditional submit

In some cases, you can use JavaScript to minimize trips to the server. For example, you can bring up a confirmation prompt before submitting the page to the server. If the user cancels the operation, the browser does not send a request. The following steps describe how to make a submit conditional.

  1. Change the button's type on the Property Inspector from Submit to Button. This causes it to generate a JavaScript event without submitting a request to the server.

  2. In the JavaScript code for the button's onClick() event, prompt the user to confirm the request. If the user clicks on OK, use the JavaScript submit() call to submit the page to the server. This is an example of a Delete button confirmation.

      if (confirm ("Are you sure you want to delete this?")) 
    {
       Page.submit(this.Delete.name);
    }

    In this example, Delete is the name of the button. You do not replace this and name in the code.

This approach would also work for validating data before sending it to the server.

    See the help system for sample code implementing a conditional submit.

Clearing credentials with JavaScript

SilverStream relies on cookies to track sessions. A cookie is a piece of information sent by a Web server to a Web browser, which the browser then saves and sends back to the server for all additional requests to the server. When the server receives a request from a browser that includes a cookie, the server uses the information stored in the cookie to connect back to the session.

It might be necessary to explicitly set a cookie to null so that credentials are no longer remembered. You can do this with JavaScript.

Controlling browser history   Top of page

SilverStream implements a history fixup mechanism that makes the browser treat each POST to a page as part of the original history entry.

Without the history fixup, each POST to the same page would result in a new history entry in the browser. Since a page cannot display a previous version of its dynamically generated HTML, an error occurs if the user clicks on the Back button in the browser.

With the history fixup enabled, the Back button in the browser goes back to the page that the user previously requested.

The history fixup mechanism uses JavaScript. History fixup is enabled by default. You can turn it off by calling setEnableHistoryFixup() with false as the parameter.

Transferring files   Top of page

A file attachment control allows the user to upload files from the browser to the server. The user can browse for a file, and the control triggers an event for which you can write code.

To download files from the server to the browser, you can add links to your page that point to files stored in the Media Store. For downloading files that are not stored in the Media Store, you can write a servlet page control.

Uploading files   Top of page

The file attachment control appears in the browser as a text field together with a browser button that opens a file selection dialog. The user can select a file and upload it as binary data to the server.

When the user specifies a file in the file attachment control, the server receives the file when a submit occurs. Thus, you will also have to provide a control that causes a submit, such as a submit button. The file attachment control on the server fires the fileUploaded event. This event contains the filename (using the original path), the content type, and the content as a binary array. You must determine what to do with the binary stream at that point.

In the following example of uploading a file, the user browses and selects a file, clicks on a button, and the file's contents are displayed in an HTML data control. The file attachment control's fileUploaded event code is:

  // create a byte array to hold the contents 
byte binary_content[] = evt.getContent();
// open an input stream
ByteArrayInputStream binary_stream =
   new ByteArrayInputStream(binary_content);
InputStreamReader reader =
   new InputStreamReader(binary_stream);
// write the contents to the HTML Data control
PrintWriter writer = HTMLControl1.openValueWriter();
try
{
   int c = reader.read();
   while (c != -1)
   {
      writer.write((char) c);
      c = reader.read();
   }
}
catch (Exception e)
{
   System.out.println("could not read file");
}
// finished writing to the HTML Data control
HTMLControl1.closeValueWriter();

    See the help system for information about the related methods getOriginalPath() and getContentType().

Downloading files   Top of page

If you want to support downloading files, simply put them in the Media Store and make links to them in the pages. When the user clicks on the link, the browser downloads the file.

However, you might have files that do not reside in the Media Store. For example, you might have files stored in a database table column. In this case, you have to access the data and write a custom control that generates the appropriate HTML link. To do this, you write a servlet page control.

A servlet page control is both a page control and a servlet. As a page control, you can drop it onto a page and generate HTML dynamically. The HTML it generates points back to the servlet. The servlet implementation then serves the file.

You can quickly implement a simple servlet page control. See the section "Using Custom Page Controls" for more information.

Implementing interfaces on a page   Top of page

A page that you create in the Page Designer can implement an interface that was created in the Business Object Designer. By implementing an interface, a page can conform to a standard protocol that allows for easy interaction with other pages. For example, if several subpages implement the same interface, a parent page that contains these subpages can send messages to the subpages by calling methods associated with the interface.

To implement an interface on a page:

  1. Open the Programming Editor.

  2. Choose File Java Interfaces from the menu.

  3. Click the Add button.

  4. Type the name of the interface you want to implement.

  5. If you want SilverStream to create a stub for the interface methods, select the Create Stubs for Method Interfaces checkbox.

  6. Click OK to close the Add Interface dialog box.

  7. Click OK to close the Java Interfaces dialog box.

  8. In the Programming Editor, code the implementation for each method associated with the interface.

    If you select the Create Stubs for Method Interfaces checkbox on the Add Interface dialog box, SilverStream adds each interface method to the list of methods in the General section for the page in the Programming Editor. If you do not select the Create Stubs for Method Interfaces checkbox, you need to define the method in the Declarations block in the General section for the page.

Using custom page controls   Top of page

You can extend the Page Designer through custom page controls. Custom page controls provide functionality that is otherwise not available (for example, a calendar control). They are JavaBeans that implement one or more interfaces defined by SilverStream. They have methods, properties, and events. Like the other controls built into the Page Designer, they emit HTML dynamically. Custom controls can also generate JavaScript by implementing the AgiJavaScriptEnabled interface.

In the SilverStream environment, you can use the Business Object Designer to create custom page controls. Alternatively, you can create custom page controls outside of the SilverStream environment. If you create a custom page control outside SilverStream, you need to add SilverServerAll.zip to your CLASSPATH environment variable to allow the compiler to find the SilverStream classes your JavaBean uses. SilverServerAll.zip is located in the lib subdirectory of the SilverStream installation directory.

You can create a custom control with a class that extends AgpControlBase, or with a class that extends one of the built-in page controls (for example, AgpTextField). You can also create a custom control with a class that implements AgiPageControl.

Creating a brand new control   Top of page

As a minimum requirement to work in the SilverStream environment, all custom page controls must implement two interfaces: com.sssw.shr.page.AgiPageControl and java.io.Serializable. Although not required, SilverStream recommends that custom page controls inherit from AgpControlBase. The class AgpControlBase, together with its base class AgpTag, provides a convenient base implementation for serialization and HTML generation.

The following sections guide you through creating a simple page control that outputs "Hello World" in a browser.

Creating a package hierarchy

Decide on a package hierarchy for your page control class. Follow the standard Java package name convention. Thus, place your class under com.yourcompanyname.

  1. Go to the SilverStream Designer and select Objects.

  2. Browse to select the desired parent package.

  3. Choose the New icon and select New Package.

  4. Type in the package name and click OK.

Creating the class

Use the Business Object Designer to create a class in your package hierarchy that extends com.sssw.shr.page.AgpControlBase. The wizard can guide you through creating the class. Note that this is a base class that already implements AgiPageControl and Serializable.

  1. In the SilverStream Designer, select Objects and highlight the desired package.

  2. Choose the New icon and select New Object. The Business Object Wizard appears.

  3. Click on Next in the first dialog.

  4. In the second dialog, type a name in the Object Name field.

  5. In the same dialog, also type the class it extends in the Extends field, such as: com.sssw.shr.page.AgpControlBase

  6. Click on Next and then click on Finish. The Business Object Designer appears.

Coding the generateHTML() method

Write code in the Business Object Designer to let this control generate custom HTML, by overriding the generateHTML() method.

  1. Select whole-file view in the Programming Editor.

  2. Position the cursor at the end of the code, just inside the last closing brace.

  3. Type code for the generateHTML() method.

      public void generateHTML(String namespace, PrintWriter writer) 
       throws IOException, ServletException
    {
       // enter code here to generate HTML at runtime
       writer.write("Hello World");
    }
  4. Select Imports from the second dropdown list (with General still selected in the first dropdown list). Type in the packages to import.

      import java.io.*; 
    import javax.servlet.*;
  5. Save the object.

Assigning a version ID to the control

When Java recreates a serialized object in memory, it first tries to determine whether the associated class has changed in ways that make it incompatible with the object. This is what happens when you load a page in the Page Designer that has a custom page control. To ensure that changes you make to the class for a custom page control do not break existing pages that use the control, you can declare a static variable that assigns a unique version ID to the control. By doing this, you tell Java to use the version number you specify rather than a dynamically generated number that might conflict with the version numbers for particular instances of the control on existing pages.

To assign a version ID to your page control, you need to run the serialver utility that ships with the JavaSoft JDK.

  1. Add the bin directory for the JDK to your PATH environment variable (for example, C:\JDK1.2\bin).

  2. Add the appropriate compilecache classes directory to your CLASSPATH environment variable to allow serialver to find the class file for your JavaBean (for example, C:\SilverStream30\compilecache\localhost\TestDB\classes).

  3. Add the SilverServerAll.zip file to your CLASSPATH environment variable to allow serialver to find the SilverStream classes your JavaBean uses. SilverServerAll.zip is located in the Lib subdirectory of the SilverStream installation directory (for example, C:\SilverStream30\Lib\SilverServerAll.zip).

  4. In a DOS box, execute the following command.

      serialver -show 
  5. When the serialver window appears, type the name of your class, including the package prefix, in the Full Class Name field and click Show.

  6. Copy the entire output string from the Serial Version field and paste it into the source code for your class.

  7. Recompile your class.

Putting the page control into a JAR file

You have two options to prepare a JAR file for the Page Designer. You can either create the required Manifest file or allow SilverStream to build it. The following sections describe the specific steps for both approaches.

Creating the Manifest file

SilverStream recommends that you create the Manifest file and include it in the new JAR file. One advantage to creating the manifest file yourself is that you can later rebuild the JAR by simply right-clicking the JAR file and selecting the Rebuild option.

  1. In the SilverStream Designer, select EJB Jars & Media.

  2. Choose the New icon and select Create JAR.

  3. Expand the Objects section. Browse to your package and select Package contents. Click on the > button to also add it to the list on the right side.

  4. Open the Property Inspector for the JAR and check the Include Manifest checkbox.

    SilverStream adds a Manifest tab that has two modes: List View and Text View. You can go back and forth between modes. SilverStream will attempt to convert the entries in Text mode to the appropriate values in List Mode.

  5. Click on the Manifest tab.

  6. Choose the Text View radio button and type the entries as required by the manifest file specification. For example:

    Manifest-Version: 1.0

    Name: com/myPackage/MyCustomControl.class

    Java-Bean: True

    Replace myPackage with your package name and replace MyCustomControl with your object's class name, using a slash (or a period) to separate them. Also, make sure that the text editor saves the file without any extra extensions. For example, the filename should be Manifest.mf, not Manifest.mf.txt.

  7. Select File>Save from the JAR Designer menu.

  8. Give the JAR file a name and click OK. It appears in the list of files in the SilverStream Designer under Jars in the EJB JARs & Media. It is now ready to use in the Page Designer.

You can also create the Manifest file outside of SilverStream by using an ASCII text editor. In this case, you need to upload the file and include it separately when you create the JAR. Here are steps for doing this:

  1. Use a text editor to create a file named Manifest.mf in any directory. Type:

    Manifest-Version: 1.0

    Name: com/myPackage/MyCustomControl.class

    Java-Bean: True

    Replace myPackage with your package name and replace MyCustomControl with your object's class name, using a slash (or a period) to separate them. Also, make sure that the text editor saves the file without any extra extensions. For example, the filename should be Manifest.mf, not Manifest.mf.txt.

  2. In the SilverStream Designer, select EJB Jars & Media.

  3. Choose the New icon and select Upload Media Item.

  4. Browse to select the new Manifest.mf file. It appears under the General section of the SilverStream Designer.

  5. In the SilverStream Designer, select EJB Jars & Media.

  6. Choose the New icon and select Create JAR.

  7. Expand the EJB JARs & Media section in the JAR Designer. Under General, browse to select the Manifest.mf file. Click on the > button to add it to the list on the right side.

  8. In the same dialog, expand the Objects section. Browse to your package and select Package contents. Click on the > button to also add it to the list on the right side.

  9. Select File>Save from the JAR Designer menu.

  10. Give the JAR file a name and click OK. It appears in the list of files in the SilverStream Designer under Jars in the EJB JARs & Media. It is now ready to use in the Page Designer.

Letting SilverStream create the Manifest file

You can also have SilverStream create the manifest file. This approach involves creating the JAR, saving it to disk, then deleting and uploading it back again.

  1. In the SilverStream Designer, select EJB JARs & Media.

  2. Choose the New icon and select Create JAR.

  3. Expand the Objects section in the JAR Designer. Browse to your package and select Package contents. Click on the > button to add it to the list on the right side.

  4. Select File>Save from the JAR Designer menu.

  5. Give the JAR file a name and click on OK. It appears in the list of files in the SilverStream Designer under Jars in the EJB JARs & Media section.

  6. In the SilverStream Designer, select the new JAR file.

  7. Right-click the JAR file and select Save to disk. Type in a filename, such as c:\tempjar.jar.

  8. Select the JAR file in the SilverStream Designer and press Delete to remove it from the list.

  9. In the SilverStream Designer, select EJB JARs & Media.

  10. Choose the New icon and select Upload JAR, ZIP, or EJB.

  11. Type in the filename you used when you saved it to disk. The JAR file will again appear in the SilverStream Designer under Jars in the EJB JARs & Media section. It is now ready to use in the Page Designer.

Inheriting from a built-in control   Top of page

To create a custom control that inherits from a built-in page control, follow the procedure to create a brand new control. In the Business Object Designer, specify the class you want to extend, instead of extending AgpControlBase. The base class will provide an implementation of AgiPageControl.

Adding persistent properties to a custom control   Top of page

The base class AgpControlBase defines two methods, getProperty() and setProperty(), to make working with persistent properties easier. When you use these methods, you can save persistent information in your control without having to implement serialization. For example, you can add the following two methods to your page control class.

  public String getMyProp1() 
{
   return (String) getProperty("MyProp1");
}
public void setMyProp1(String myprop1)
{
   setProperty("MyProp1", myprop1);
}

Implementing these methods adds a property called "MyProp1" to the page control. The Page Designer will discover the property and make it available in the Property Inspector at design time.

Controls that derive from SilverStream controls (such as AgpTextField) are data bindable. Controls that derive AgpControlBase are also data bindable if they have a default property indicated in their BeanInfo. In this case, the default property becomes bindable. In both cases, SilverStream will perform introspection on the control to display its properties in the Property Inspector.

Java provides an alternative way to add persistent properties to a custom page control. Instead of calling the SilverStream getProperty() and setProperty() methods, you can add persistent properties to a page control by calling the read methods associated with the ObjectInput interface (for example, readInt() and readUTF()) and the write methods associated with the ObjectOutput interface (for example, writeInt and writeUTF). You call these methods in the implementation for the readExternal() and writeExternal() methods.

  String m_pattern; 

static final long serialVersionUID = 2111702466452921695L;

public void setPattern(String text)
{
   m_pattern = text;
}
public String getPattern()
{
   return m_pattern;
}
public void writeExternal(ObjectOutput out)
   throws IOException
{
   super.writeExternal(out);
   if (null==m_pattern) m_pattern = "/\\d{3}-\\d{3}-\\d{4}/";
   System.out.println("TextFieldEditMask (writeExternal).
      Pattern = " + m_pattern);
   out.writeUTF(m_pattern);
}
public void readExternal(ObjectInput in)
   throws IOException, ClassNotFoundException
{
   super.readExternal(in);
   m_pattern = in.readUTF();
}

Defining the design-time appearance of a custom control   Top of page

SilverStream allows you to define how a custom control will appear on a page in the Page Designer. If you do not specify the design-time appearance, the control will have a default appearance. The default appearance is a gray rectangle.

To define the design-time appearance of a custom control, you need to

  1. Create a utility class that extends AgpControlHTMLUnitBase in the same package as the custom control.

    The utility class must have the same name as the control, but have the suffix HTMLUnit. For example, if the class that defines a custom control is called CustomTextField, the name of the utility class that defines the design-time appearance of the control must be CustomTextFieldHTMLUnit.

  2. Select Imports from the second dropdown list (with General still selected in the first dropdown list). Add the following import statements.

      import java.awt.*; 
    import java.io.*;
    import com.sssw.rt.util.*;
    import com.sssw.shr.page.*;
  3. Provide an implementation for the layout() method.

    The layout() method lets you determine the dimensions of the text within the control. Here's a sample implementation:

      TextFieldEditMask tb = (TextFieldEditMask) getControl(); 
    String name = tb.getName();

    m_myWidth = getFontStyle().getTextWidth(name);
    m_myWidth += 44;

    m_myAscent = getFontStyle().getMaxAscent();
    m_myDescent = getFontStyle().getMaxDescent();

    if (m_myAscent < 36)
    m_myAscent = 36;

    This code presumes that you've defined three member variables, m_myWidth, m_myAscent, and m_myDescent, all of which are of type int.

  4. Provide an implementation for the getWidth() method. The getWidth() method lets you specify the width of the control:

      return m_myWidth; 
  5. Provide an implementation for the getAscent() method. The getAscent() method lets you specify the ascent for the control:

      return m_myAscent; 
  6. Provide an implementation for the getDescent() method. The getDescent() method lets you specify the descent for the control:

      return m_myDescent; 
  7. Provide an implementation for the draw() method.

    The draw() method lets you draw the image and text for the control. Here's a sample implementation:

      TextFieldEditMask tb = (TextFieldEditMask) getControl(); 
    g.setColor(Color.white);

    g.fillRect(0, 0, m_myWidth - 1 , m_myAscent + m_myDescent - 1);
    g.setColor(Color.blue);
    g.drawRect(0, 0, m_myWidth - 1 , m_myAscent + m_myDescent - 1);

    String name = tb.getName();
    getFontStyle().drawText(g, name, 40 , m_myAscent);

    if (m_image == null)
    {
       try
       {
          m_image=Toolkit.getDefaultToolkit().createImage
            (getImageData());
       }
       catch (Exception ff)
       {
          System.out.println("+ Error getting image: "+ff);
       }
    }
    if (m_image != null) g.drawImage(m_image, 4, 5, null);

    This example uses a user-defined method called getImageData() to load an image into a member variable called m_image, which is of type Image.

  8. Optionally provide an implementation for the resize() method.

    The resize() method lets you control what happens when the user resizes the control.

Installing a custom control   Top of page

Custom page controls are packaged in JAR files. To install a JAR file onto the server, use the SilverStream Designer to upload it to the Media Store area. This is the method for installing all types of JavaBeans. The server will determine what kind of JavaBean it is and manage it appropriately.

These are the steps to drop a custom page control onto a page.

  1. Position the cursor where you want to insert the control.

  2. Select the Media gallery in the Page Designer.

  3. Expand the JavaBeans section.

  4. You will see a combined list of all JavaBeans coming from all of the installed JARs on the server. Select one to drop it onto the page.

    If you created a JAR that contains a new page control while the Page Designer was already open, the new control may not appear in the Page Designer. In this case, you need to close the Page Designer and open it again.

Once you have added the page control to the page, you will see a rendition of the control in the Page Designer. You can inspect its properties in the Property Inspector and write code for it in the Programming Editor.

Binding custom controls to data   Top of page

You can bind custom page controls to data by calling the bind() method on the instance variable agDataMgr. See the online help system for a description of the parameters for this method.

Posting data from a page to a servlet   Top of page

Silverstream supports the Application Program Interface (API) for Java Servlet. Here are two scenarios that might require integrating a dynamically generated page with a servlet.

Defining servlet page controls   Top of page

Servlet page controls are page control JavaBeans that implement the javax.servlet.Servlet interface. You might create a servlet page control to serve up content other than the HTML it generates into the containing page. For example, a control that generates an image link into a page could also serve up the actual image binary data. By implementing the servlet interface, a page control can service an HTTP request to serve up the binary data for the image. An example is an image label control that serves up different employee photos coming from a database table.

The Page Designer environment can readily use servlet page controls. You can easily drop them onto a page. As page controls, they can define properties and methods that you can access programmatically from the page. They can also participate in data binding.

You might have servlet page controls that serve up executable binary. For example, you could write a page control that serves up an ActiveX control. This allows you to enhance the design time and programmatic features of your page controls.

You might also define servlet page controls that perform query processing and generate a different page. You can create links on the page with query parameters and have their URLs target the page controls.

An important feature of a servlet page control is that it generally causes HTTP GET requests to be sent back to the server. To support this, SilverStream assigns it a dynamic URL space. The dynamic URL space of a servlet page control relates to its dynamically assigned namespace. You can think of the page as a directory and the servlet page control as an item in the directory.

For example, a page named "myPage.html" has a page control with the dynamically assigned namespace "S3_". The dynamic URL space of the servlet page control would be "myPage.html/S3_". The URL might look like this:

  http://silverstream.exmpl.com/myDB/SilverStream/Pages/myPage.html/S3_ 

When the server receives a request targeted at a URL in the dynamic URL space, it asks the page control in the page "myPage.html" with the namespace "S3_" to service the HTTP request, by calling that control's service() method with the current request and response objects.

Understanding dynamic name assignment   Top of page

Whenever the input processor for a page is set to This Page (rather than Action URL) in the Property Inspector, SilverStream dynamically assigns unique names to controls when it generates HTML. These names differ from the names you use when working with the controls in the Page Designer and when coding in Java. This dynamic name assignment allows you to place one page inside another page, even if they both have controls with the same name. You need to know about these dynamic names only when you are creating a custom control.

By viewing the HTML source for the page in a browser, you can examine the dynamic name assignments. The assignments appear in the JavaScript section between <SCRIPT> and </SCRIPT>. A simple page containing a text field might have the following name assignment.

  Page.Field1=document.forms[0].elements["S5_"]; 

The <BODY> tag then creates the control using the new name.

  <INPUT NAME="S5_" TYPE="TEXT" SIZE="20"> 

In the example, the Field1 control is known as "S5_" to the browser.

This dynamic naming model handles the potential conflict when you place this page inside another page that also has a text field named Field1. The source in the browser for this example might have these name assignments.

  Page.Field1=document.forms[0].elements["S5_"]; 
Page.pgSubpage.Field1=document.forms[0].elements["S8_5_"];

The <BODY> tag then creates controls for the parent page and subpage using the new names.

  <INPUT NAME="S5_" TYPE="TEXT" SIZE="20"> 
<INPUT NAME="S8_5_" TYPE="TEXT" SIZE="20">

In the example, SilverStream assigned the name "S5_" to the parent page's Field1 control. The subpage now has a namespace of "S8_", which becomes a prefix to temporarily name the controls belonging to the subpage. The subpage's Field1 control now has the name "S8_5_".

Handling international characters in older browsers   Top of page

The AgpPage class provides several methods that let you handle international characters in older browsers:

If your data includes international characters and your user community works with the common older browsers (such Navigator 2.x or 3.x, or Internet Explorer 3.0), you need to call the setCharEncoding() method in the pageLoaded event for your page. For example, to set the character encoding scheme to Latin-1 (the character set for Western Europe), you would add this line of code:

  setCharEncoding("iso-8859-1"); 

The page, along with all form data, is sent from the server to the browser encoded in the character set you specify. Data is sent using the "multipart/form-data" MIME format, regardless of whether you have any file attachments.

If your data includes international characters and your user community works with a browser that does not support the "multiform/form-data" MIME format, you need to add the following lines of code to the pageLoaded event for the page:

  setCharEncoding("iso-8859-1"); 
setUseMultipartFormData(false);
setFormDataCharEncoding("iso-8859-1");

By default, the setCharEncoding() method turns on the use of the "multipart/form-data" format. Therefore, if you turn it off by calling setUseMultipartFormData(), you must inform the server of the character set in which the browser will send posted data. You do this by calling the setFormDataCharEncoding() method. In most cases, browsers post the data in the same character set that the server used to send the page, so the character encoding scheme specified in the setFormDataCharEncoding() method will typically be the same as the encoding scheme specified in the call to setCharEncoding().

Importing static HTML into SilverStream   Top of page

SilverStream supports two methods for importing static HTML pages:

NOTE   The SilverHelp3 database contains static HTML pages that were imported by using this latter method.






Copyright © 2000, SilverStream Software, Inc. All rights reserved.