112
CHAPTER 5
G
ENERATING
USER
INTERFACES
@out_file.write( process_container( node ) )                   
end         
}        
pop_context()         
@out_file.close()
print "#{file_name}\n"
end
private
def process_container( container )
process_template( container.attributes[ 'name' ], container )
end
def process_template( name, node )
context = push_context( node )                                    
template_full_name = "#{@templates_directory}/#{name}" 
begin
fh = File.new( template_full_name )                             
erb_script = fh.read                                            
fh.close()                                                      
rescue
raise "Could not read template #{name}"
end
begin
erb = ERb.new( erb_script )                                     
erb_result = erb.result( binding )                              
rescue => err
raise err #, "There was a problem interpreting template #{name}"
end
pop_context()                         
erb_result
end
def each_node()                                                      
current_node = get_current_node()
result = ""
nodes = current_node.elements
nodes.each() { |node|
text = ""
if ( node.name == "container" )
text = process_container( node )
else
text = process_template( node.name, node )
end
result += ERbStrIO.as_stdout { yield( node, text ) }
}
result
end
def process_nodes()             
result = ""
each_node() { |node, text|
Finds top-level 
containers and 
runs them
Pushes the node onto 
the context and gets 
the context stack
Gets the 
template
Runs the 
template
Pushes the node onto 
the context and gets 
the context stack
Iterates the interior node
y
Pops our node 
from the context
Prints the interior node
u
Change font size pdf document - Compress reduce PDF size in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
C# Code & .NET API to Compress & Decompress PDF Document
best pdf compressor; apple compress pdf
Change font size pdf document - VB.NET PDF File Compress Library: Compress reduce PDF size in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
VB.NET PDF Document Compression and Decompression Control SDK
best way to compress pdf files; pdf page size may not be reduced
CASE
STUDY
GENERATING
JSP
113
result += text
}
result
end
def build_context()
context = {}
@context_stack.each { |values|
values.each { |key,value|
context[ key ] = value;
}
}
context
end
def get_current_node()
@node_stack.last
end
def push_context( node )  
@node_stack.push( node )
values = {}
node.attributes.each() { |key,value|
values[ key ] = value;
}
@context_stack.push( values )
build_context()
end
def pop_context()        
@node_stack.pop
@context_stack.pop()
end
end
if ( ARGV[0] )
proc = UIBuilder.new()               
begin 
proc.process_file( ARGV[0] )       
rescue => problem
print "#{problem}\n"                                              
exit –1                                                           
end
exit 0
else
print "No input file specified\n"
exit -1
end
q
The out_file variable is the output file handle. output_file_name is the name
of the output file, and output_full_name is the full pathname of the output file.
Adds a level to 
the context
i
Removes a level 
from the context
o
Handles errors 
gracefully
Creates the UIBuilder object
Runs the definition file
C# PDF insert text Library: insert text into PDF content in C#.net
Powerful .NET PDF edit control allows modify existing scanned PDF text. Ability to change text font, color, size and location and output a new PDF document.
adjust size of pdf; change font size in pdf file
C# PDF Annotate Library: Draw, edit PDF annotation, markups in C#.
Able to edit and change PDF annotation properties such as font size or color. Abilities to draw markups on PDF document or stamp on PDF file.
best pdf compression tool; reduce pdf file size
114
CHAPTER 5
G
ENERATING
USER
INTERFACES
w
These two instance variables store the location of the output directory and the templates
directory. If you derive from this class, you can specify new locations for these values.
e
This code initializes the context stack. The context stack is an array of hash tables. As
context hashes are added, they are pushed onto the stack and then popped off as the
XML tag processing is completed.
r
node_stack holds an array of references to the all of the nodes before the current node.
t
process_file is the main entry point for this class. file_name contains the
name of the definition file. It is the job of process_file to read in the definition
file, run the templates, and store the output.
y
each_node is one of the methods that a container can use to deal with interior
nodes. each_node runs each interior node and passes the text back to the template.
The template can then wrap this text in some more HTML before going on to the next
interior node.
u
process_nodes processes each node in the container and returns the text of all the
nodes concatenated together.
i
push_context is called whenever you invoke a new field or container. It adds the
attributes of the new XML node as a new layer in the context. When you’ve finished
with the XML node, the layer is popped off by calling pop_context.
o
pop_context pops one layer off the context stack. 
Of course, the UIBuilder class is worthless without the set of templates that
build the output code. The first template section of the code covers the templates used
to build a query table.
First, we need to go back to the definition file that sets the requirements for our
query table:
<file name="table1.jsp" title="Edit Name">
<container name="table_page" bean="NameBean">      
<column title="First" name="first" field="first" />    
<column title="Middle" name="middle" field="middle" />    
<column title="Last" name="last" field="last" />    
</container>      
</file>
This XML doesn’t have any comments in it, but there is no reason it couldn’t. You
should treat definition files just like source code. They should include comments that
describe the purpose, the author, the revision history, and so forth. XML allows for this
using the <!-- --> comment standard.
The definition file shows us that we’ll use two templates: table_page and
column. The table_page is referenced by the container tag, and the column
template is referenced by the column tag. Remember that the design of this generator
C# PDF Sticky Note Library: add, delete, update PDF note in C#.net
Able to change font size in PDF comment box. Note is a necessary feature in PDF annotation, which bring users quick and efficient working with PDF Document.
change paper size in pdf; pdf form change font size
C# PDF Convert to Word SDK: Convert PDF to Word library in C#.net
target PDF document, keeps the elements (like images, tables and chats) of original PDF file and maintains the original text style (including font, size, color
.pdf printing in thumbnail size; change font size in pdf comment box
CASE
STUDY
GENERATING
JSP
115
specifies that anything that isn’t explicitly a “container” (excluding the file tag at
the top) is a template reference, wherein the name of the tag is actually the name of
the template. So the column tag becomes a reference to the column template.
Listing 5.2 contains the code for the table_page template. 
<jsp:useBean id="myBean" class="<%= context[ 'bean' ] %>" scope=request></
jsp:useBean>   
<html>
<head>
<title><%= context[ 'title' ] %></title>
</head>
<body>
<table>
<tr>
<% print each_node() { |node,text| %>                                  
<th><%= node.attributes[ 'title' ] %></th>                             
<% } %>                                                                
</tr>
% ResultSet result = myBean.query();
% while( result.next ) {
<tr>
<%= process_nodes() %>
</tr>
% }
</table>
</body>
</html>
q
The template uses the local context to specify the bean, in addition to setting the title
of the page.
w
The each_node iterator is used to build the header for the table. Then you use
process_nodes() to fill in the interior of the Java table iterator, which builds all of
the <tr> and <td> nodes of the table. 
The next template used in this example is the column template, shown here:
<td><%%= result.get<%= context['field'].capitalize %>() %%></td>
This is a simple template that creates a single JSP 
<td>
tag builder.
The capitalize method on Strings in Ruby uppercases the first character in
the string and lowercases the rest of the string. If your field has camel case characters
(e.g., myValue), be warned that capitalize may not give you the result you
expect. If you have this problem, you should write your own routine to handle your
case-sensitivity variants.
Listing 5.2 2 table_page
References 
the EJB beans
q
Builds the 
interior nodes
w
C# PDF Field Edit Library: insert, delete, update pdf form field
A best C#.NET PDF document SDK library for PDF form field Able to add text field to specified PDF file position in C# Support to change font size in PDF form.
pdf file size; pdf paper size
C# PDF: Use C# Code to Add Watermark to PDF Document
into your C#.NET class application, developers can easily add a transparent watermark with desired font color, size and position onto target PDF document page.
adjust pdf page size; change font size in pdf form
116
CHAPTER 5
G
ENERATING
USER
INTERFACES
The <%%= is the ERb method for specifying <%= in the output. The %%> sequence
creates %> in the output.
Now, here’s the output of the generator for the definition file:
<jsp:useBean id="myBean" class="NameBean" scope=request></jsp:useBean>
<html>
<head>
<title>Edit Name</title>
</head>
<body>
<table>
<tr>
<th>First</th>
<th>Middle</th>
<th>Last</th>
</tr>
% ResultSet result = myBean.query();
% while( result.next ) {
<tr>
<td><%= result.getFirst() %></td>
<td><%= result.getMiddle() %></td>
<td><%= result.getLast() %></td>
</tr>
% }
</table>
</body>
</html>
In the production code, you will likely need to add URL argument handling to the
templates so that the resulting JSP can send query parameters to the bean. Depending
on your application architecture, you could hard-code these parameters into different
types of page_templates, or you could migrate the URL parameters into the defi-
nition file and then have the page_template respond to those by generating the
URL-handling JSP.
Another goal of the generator is to build HTML forms. An example HTML form
definition is shown in listing 5.3. The edit_form template (listing 5.4) creates a
page of form controls. 
<file name="form1.jsp" title="Edit Name">
<container name="edit_form" bean="NameBean">      
<edit name="first" field="first" />    
<edit name="middle" field="middle" />    
<edit name="last" field="last" />            
</container>      
</file>
Listing 5.3 3 Form template code
Generate Barcodes in Web Image Viewer| Online Tutorials
Select "Generate" to process barcode generation; Change Barcode Properties. Select "Font" to choose human-readable text font style, color, size and effects;
best pdf compression; pdf file size limit
VB.NET Image: Visual Basic .NET Guide to Draw Text on Image in .
Please note that you can change some of the example, you can adjust the text font, font size, font type (regular LoadImage) Dim DrawFont As New Font("Arial", 16
change file size of pdf; adjust pdf size
CASE
STUDY
GENERATING
JSP
117
<jsp:useBean id="myBean" class="<%= context[ 'bean' ] %>" scope=request></
jsp:useBean>   
<html>
<head>
<title><%= context[ 'title' ] %></title>
</head>
<body>
<form action="<%= @output_file_name %>" method="post">           
<%= process_nodes() %> 
</form>
</body>
</html>
q
The template uses the context to get the bean and to set the title for the HTML page.
w
The template also uses the @output_file_name class member of the host
UIBuilder object. It can do this because the binding of the UIBuilder object is
sent to the ERb template. This binding includes the context hash, but it also
includes anything in the current scope of execution, such as member variables. If this
design does not suit you, one alternative would be to use specially named values in the
context for elements like the output filename. 
Now, here’s the code for the edit template:
<edit name="<%= context[ 'field' ] %>" value="<%% myBean.get<%= con-
text['field'].capitalize %>() %%>">
This simple template uses the context to build the HTML for the edit control and to
build the JSP that sets the value of the field at runtime.
The output of the JSP generator for this form definition should look like this:
<jsp:useBean id="myBean" class="NameBean" scope=request></jsp:useBean>
<html>
<head>
<title>Edit Name</title>
</head>
<body>
<form action="form1.jsp" method="post">
<edit name="first" value="<% myBean.getFirst() %>">
<edit name="middle" value="<% myBean.getMiddle() %>">
<edit name="last" value="<% myBean.getLast() %>">
</form>
</body>
</html>
Listing 5.4 4 edit_form 
References 
the EJB bean
q
Inserts interior 
form elements
w
118
CHAPTER 5
G
ENERATING
USER
INTERFACES
We deliberately simplified this example; in a production environment you will
need to include field validation, page-level security, and URL-handling code. 
For this generator, let’s use the system test utility (described in appendix B) with
the following definition file:
<ut kgdir="kg">
<test cmd="ruby uigen.rb definitions/form1.def" out="output/form1.jsp" />      
<test cmd="ruby uigen.rb definitions/form2.def" out="output/form2.jsp" />      
<test cmd="ruby uigen.rb definitions/table1.def" out="output/table1.jsp" /
     
</ut>
The first time you run the JSP generator, you want to create a set of known good out-
put. The known good output is a copy of the output that you certify as perfect. To
create the known good output, run the following:
ruby ../ut1/ut1.rb -m -f ut.def
ruby uigen.rb definitions/form1.def
definitions/form1.def
Known good kg/form1.jsp stored
ruby uigen.rb definitions/form2.def
definitions/form2.def
Known good kg/form2.jsp stored
ruby uigen.rb definitions/table1.def
definitions/table1.def
Known good kg/table1.jsp stored
Of course, you should inspect the known good output files to make sure they are really
“good.” Then you can make whatever modifications you like to the generator and rerun
the tests:
ruby ../ut1/ut1.rb -f ut.def
ruby uigen.rb definitions/form1.def
definitions/form1.def
ruby uigen.rb definitions/form2.def
definitions/form2.def
ruby uigen.rb definitions/table1.def
definitions/table1.def
No test failures
At this point you can be reasonably sure that, as long as your tests covered a reasonable
gamut of functionality, your system is still performing well after alterations.
T
ECHNIQUE
GENERATING
S
WING
DIALOG
BOXES
119
5.5
T
ECHNIQUE
GENERATING
S
WING
DIALOG
BOXES
Swing is a cross-platform UI class library built entirely in Java. The Swing class library
is intended for desktop application development and supports all of the modern inter-
action models, such as documents, modal and modeless dialog boxes, menus, and tool-
bars. Not only is Swing portable between all of the common operating systems, it also
emulates the look and feel of those platforms. An application written in Swing looks
as if it were written for its operating system directly. In this section, we'll discuss a
generator that builds a Swing-based UI.
5.5.1
Generator requirements
Swing implements dialog boxes as code; there is no resource file from which the Swing
library reads a dialog definition and creates controls. Building a dialog box involves
building a set of control objects, containers, and callbacks in Java code. As with most
interface toolkits, the business rules that drive the interface get lost in all of the con-
struction and maintenance minutiae. An ideal generator architecture allows you to
keep the business logic of the interface separate from its Swing implementation.
The details in a Swing dialog box can be divided into two groups. The first group
includes the relevant details for the business side: 
• A data source for getting and setting the data
• Fields
• Basic types of the fields (e.g.,  String, Integer)
• The layout of the fields
• Which fields are editable
• Which validations should be applied to each field
• Which cross-field validations are required
The next set of items provide the implementation details:
• Swing objects that represent each field
• The dialog class
• The constructor that builds the class and lays out the fields
• Event responders that listen for button presses
• Code that implements the field and cross-field validations
In a hand-coded dialog box, the items in both lists are mixed together in the imple-
mentation. The generator handles the implementation details and thus allows you to
concentrate on the business details.
We have to be realistic, however. A generator will not be able to handle all of the
edge cases in the user interface. Login pages are an example of edge case pages that are
120
CHAPTER 5
G
ENERATING
USER
INTERFACES
often custom built. This is because the logic for supporting the page, validating the
login information and privileges, and initiating the session is singular to the login page
alone. So generating this one-off page is inefficient. For that reason, we need to be able
to add custom code to the process so that we can override or extend the output of the
generator to handle edge cases.
Note that with the exception of the Java types in the business details and any cus-
tom edge case code, the business details are platform neutral. This lets you maintain
the portability of the business logic for the interface. If you decide to change plat-
forms, you can move the dialog boxes by mapping the Java types and porting the edge
case code. Even if the generated output isn’t a complete solution, you will still be fur-
ther along than if you had tried to port the Swing code directly.
5.5.2
Architectural recommendation
In this example, the business requirements tell you that you need to take the business
details and custom code as input and create the Java Swing code to manage the dialog
boxes. The block architecture for a Swing dialog generator, based on the tier generator
model, is shown in figure 5.10.
The generator reads the business details from an XML definition file. When custom
code is required, the definition files reference an external file that contains the required
Java code. The generator takes both of these inputs and merges them, using a reservoir
of templates, into Java implementation files.
The templates are fairly simple. First you have a framework template that builds
the basics of the dialog class. Then, there are control templates for building each of
the types of controls for each of the fields specified and for doing the validation of
those controls when processing the OK click.
Generator
DefinitionFiles
SwingJava
Dialog
Class
Table
Checkbox
Dropdown
CustomCodeFiles
Validations
Event
Handlers
BusinessLogic
DB
Figure 5.10 0 A generator that builds Swing classes 
T
ECHNIQUE
GENERATING
MFC 
DIALOG
BOXES
121
5.5.3
Processing flow 
The processing flow of the generator is as follows:
Reads and validates the definition XML files and stores the information in local
structures.
Checks for any custom code references. Reads in the code files and stores them in
the local structures.
Iterates the following steps over every dialog box defined in the XML file:
Initializes caches of code for the variable declarations and the methods.
Iterates over each field and performs the following steps:
Builds and caches the field definitions.
Builds the event handlers and adds to the methods cache.
Adds any custom per-field to the methods cache.
Handles any per-dialog custom code by adding the code to the methods cache.
Uses the Java Dialog Class template to create the implementation for the class.
This template should contain the class, the constructor, and the standard event
handlers. The variables and methods text from the field processing steps should
be merged into the output.
Stores the output of this template in the .java file with the correct name.
5.6
T
ECHNIQUE
GENERATING
MFC 
DIALOG
BOXES
The Microsoft Foundation Classes (MFC)  are a set of C++ classes that provide a wrap-
per around the Win32 API. To build a dialog box in MFC, you use the Resource Editor
provided with the Microsoft Visual C++ IDE. You then build the C++ class to handle
the dialog events using the Dialog Wizard. The Dialog Wizard creates classes, maps
controls to classes, and handles some rudimentary validations. This wizard follows the
mixed-code generation model by managing the C++ code within special comments. You
are free to override the default behavior by adding custom C++ outside the comments.
5.6.1
Generator requirements
So why write another generator if Microsoft already has developed one? There are some
drawbacks to the Dialog Wizard approach: 
• The business details of the dialog box are mixed in with the code that maintains
the state of the controls.
• The validations are fairly rudimentary, and there is no way to generate cross-
field validations.
Swing generator
Documents you may be interested
Documents you may be interested