Retired Document
Important: This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid.
Freezing XML User Interfaces
You can use the tutorial project you created earlier in Enhancing the Application as the basis for the exercises in this chapter.
Freeze XML User Interfaces
Problem: You need more finely grained control over the user interface than the Direct to Java Client Assistant allows.
Solution: Use the XML generated by Assistant as a starting point, then edit it by hand to suit your needs.
Freezing XML is another way to customize Direct to Java Client applications. While Assistant allows you to make basic user interface customizations to your application, it is necessarily limited. Freezing XML, however, gives you finer control over your application’s user interface. With that said, you should use Assistant as much as you can since freezing XML makes your application more complex and less flexible than just using Assistant.
Freezing XML involves these steps:
making a new D2WComponent
copying an XML description from Assistant and editing it in the new component’s
.html
filewriting a rule to tell the rule system to use the XML component
Follow these steps to customize the user interface of the Admissions application using frozen XML:
In Project Builder, select the Web Components group, choose File > New File, and select Component from the WebObjects list, as shown in Figure 16-1. Do not select Display Group Component or Java Client Component.
Name the new component
StudentFormWindow
and make sure Application Server is the selected target, as shown in Figure 16-2.The recommend convention for naming frozen XML components is EntityNameTaskNameWindowType. So, if the entity in question is Student, and the task is query, the frozen XML component should be named
StudentQueryWindow
.Click Finish.
The Project Builder assistant for new component files creates a standard WebObjects component, so you need to change it to a D2WComponent. Add the import statement for
com.webobjects.directtoweb
and change the superclass ofStudentFormWindow
toD2WComponent
, as shown in Listing 16-1.Listing 16-1 Change the superclass of StudentFormWindow to D2WComponent
import com.webobjects.foundation.*;
import com.webobjects.appserver.*;
import com.webobjects.eocontrol.*;
import com.webobjects.eoaccess.*;
import com.webobjects.directtoweb.*;
public class StudentFormWindow extends D2WComponent {
public StudentFormWindow(WOContext context) {
super(context);
}
}
Build and run the application and start the client application.
Switch to the XML pane in Assistant.
Under Specification, choose entity > Student, question > window, and task > form. This puts the XML description for that selection in the XML window as shown in Figure 16-3.
Copy the whole XML specification and paste it into the
StudentFormWindow.html
file in Project Builder.StudentFormWindow.html
is in the StudentFormWindow component.In Project Builder, select the Resources group and choose File > New File and select Empty File. Name the file
d2w.d2wmodel
and make sure Application Server is the selected target, as shown in Figure 16-4. This file will hold custom rules you write. Skip this step if your project already has ad2w.d2wmodel
file.You need to have a
d2w.d2wmodel
file for a few reasons. First, Assistant stores its rules in theuser.d2wmodel
file and writes out this file whenever it saves. So, any rules you add or change manually in theuser.d2wmodel
file is wiped out by Assistant.By writing rules in a separate file, you can maintain a custom set of rules and still use Assistant for basic customizations. At runtime, all the
user.d2wmodel
files in the frameworks and all thed2w.d2wmodel
files in your project and in your project’s frameworks are merged, so the rule system picks up your custom rules and the rules you specified with Assistant, along with all the default rules.Put the Rule Editor application (found in
/Developer/Applications/
) in the Dock. Drag thed2w.d2wmodel
file to the Rule Editor icon in the Dock to open it.Click New to make a new rule and add these arguments to the left-hand side:
(task = 'form') and (entity.name = 'Student')
.Collectively, the left-hand side arguments constitute the rule’s condition. If the condition exists (that is, the user or application performs some action that triggers the condition), the rule fires and the right-hand side of the rule is evaluated.
In this case, if the form task is triggered (usually by a user action) on the Student entity, the condition of this rule is
true
, so the rule fires. Collectively, the left-hand side arguments ask “how should this part of the application behave?” And since the condition has been triggered, the behavior of this part of the application is changed per the right-hand side arguments.As described in Task Pop-Up Menu, Direct to Java Client applications have four basic tasks: query, form, list, and identify. (The rule system defines other tasks with which you usually do not need to interact). In this step, specifying
task = 'form'
tells the rule system that this rule pertains to the form task. By specifying the entity withentity.name = 'Student'
, the rule system knows that this rule pertains to the form task for the Student entity. However, if you want to use the frozen XML window for the query task, you would instead specifytask = 'query'
.Set the right-hand side key to
window
and the value toStudentFormWindow
. Set the priority to 50. Refer to Figure 16-5 for clarity. For an explanation of rule system priorities, see Rule System Priorities.The right-hand side arguments constitute the answer to the question posed in the left-hand side arguments. The answer is made up of a key and a value for that key. In this case, the key is
window
and the value isStudentFormWindow
. So in this case, the answer is “use the StudentFormWindow as the window for form tasks for the Student entity.”For high-level questions like
controller
,window
, andmodalDialog
, the rule system expects the value to be the name of a D2WComponent, like StudentFormWindow or any of the default D2WComponent classes defined incom.webobjects.eogeneration.*;
(see/System/Library/Frameworks/JavaEOGeneration.framework/Resources/
).Save the
.d2wmodel
file.
Customize the XML
Now that you’ve successfully frozen XML, you need to customize it to see any benefit. The default Student form window generated by the EOGeneration framework isn’t too bad, but you might want to group Student’s attributes in a box controller for a cleaner look. Assistant doesn’t give you this level of control of the user interface, so you need to edit the XML by hand.
If you closely examine the XML, you’ll notice that the widgets are organized in a hierarchy of controllers. The window is defined by a FRAMECONTROLLER
tag, the action buttons by an ACTIONSBUTTONCONTROLLER
tag, the form elements by a FORMCONTROLLER
tag, and the components of the form by COMPONENTCONTROLLER
tags. You’ll notice that the COMPONENTCONTROLLER
tag for the form that contains the attributes of the Student entity includes two nested COMPONENTCONTROLLER
tags. You can group Student’s attributes into a box by adding a BOXCONTROLLER
tag between Student’s outermost COMPONENTCONTROLLER
tag and its first inner COMPONENTCONTROLLER
tag. Add a BOXCONTROLLER
tag with the following XML (also see code line 1 in Listing 16-2):
<BOXCONTROLLER usesTitleBorder="false" highlight="true" |
border="RaisedBezel"> |
The beginning of the StudentFormWindow.html
file should look like Listing 16-2. Make sure to also add a closing tag for the box controller </BOXCONTROLLER>
before the closing tag of Student’s outermost COMPONENTCONTROLLER
tag, as shown in code line 2 in Listing 16-2.
Listing 16-2 StudentFormWindow.html
(frozen XML)
<FRAMECONTROLLER disposeIfDeactivated="true" typeName="question = window, task = form, |
entity = Student" reuseMode="NeverReuse"> |
<ACTIONBUTTONSCONTROLLER widgetPosition="Top"> |
<FORMCONTROLLER className="admissions.client.CustomFormController" |
alignsComponents="true" entity="Student" minimumWidth="256"> |
<COMPONENTCONTROLLER minimumWidth="256" usesHorizontalLayout="true" |
alignsComponents="true"> |
<BOXCONTROLLER usesTitleBorder="false" highlight="true"// 1 |
border="RaisedBezel">// 2 |
<COMPONENTCONTROLLER minimumWidth="256" alignsComponents="true"> |
<TEXTFIELDCONTROLLER valueKey="name"/> |
<TEXTFIELDCONTROLLER |
formatClass="com.webobjects.foundation.NSNumberFormatter" |
formatPattern="0;-0" valueKey="act"/> |
<TEXTFIELDCONTROLLER |
formatClass="com.webobjects.foundation.NSTimestampFormatter" |
formatPattern="MM/dd/yyyy" valueKey="firstContact"/> |
</COMPONENTCONTROLLER> |
<COMPONENTCONTROLLER minimumWidth="256" alignsComponents="true"> |
<TEXTFIELDCONTROLLER |
formatClass="com.webobjects.foundation.NSNumberFormatter" |
label="GPA" formatPattern="#,##0.00;-#,##0.00" valueKey="gpa"/> |
<TEXTFIELDCONTROLLER |
formatClass="com.webobjects.foundation.NSNumberFormatter" formatPattern="0;-0" valueKey="sat"/> |
<TEXTFIELDCONTROLLER editability="Never" |
formatClass="com.webobjects.foundation.NSNumberFormatter" |
formatPattern="#,##0.00" valueKey="rating"/> |
</COMPONENTCONTROLLER> |
</BOXCONTROLLER>// 3 |
Figure 16-6 shows an example of a Student form window with the new BOXCONTROLLER
.
Adding Actions to Frozen XML
Problem: You need to add custom actions to a frozen XML component.
Solution: Specify an action method in a business logic class or write a custom controller class.
Edit XML by Hand
To add an action to a frozen XML component, you embed an ACTIONCONTROLLER
tag inside an ACTIONBUTTONSCONTROLLER
block (or elsewhere, depending on where you want the button) in a frozen XML file:
<ACTIONCONTROLLER label="Send Record Via Email" usesButton="false" usesAction="true" iconName="ActionIconOk" actionKey="sendRecordViaEmail"> |
</ACTIONCONTROLLER> |
Implement the custom action method in the client-side business logic class.
Using a Custom Controller Class in Frozen XML
You can also add actions to frozen XML components by using a custom controller class.
To do this, create an empty Java class file (File > New File, then select “Java class” in the Pure Java group) in Project Builder. Name the new file NewController
and add it to the Web Server target. Add the import statements and methods shown in the code listing here:
package businesslogic.client; |
import java.awt.event.*; |
import javax.swing.*; |
import com.webobjects.foundation.*; |
import com.webobjects.eoapplication.*; |
import com.webobjects.eogeneration.*; |
public class NewController extends EOController { |
public NewController(EOXMLUnarchiver unarchiver) { |
super(unarchiver); |
} |
protected NSArray defaultActions() { |
Icon icon = |
EOUserInterfaceParameters.localizedIcon("ActionIconInspect"); |
NSMutableArray actions = new NSMutableArray(); |
actions.addObject(EOAction.actionForControllerHierarchy("runInfoDialog", |
"Run Info Dialog", "Run Info Dialog", icon, null, null, 300, 50, false)); |
return EOAction.mergedActions(actions, super.defaultActions()); |
} |
public boolean canPerformActionNamed(String actionName) { |
return actionName.equals("sendRecordViaEmail") || |
super.canPerformActionNamed(actionName); |
} |
public void sendRecordViaEmail() { |
EODialogs.runInformationDialog("Hello World!", "Hello World!"); |
} |
} |
By overriding defaultActions
, you are adding to the actions that are displayed in the user interface by the ACTIONBUTTONSCONTROLLER
tags. See the API reference for EOApplication.defaultActions
for a description of the parameters.
Notice in the defaultActions
method that a custom icon is specified using EOUserInterfaceParameters.localizedIcon
. The method takes a string that is the name of an icon in the Web Server target. You should group all resources such as images in the Web Resources group in your project.
After writing the custom controller class, you must include it in a frozen XML component:
<CONTROLLER className="businesslogic.client.NewController"> |
Make sure to place it in the XML hierarchy within an ACTIONBUTTONSCONTROLLER
block.
The implementation of the action method in this example simply puts up a dialog as shown in Figure 16-7.
Copyright © 2002, 2005 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2005-08-11