November 23, 2014
Hot Topics:

An Improved Approach for Creating SVG/XML Code and SVG/XML DOM Nodes using Java

  • March 13, 2007
  • By Richard G. Baldwin
  • Send Email »
  • More Articles »

Java Programming Notes # 2214


Preface

General

This is the second lesson in a series designed to teach you how to write servlets to produce SVG code that will be rendered in graphic form by an SVG-compatible browser.

An SVG graphics library

In the previous lesson titled "Java JAXP, Creating graphics using Java and SVG" (see Resources) I taught you how write your own SVG graphics library to eliminate, or at least alleviate the requirement to write raw XML code or raw JAXP DOM code, making it possible for you to produce SVG output simply by making typical Java method calls.

At the end of the previous lesson, I promised that this lesson would teach you how to take what you learned in the previous lesson and apply it to the generation of XHTML files containing in-line SVG/XML code.  I also promised that this lesson would teach you how to apply that knowledge to the writing of servlets that produce XHTML output containing in-line SVG/XML code.  Upon further consideration, however, I decided to delay that material until the lesson following this one.

Upgrading the SVG graphics library

In this lesson, I will provide two more methods for the SVG graphics library that make it even easier to write servlets to produce SVG output.  The first method eliminates the frustration of dealing with the escape sequences required for the quotation marks that surround attribute values in XML.  The second method makes it possible to create a general node in the DOM tree being used to represent an SVG graphic.

Viewing tip

I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.  You may also find it useful to open a third browser window at the Resources section near the end of the document.  That will make it easy for you to open those resources when they are mentioned in the text.

Figures

  • Figure 1. Svg07 screen output.
  • Figure 2. Recommended usage of the makeElement method.
  • Figure 3. Graphic output from Svg08.
  • Figure 4. Recommended usage of the makeNode method.

Listings

Supplementary material

I recommend that you also study the other lessons in my extensive collection of online Java tutorials.  You will find a consolidated index at www.DickBaldwin.com.

General background information

According to the W3C

"SVG is a language for describing two-dimensional graphics in XML. SVG allows for three types of graphic objects: vector graphic shapes (e.g., paths consisting of straight lines and curves), images and text. Graphical objects can be grouped, styled, transformed and composited into previously rendered objects. The feature set includes nested transformations, clipping paths, alpha masks, filter effects and template objects."

Not easy reading

The Scalable Vector Graphics (SVG) 1.1 Specification is extensive.  Unfortunately, a person needs a fairly strong background in XML to be able to understand much of the information in the specification, thereby reducing the accessibility of that information to Java programmers who lack such a background in XML.

Will present in a more understandable form

While I don't claim to have expertise in XML, I do know enough about the topic that I can usually make sense of the material provided in the SVG specification.  One of my objectives for this series is to extract much of the important information from the specification and to present it in such a way as to make it accessible to Java programmers who lack a strong background in XML and who don't have the time available to gain that background knowledge.

The bottom line - great graphics in the browser

No experience with IE/SVG plug-in
Please note that because I am not a frequent user of Internet Explorer, I have not installed and tested the SVG plug-in for IE.  The sample programs in this series were tested using Firefox 1.5.  I have read, however, that IE can be made SVG compatible by installing the plug-in.
The bottom line is that Java programs can be written to produce XML output, which, when presented to an SVG rendering engine, (such as Firefox 1.5 or IE 6 with the SVG plug-in installed), will cause the display of graphic material in the following three categories:

  • Vector graphic shapes
  • Images
  • Text

As a practical matter, when combined with the use of servlets, this makes it possible to display graphic material in the client area of a web browser that competes favorably with the graphic material that can be displayed using the Java 2D API in desktop applications. 

Preview

Escape sequences for quotation marks
Actually, it isn't too difficult to write the code to create escape sequences for quotation marks surrounding XML attributes.  What I find difficult is to understand that code when I have to go back and make sense of it later.
The program named Svg07

Despite your best intentions, when you are writing Java programs that produce XML output, you must occasionally write an output statement that produces raw XML code, often in the form of a very complex XML element having multiple attributes.  One of the most frustrating things about writing Java code to create elements in XML (also XHTML and HTML) is having to deal with the escape sequences for the many required quotation marks that surround attribute values. 

The program named Svg07 demonstrates a method that I will add to my SVG graphics library, which can be used to easily create XML elements without having to deal with those escape sequences.  The elements produced by the method may or may not be empty, and may or may not have attributes.

The program named Svg08

The program named Svg08 uses a similar technique as Svg07 to deal with another issue that frequently surfaces when using Java to create SVG graphics.  This issue has to do with the accommodation of a very large number of possible attributes that can be applied to each node in the DOM tree.

My original SVG graphics library

The previous lesson (see Resources) presented a small proof-of-concept SVG graphics library that provided method calls for the creation of the following DOM tree nodes:

  • A simple element with no attributes.
  • A linear gradient element.
  • An ellipse.
  • A circle.

Once the DOM tree representing a particular graphic image has been created, it can easily be transformed into an output SVG file containing the XML code required for rendering the graphic using an SVG rendering engine such as Firefox 1.5.

An expanded SVG graphics library

The next lesson in this series will expand my SVG graphics library to provide method calls for all of the Basic Shapes in the SVG specification (see Resources), plus some other elements as well.  This will include the following basic shapes:

  • rect
  • circle
  • ellipse
  • line
  • polyline
  • polygon

Many attributes for each shape

When programming with raw SVG/XML code, there are a dozen or more attributes that can be applied to each shape when it is rendered.

A programmer calling a higher level method to create a shape, (such as an ellipse for example), would usually prefer not to have to routinely deal with more than a dozen attributes for each ellipse.  That programmer would probably prefer to routinely deal with only those attributes that are most likely to be different from one ellipse to the next.

Therefore, the methods in my SVG graphics library attempt to default most of the attributes and require the programmer to deal only with the attributes that are most likely to be different from one instance of the shape to the next.

Must provide a fallback position

Having taken that approach, however, it is necessary to provide the programmer with a method that can be used to create a shape dealing with all or any combination of the available attributes.  The program named Svg08 demonstrates an SVG graphics method that can be used to create a general DOM tree node having any name and any number of attributes with any attribute names and any String value for each attribute.  I will also add this method to my SVG graphics library to be used in the next and all subsequent lessons in this series.

This program produces an SVG file as its output.  The file can be rendered using Firefox 1.5.  Note, however, that the method is equally appropriate for use in producing XHTML output code, which I plan to explain in the next lesson.

Discussion and sample code

The Svg07 program

Description of the program

As I mentioned earlier, one of the most frustrating things about using Java to create raw code elements in XML, XHTML, or HTML is having to deal with the escape sequences for the many required quotation marks that surround attribute values.  This program demonstrates a method that can be used to easily create raw XML code elements without having to deal with those escape sequences.  The elements produced by the method may or may not be empty, and may or may not have attributes.

Color and boldface
The program named Svg07 does not produce the color and boldface shown in Figure 1.  I added those features manually to make it easier to refer back to the contents of Figure 1 later.
Svg07 screen output

The screen output of the program named Svg07 is shown in Figure 1. I will refer back to this screen output as I discuss the program code.

Figure 1. Svg07 screen output.

Demo empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" />

Demo empty element with no attributes.
Probably doesn't make any sense.
<ElementName />

Demo non-empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" >
Content of element.
</ElementName>

Demo non-empty element with no attributes.
<ElementName >
Content of element.
</ElementName>

This program was tested using J2SE 5.0 and WinXP.

Will discuss in fragments

As is my custom, I will discuss and explain this program in fragments.  (You can view the entire program in Listing 22 near the end of the lesson.)  The first fragment in Listing 1 shows the beginning of the class and the beginning of the main method.

Listing 1. Beginning of the class named Svg07.

public class Svg07{
  public static void main(String argv[]){
    String name = "ElementName";
    System.out.println(
                   "Demo empty element with attributes.");

    String emptyElement = makeElement(true,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(emptyElement);

No requirement to program using the escape sequence

The code in Listing 1 produces the first block of output text shown in Figure 1.  Note the correspondence between the values in the elements of the array object of type String[] in Listing 1 and the attribute names and values in the first block of output text in Figure 1.  Note also that there was no requirement in Listing 1 to create string data using the escape sequence for quotation marks as shown below:

"color="Color.RED" width="10" height="20""

Instead, each attribute name and each attribute value was specified as a simple String in Listing 1, and the method named makeElement produced the required output format shown in the first block of text in Figure 1.  While this method is very simple, it is also extremely useful.  (Sometimes the most useful things are the simplest.)

The method named makeElement

At this point, I am going to put the main method on the back burner and explain the method named makeElement.

As mentioned earlier, one of the most frustrating things about using Java to create raw elements in XML, XHTML, or HTML is having to deal with the escape sequences for the many required quotation marks that surround attribute values. The method named makeElement constructs an element, which may or may not have attributes. Also, the element may or may not be empty.

The user of this method does not have to deal with the required quotation marks surrounding attribute values and the corresponding escape sequences.

Recommended usage of the makeElement method

The recommended usage of the makeElement method is shown in Figure 2. 

Figure 2. Recommended usage of the makeElement method.

String newElement = makeElement(
                         true/false,
                         name,
                         new String[]{"name","value",
                                      "name","value",
                                      "name","value",
                                      ...
                                      "name","value",
                                     });

(Note that the ellipses (...) in Figure 2 indicate that any number of name/value pairs is allowed.)

The first parameter to the method

The first parameter must be true if the element is empty and false if the element is not empty.

If the first parameter is true, the element is sealed off in the required manner for an empty element (see the end of the black boldface text in the first block of text in Figure 1).

If the first parameter is false, the method returns the complete start tag for the element but does not return a complete element.  (See the black boldface text in the third and fourth blocks of text in Figure 1.)   In this case, it is the responsibility of the calling method to provide the content and the end tag for the element.  (See the red text in the third and fourth blocks of text in Figure 1.)

The second parameter to the method

The second parameter to the makeElement method must be a String that specifies the name of the element.

The third parameter to the method

The third parameter to the makeElement method must be a reference to an array object of type String[] or null.

This array must contain an even number of elements.  Each pair of array elements constitutes the name and the value of an attribute, in the order name, value, name, value, etc.

Start tag for an element with no attributes
Although this is one of the possible combinations, it is probably easier to hard-code such a start tag in the Java code rather than to make a call to the makeElement method.
If the reference to the array object is null and the first parameter is false, the method returns the start tag for an element that has no attributes and is not empty. (See the black boldface text in the fourth block of text in Figure 1.) 

An empty element with no attributes
This combination probably won't be heavily used because there isn't a lot of demand for XML elements that are empty with no attributes.
If the reference to the array object is null and the first parameter is true, the method returns a complete empty element with no attributes (see the black boldface text in the second block of text in Figure 1)

The most useful combinations

Because the purpose of the method is to make it easier to deal with the quotation marks that must surround attribute values in XML elements, the most useful combinations are represented by the first and third blocks of text in Figure 1, which are respectively:

  • An empty element with attributes.
  • An element with attributes that is not empty.

The beginning of the makeElement method

The method named makeElement begins in Listing 2.

Listing 2. The beginning of the makeElement method.

  static String makeElement(boolean empty,
                            String elementName,
                            String[] data){

    //Begin constructing the start tag.
    String element = "<" + elementName + " ";

The StringBuffer class
Another, and possibly more efficient way to construct the String object that represents the element would be to use the append method of the StringBuffer class.
The code in Listing 2 instantiates a String object, which consists of a left angle bracket concatenated with the name of the element.  This object will be used to create a succession of new String objects containing attribute names and values as the method executes.

Dealing with elements that have no attributes

Listing 3 deals with elements that have no attributes on the basis of the values of the first and third parameters.

Listing 3. Dealing with elements that have no attributes.

    if((empty==false) && (data == null)){
      //Return a complete start tag.
      return element + ">";
    }else if((empty==true) && (data == null)){
      //Return a complete empty element.
      return element + "/>";
    }//end if

The code in Listing 3 is straightforward.  Because there are no attributes, no further processing within the method is required.  Depending on the combination of parameter values, this code will return the String object shown by the black boldface text in either the second block of text or the fourth block of text in Figure 1.

Processing the attributes

The code in Listing 4 is executed when the third parameter is not null, meaning that there are attribute names and values in the array object referenced by the value of the third parameter.

Listing 4. Processing the attributes.

    for(int cnt=0;cnt<data.length;cnt+=2){
      String name = data[cnt];
      String value = data[cnt+1];
      element += name + "=" + """ + value + "" ";
    }//end for loop

The code in Listing 4 extracts the values from the array in pairs and uses those pairs of values to successively create extended String objects that are formatted properly for the specification of XML element attribute names and values.  (See the black boldface text in the first and third blocks of text in Figure 1.)  Note that the code in Listing 4 uses the escape sequence to properly surround the attribute values with quotation marks, thus relieving the using programmer of the requirement to perform this task.

Decision time: empty element or non-empty element

When the loop in Listing 4 terminates, the element has been constructed out to the point where it is necessary to decide whether to seal it off as an empty element (/>) or to seal it off as the end of the start tag (>) for an element that is not empty.  That decision is made by the code in Listing 5 on the basis of the value of the first parameter.

Listing 5. Decision: empty element or non-empty element.

    if(empty){
      //Terminate the element appropriately for an
      // empty element. A complete empty element will
      // be returned.
      element += "/>";
    }else{
      //End the start tag for an element that is not
      // empty. In this case, only the start tag will
      // be returned.  The calling program must provide
      // the content for the element as well as the end
      // tag for the element.
      element += ">";
    }//end else
    
    return element;
  }//end makeElement

The code in Listing 5 is straightforward and shouldn't require further explanation.

Return the element and terminate the method

Listing 5 also returns a reference to the String object containing the newly-constructed element and terminates the method named makeElement.

Remaining code in the main method

Now that you understand how the method named makeElement works, you shouldn't have any difficulty understanding the remaining code in the main method, which is shown in Listing 6.

Listing 6. Remaining code in the main method.

    System.out.println();
    System.out.println(
                "Demo empty element with no attributes.");
    System.out.println(
                      "Probably doesn't make any sense.");
    emptyElement = makeElement(true,name,null);
    System.out.println(emptyElement);

    System.out.println();
    System.out.println(
               "Demo non-empty element with attributes.");
    String elementStartTag = makeElement(false,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

    System.out.println();
    System.out.println(
            "Demo non-empty element with no attributes.");
    elementStartTag = makeElement(false,name,null);
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

  }// end main()

The code in Listing 6 calls the makeElement method three times to produce the screen output shown in Figure 1.  You should have no difficulty correlating the code in Listing 6 with the screen output shown in Figure 1.

Displayed on the screen for illustration

For illustration purposes, this program has simply used a println statement to display the XML elements produced by the makeElement method on the screen.  In future lessons, those elements will either be written into SVG files as part of the SVG code required to render a graphic image, or sent from a servlet to a browser as part of the SVG code produced by the servlet.

The Svg08 program

Graphic output from Svg08

Before getting into the details of the program code for the program named Svg08, I want to show you the graphic output from this program and explain what it mean.  That output is shown in Figure 3.

Figure 3. Graphic output from Svg08.

The first way to draw an ellipse

Basically, this program illustrates three different ways to use the methods in my SVG graphics library to draw an ellipse.  The first way is to call the method named makeEllipse, providing attribute values for the coordinates that define the center of the ellipse, the width of the ellipse, and the height of the ellipse, and accept the default attribute values for all of the other attributes.  This approach resulted in the black ellipse at the top of Figure 3.  As you can see, this ellipse is completely opaque, and the blue line beneath it does not show through.

The second way to draw an ellipse

The second way to draw an ellipse is to do the same thing as above, but to follow that up by making two successive calls to the setAttribute method to set the style attribute to fill:red, and to set the opacity attribute to 0.6, (or 60-percent opaque).  This resulted in the pink ellipse in the center of Figure 3, with the white background and the wide blue line beneath the ellipse showing through.

The third way to draw an ellipse

The third way to draw an ellipse is to call the makeNode method to draw an ellipse with the following attributes names and values:

  • cx: 110 (coordinate of center along the x-axis)
  • cy 300 (coordinate of center along the y-axis)
  • rx: 100 (radius along the x-axis)
  • ry: 40 (radius along the y-axis)
  • style: fill:green (fill color for the ellipse)
  • opacity: 0.6 (opacity attribute value)
  • transform: translate(110,300) rotate(15) translate(-110,-300)

This resulted in the rotated green ellipse at the bottom of Figure 3.

The first four attributes in the above list are the same attributes for which the values were set for the black ellipse (but with different attribute values).

The first six attributes in the above list are the same attributes for which the values were set for the red ellipse (again with different attribute values).

The last attribute in the above list was an extra attribute that was set on the third (green) ellipse to cause it to be rotated by 15 degrees clockwise about its center.  This attribute was not set for either the black ellipse or the red ellipse.

A bit of trivia
Although I never realized it until just this moment, the word ellipses can describe either three spaced periods indicating the omission of text or the plural of ellipse.
Other graphic elements

In addition to the three ellipses that were drawn by this program, a wide blue line was drawn underneath the three ellipses in order to demonstrate the transparency that results from setting the opacity attribute value to less than 1.0.

Also, a black border, one pixel wide, was drawn to outline the canvas on which the ellipses and the line were drawn.

Description of the program

The purpose of this program is to demonstrate the use of a graphics method named makeNode that can be used to create a general DOM tree node having any name and any number of attributes with any attribute names and any String values for the attributes.

The program creates a DOM tree describing the graphic image shown in Figure 3 in SVG format.  Then the program transforms the DOM tree into raw XML code and writes the XML code out into an XML file named junk.svg.

The program illustrates three different ways to use the methods of the SVG graphics library to draw ellipses having different attribute values. The output file produced by this program can be rendered by loading it into Firefox 1.5.

The program was tested using J2SE 5.0, Firefox v1.5.0.8, and WinXP.

Will discuss in fragments

As before, I will present and explain the program in fragments.  (You can view the entire program in Listing 23 near the end of the lesson.)

The getDocument method
The method named getDocument was explained in an earlier lesson.  That explanation won't be repeated here.
The first fragment is shown in Listing 7.  This fragment shows the beginning of the class and the main method, along with the beginning of the code required to create the DOM tree. 

Listing 7. Begin creating the DOM tree.

public class Svg08 {

  public static void main(String[] args){

    //Begin by creating a DOM tree that represents the XML
    // code that will be rendered to produce the image of
    // interest.

    //Get the Document object.
    Document document = SvgGraphics.getDocument();

Create the root node named svg

Listing 8 calls the makeNode method to create the root node named svg and to append it to the document.

Listing 8. Create the root node named svg.

    Element svg = SvgGraphics.makeNode(
        document,
        null,//parent
        "svg",//node type
        new String[]{"xmlns","http://www.w3.org/2000/svg",
                     "version","1.1",
                     "width","220",
                     "height","440",
                     "position","absolute",
                     "top","0",
                     "left","0",
                    });//end makeNode method

For this special case where the new node needs to be a child of the document, null is passed as the second parameter (that specifies the parent).  Otherwise, a reference to the actual parent node should be passed as the second parameter.

With the exception of the attributes named xmlns and position, you can probably pretty well surmise what the purpose of each attribute is.  I will leave it as an exercise for the reader to go to the SVG specification (see Resources) to learn about those attributes.

The makeNode method

At this point, I am going to put the discussion of the main method on the back burner while I present and explain the makeNode method.

The purpose of this method is to create a general node having any name and any number of attributes with any attribute names and any String values for the attributes.

Recommended usage of the makeNode method

Figure 4 shows an example of the recommended usage for the makeNode method.

Figure 4. Recommended usage of the makeNode method.

    Element abc = SvgGraphics.makeNode(
                      document,
                      def,//parent could be null
                      "ghi",//node type
                      new String[]{"name","value",
                                   "name","value",
                                   ...
                                   "name","value",
                                  });//end makeNode method

The first parameter is a reference to the document to which the new node belongs

The second parameter is a reference to the parent node to which this node is to be appended so as to become a child of that node.  If this parameter is null, the new node is appended to the document.  Otherwise, it is appended to the specified parent node.

The third parameter is a String that specifies the type of the new node.

Reference to a String array object

The fourth parameter must be a reference to an array object of type String or it must be null.  This array must contain an even number of elements.  Each pair of elements constitutes the name and the value of an attribute, in the following order: name, value, name, value, etc.  (Any number of name/value pairs is allowed.)

Referring back to Listing 8, you see a call to the makeNode method to create a new node of type svg and append it to (make it a child node of) the document node.

A reference to an array object of type String[] was passed as the fourth parameter.  The array object in Listing 8 contained seven different pairs of strings specifying the attribute names and corresponding attribute values for seven different attributes.

Note the values of the width, height, top, and left attributes in Listing 8.  Basically, these values specify the location and dimensions of the canvas upon which the ellipses will be drawn.  These values will become important when I return to the discussion of the code in the main method.

Beginning of the makeNode method

Listing 9 shows the beginning of the makeNode method, including the creation of the new node of type Element.  The node is bare at this point, but will be dressed up to contain attribute nodes, etc., as the execution of the method progresses.

Listing 9. Beginning of the makeNode method.

  static Element makeNode(Document document,
                          Element parent,
                          String nodeType,
                          String[] data){
  
    Element element = 
                (Element)document.createElement(nodeType);

Append new node to its parent

Listing 10 calls the appendChild method, to cause the new node to become a child node of the specified parent.

Listing 10. Append new node to its parent.

    if(parent == null){
      //For the special case of parent equal to null,
      // append the new node to the document.
      document.appendChild(element);
    }else{
      //Otherwise, append the new node to the specified
      // parent.
      parent.appendChild(element);
    }//end else

For the special case where the parent is specified as null, the new node is appended to the document.  Otherwise, it is appended to the specified parent node.

Nodes that have no attributes

Listing 11 deals with the case where the reference to the array object is null, indicating that this new node has no attributes.

Listing 11. Nodes that have no attributes.

    //Deal with elements that have no attributes.
    if(data == null){
      return element;
    }//end if

For this case, the node that was created in Listing 10 and appended to its parent in Listing 11 is all that is required.  Therefore, the code in Listing 11 simply returns a reference to that node and the method terminates.

Processing the attribute names and values

The for loop in Listing 12 extracts each attribute-name/value pair from the array object and uses that information to set an attribute on the new node with a matching name and a matching value.

Listing 12. Processing the attribute names and values.

    
    for(int cnt=0;cnt<data.length;cnt+=2){
      String name = data[cnt];
      String value = data[cnt+1];
      element.setAttribute(name,value);
    }//end for loop
    
    return element;
  }//end makeNode

At this point, you could set an attribute on the node having just about any name and just about any String value on the new node.  However, in order for an attribute to be effective in the ultimate rendering of the graphic image, the name and value must be included in the names and values that are allowed by the SVG specification for an element of that type (see Resources).

Return the new node

Listing 12 also returns a reference to the new node and terminates the method.

Show outline of the canvas

Now, returning to the discussion of the main method and continuing from where we left off in Listing 8, Listing 13 calls the makeNode method to draw the rectangular outline at the edge of the drawing canvas shown in Figure 3.

Listing 13. Show outline of the canvas.

      Element outline = SvgGraphics.makeNode(document,
                                         svg,//parent
                                         "rect",//type
        new String[]{"x","0",
                     "y","0",
                     "width","220",
                     "height","440",
                     "fill","none",
                     "stroke","black",
                     "stroke-width","1",
                    });//end makeNode method

The attribute values

The earlier code in Listing 8 created the canvas at the location and with the dimensions that I pointed out earlier.  Note that the location and dimensions of the rectangular outline drawn by the code in Listing 13 matches the location and dimensions of the canvas created in Listing 8.

The fill attribute specifies what is to be used to fill the interior of the rectangle, and in this case, "none" is specified.

The stroke attribute specifies information about the stroke that forms the outline of the rectangle.  In this case it was simply specified as "black."

The stroke-width attribute specifies the thickness of the stroke that forms the outline of the rectangle.  In this case the width was specified to be the width of a single pixel.

Create a group container named g

Listing 14 calls the makeNode method to create a non-visual node named g.  This node will be the parent for a line and three ellipses.  Although I won't demonstrate it in this program, having assigned the three visual components to the same group, it would be possible for me to manipulate them as a group in various ways.

Listing 14. Create a group container named g.

    Element g = SvgGraphics.makeNode(document,
                                     svg,//parent
                                     "g",
                                     null);

Note that Listing 14 passes null in place of a reference to an array object containing attribute name/value pairs.  As a result, the node named g is constructed with no attributes.

Draw a blue line

Listing 15 draws the blue line shown in Figure 3 beginning at the upper left corner of the canvas and extending to the lower right corner of the canvas.  The line is 12 pixels wide.

Listing 15. Draw a blue line.

    Element line = SvgGraphics.makeLine(document,
                                        g,   //owner
                                        0,   //x1
                                        0,   //y1
                                        220, //x2
                                        440);//y2
    line.setAttribute("stroke","blue");
    line.setAttribute("stroke-width","12");

The makeLine method
Note that the makeLine method is much less general than the makeNode method, which could also have been used to draw this line.  The choice between the two is based on programmer preference.
The drawing of the line is accomplished in three steps.  The first step is to draw the line as a default black line one pixel wide by calling the makeLine method, passing the coordinates for the beginning and end points of the line as parameters to the method. 

The second step is to call the setAttribute method to change the color from black to blue.

The third step is to call the setAttribute method again to change the line width from one pixel to twelve pixels.

This is a case of originally drawing the image by calling a very specialized method, and then supplementing that call by two successive calls to a general method that can be used to set attribute values, one attribute at a time.

The makeLine method

Once again, let's put the discussion of the main method on the back burner while we take a look at the code in the makeLine method, which is shown in its entirety in Listing 16.

Listing 16. The makeLine method.

  static Element makeLine(Document document,
                          Element parent,
                          int x1,
                          int y1,
                          int x2,
                          int y2){
    Element line  = 
                  (Element)document.createElement("line");
    parent.appendChild(line);
    line.setAttribute("x1",""+x1);
    line.setAttribute("y1",""+y1);
    line.setAttribute("x2",""+x2);
    line.setAttribute("y2",""+y2);
    line.setAttribute("stroke","black");
    line.setAttribute("stroke-width","1");
    return line;
  }//end makeLine

The parameter values

This method returns a reference to a line. The parameters x1 and y1 specify the starting point of the line.  The parameters x2 and y2 specify the end point of the line.  (The line could be rotated and translated later to make it appear differently but that wasn't done in this case.)   By default, the stroke is set to black one pixel wide.

There is nothing complicated in Listing 16, so it shouldn't require further explanation.

Draw the black ellipse

Returning now to the main method, Listing 17 calls the makeEllipse method to draw the black ellipse at the top in Figure 3.

Listing 17. Draw the black ellipse.

    SvgGraphics.makeEllipse(document,//This document
                            g,//Owner
                            110,//Center x-coordinate
                            100,//Center y-coordinate
                            100,//Width
                            40); //Height

The call to the makeEllipse method in Listing 17 passes parameter values for four of the attributes.  These four attributes, which are set by the makeEllipse method, specify the location and size of the ellipse. The ellipse is black because the attribute that controls the color was not set.

The makeEllipse method

The makeEllipse method is shown in its entirety in Listing 18.

Listing 18. The makeEllipse method.

  static Element makeEllipse(Document document,
                             Element parent,
                             int xCoor,
                             int yCoor,
                             int xRadius,
                             int yRadius){
    Element ellipse  = 
               (Element)document.createElement("ellipse");
    parent.appendChild(ellipse);
    ellipse.setAttribute("cx",""+xCoor);
    ellipse.setAttribute("cy",""+yCoor);
    ellipse.setAttribute("rx",""+xRadius);
    ellipse.setAttribute("ry",""+yRadius);
    return ellipse;
  }//end makeEllipse

This makeEllipse method returns a reference to an ellipse. The xCoor and yCoor parameters specify the center of the ellipse. The xRadius and yRadius parameters specify the width and height of the ellipse respectively.  The code in Listing 18 is straightforward and shouldn't require further explanation.

Draw the red ellipse

Returning once more to the main method, Listing 19 draws the red (pink) ellipse in the middle of Figure 3.

Listing 19. Draw the red ellipse.

    Element ellipse2 = SvgGraphics.makeEllipse(
                           document,
                           g,//Owner
                           110,//Center x-coordinate
                           200,//Center y-coordinate
                           100,//Width
                           40); //Height
    ellipse2.setAttribute("style","fill:red");
    ellipse2.setAttribute("opacity","0.6");

As with the line that was drawn earlier, the red ellipse in Figure 3 was drawn in three steps.  The first step was to call the makeEllipse method to draw a black ellipse in the correct position with the correct shape.

The second step was to call the setAttribute method to change the fill color from black to red.

The third step was to call the setAttribute method again to change the opacity from the default value of 100-percent opaque to a new value of 60-percent opaque (0.6).

Draw the green rotated ellipse

The green rotated ellipse shown at the bottom of Figure 3 could have been drawn using the same approach as for the red ellipse and adding one more call to the setAttribute method to accomplish the rotation.  However, instead of drawing it that way, as shown in Listing 20, the green ellipse was drawn by calling the makeNode method, and passing all of the relevant attribute names and attribute values as the contents of an array object.

Listing 20. Draw the green rotated ellipse.

    Element ellipse3 = SvgGraphics.makeNode(
      document,
      g,//parent
      "ellipse",//node type
      new String[]{"cx","110",
                   "cy","300",
                   "rx","100",
                   "ry","40",
                   "style","fill:green",
                   "opacity","0.6",
                   "transform","translate(110,300) "
                             + "rotate(15) "
                             + "translate(-110,-300)"
                  });//end makeNode method 

The transform attribute
The transform attribute can be used to perform a variety of transformations on a shape, such as rotate, scale, translate, and skew.  See section 7 of the SVG specification in Resources.
The makeNode method

If you examine the code in Listing 20 carefully, and compare it with the code for the makeNode method in Listing 9 through Listing 12, you will see that it draws a green ellipse with 60% opacity rotated by 15-degrees clockwise relative to its center.

As I explained earlier, the makeNode method lets you set all, none, or any combination of attribute values in order to take advantage of any combination of available attributes with no assumptions being made about any of the attributes. This is the most general of the three approaches presented and discussed in this lesson.

Transform the DOM and write the output file

Listing 21 transforms the DOM tree into raw XML code and writes that XML code into an output file named junk.svg

Listing 21. Transform the DOM and write the output file.

    SvgGraphics.transformTheDom(document,"junk.svg");

  }// end main()

The method named transformTheDom was explained in an earlier lesson.  That explanation won't be repeated here.

The end of the program

Listing 21 also signals the end of the main method and the end of the program.

Run the program

I encourage you to copy the code from Listing 22 and Listing 23 into your text editor, compile it, and execute it.  Then view the resulting SVG files in Firefox 1.5, or some other suitable SVG rendering engine.  Experiment with the code, making changes, and observing the results of your changes.

Above all, enjoy the process. Programming can be fun.

Summary

Continuing with the SVG graphics library from the previous lesson, I taught you how to write a method that deals with the escape sequences required for the quotation marks that surround attribute values in XML thereby making it much easier to write Java code that generates XML code.

I also taught you how to write a method that makes it possible to create a general node in the DOM tree being constructed to represent an SVG graphic, making no prior assumptions about the number of attributes, the names of the attributes, or the values of the attributes.

What's next?

The next lesson in this series will show you how to take what you have learned in this and the previous lesson and to apply that knowledge to the generation of XHTML files containing in-line SVG/XML code.  The next lesson will also teach you how to apply that knowledge to the writing of servlets that produce XHTML output containing in-line SVG/XML code.

Future lessons will teach you how to write servlets that:

  • Produce XHTML output containing references to external SVG files, some of which are created on-the-fly during the execution of the servlet.
  • Create and re-use graphic elements.
  • Use SVG symbols.
  • Deal with stroke caps in SVG in comparison with similar caps in Java 2D.
  • Use the switch element in SVG.
  • Deal with bit-mapped images in SVG.
  • Deal with text in SVG.
  • Deal with other features such as animation in SVG.

Complete program listings

Complete listings of the programs discussed in this lesson are shown in Listing 22 and Listing 23 below.

Listing 22. The program named Svg07.

/*File Svg07.java
Copyright 2006, R.G.Baldwin

One of the most frustrating things about using Java to
create elements in XML, XHTML, or HTML is having to deal
with the escape characters for the many required
quotation marks that surround attribute values.  This 
program demonstrates a method that can be used to easily 
create elements without having to deal with those escape 
characters. The element produced by the method may or may 
not be empty, and may or may not have attributes.

This program produces the following output:

Demo empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" />

Demo empty element with no attributes.
Probably doesn't make any sense.
<ElementName />

Demo non-empty element with attributes.
<ElementName color="Color.RED" width="10" height="20" >
Content of element.
</ElementName>

Demo non-empty element with no attributes.
<ElementName >
Content of element.
</ElementName>

Tested using J2SE 5.0, Firefox v1.5.0.9, and WinXP.
*********************************************************/
import java.io.*;

public class Svg07{
  public static void main(String argv[]){
    String name = "ElementName";
    System.out.println(
                   "Demo empty element with attributes.");

    String emptyElement = makeElement(true,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(emptyElement);

    System.out.println();
    System.out.println(
                "Demo empty element with no attributes.");
    System.out.println(
                      "Probably doesn't make any sense.");
    emptyElement = makeElement(true,name,null);
    System.out.println(emptyElement);

    System.out.println();
    System.out.println(
               "Demo non-empty element with attributes.");
    String elementStartTag = makeElement(false,name,
                         new String[]{"Color","Color.RED",
                                      "width","10",
                                      "height","20"});
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

    System.out.println();
    System.out.println(
            "Demo non-empty element with no attributes.");
    elementStartTag = makeElement(false,name,null);
    System.out.println(elementStartTag);
    System.out.println("Content of element.");
    //Create end tag for element
    System.out.println("</" + name + ">");

  }// end main()
  //----------------------------------------------------//
  /*
  One of the most frustrating things about using Java
   to create elements in XML, XHTML, or HTML is having
   to deal with the escape characters for the many
   required quotation marks. This method constructs an
   element, which may or may not have attributes. Also,
   the element may or may not be empty.
  The user of this method does not have to deal with the
   required quotation marks surrounding attribute values
   and the corresponding escape characters     
  The first incoming parameter must be true if the
   element is empty and false if the element is not
   empty.
  If the first parameter is true, the element is sealed
   off in the required manner for an empty element. If
   the first parameter is false, the method returns the
   complete start tag for the element but does not
   return a complete element. It is the responsibility
   of the calling method to provide the content and the
   end tag for the element.
  The second parameter to the method must be a String
   that specifies the name of the element.
  The third parameter to the method must be a reference
   to an array object of type String.  This array must 
   contain an even number of elements.  Each pair of 
   elements constitutes the name and the value of an 
   attribute, in the order name, value, name, value, etc.

  If the reference to the array object is null and the
   first parameter is false, the method returns the start
   tag for an element that has no attributes and is not 
   empty.
  If the reference is null and the first parameter is
   true, the method returns a complete empty element with 
   no attributes (which probably doesn't make any sense).
   
  An example of the recommended usage of the method
   follows:
   
  String newElement = makeElement(
                         true/false,
                         name,
                         new String[]{"name","value",
                                      "name","value",
                                      "name","value",
                                     });
   
  */
  
  static String makeElement(
          boolean empty,String elementName,String[] data){

    //Begin constructing the start tag.
    String element = "<" + elementName + " ";
    
    //Deal with elements that have no attributes.
    if((empty==false) && (data == null)){
      //Return a complete start tag.
      return element + ">";
    }else if((empty==true) && (data == null)){
      //Return a complete empty element.
      return element + "/>";
    }//end if

    for(int cnt=0;cnt<data.length;cnt+=2){

      String name = data[cnt];
      String value = data[cnt+1];
      element += name + "=" + """ + value + "" ";
    }//end for loop
    
    if(empty){
      //Terminate the element appropriately for an
      // empty element. A complete empty element will
      // be returned.
      element += "/>";
    }else{
      //End the start tag for an element that is not
      // empty. In this case, only the start tag will
      // be returned.  The calling program must provide
      // the content for the element as well as the end
      // tag for the element.
      element += ">";
    }//end else
      
  return element;
  }//end makeElement

}//end Svg07

 

Listing 23. The program named Svg08.

/*File Svg08.java
Copyright 2006 R.G.Baldwin

The purpose of this program is to demonstrate the use of 
a new graphics method that can be used to create a general
node having any name, and any number of attributes with 
any attribute names and any String values for the 
attributes, or no attributes at all.

The program creates a DOM tree describing a specific 
graphic image in SVG format and writes it out into an XML 
file named junk.svg.

The program illustrates three different ways to use the
methods of the SVG graphics library to create ellipses
having different attribute values.

The output file produced by this program can be rendered 
by loading it into Firefox 1.5.

Tested using J2SE 5.0, Firefox v1.5.0.8, and WinXP.
*********************************************************/

import javax.xml.parsers.*;
import org.w3c.dom.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

public class Svg08 {

  public static void main(String[] args){

    //Begin by creating a DOM tree that represents the XML
    // code that will render to produce the image of
    // interest.

    //Get the Document object.
    Document document = SvgGraphics.getDocument();

    //Create the root node named svg and append it to the
    // document.  Specify the parent as null for the
    // special case where the parent is the document.
    // Otherwise, specify the actual parent node.
    Element svg = SvgGraphics.makeNode(
        document,
        null,//parent
        "svg",//node type
        new String[]{"xmlns","http://www.w3.org/2000/svg",
                     "version","1.1",
                     "width","220",
                     "height","440",
                     "position","absolute",
                     "top","0",
                     "left","0",
                    });//end makeNode method



      //Show outline of canvas using 'rect' element
      Element outline = SvgGraphics.makeNode(document,
                                         svg,//parent
                                         "rect",//type
        new String[]{"x","0",
                     "y","0",
                     "width","220",
                     "height","440",
                     "fill","none",
                     "stroke","black",
                     "stroke-width","1",
                    });//end makeNode method

    //Create a node named g, which will be the parent for
    // an ellipse. Pass null for the reference to the
    // array object for the special case where the node
    // has no attributes.
    Element g = SvgGraphics.makeNode(document,
                                     svg,//parent
                                     "g",
                                     null);
                                     
    //Draw a blue line 12 pixels wide.  First define the
    // line by providing values for the four default
    // attributes of the makeLine method that specify the
    // end point locations of the line.  Then supplement
    // those attributes by invoking the setAttribute
    // method twice in succession on the reference to the
    // line to set the stroke and stroke-width attributes,
    // causing the line to be blue with a width of 12
    // pixels.
    Element line = SvgGraphics.makeLine(document,
                                        g,   //owner
                                        0,   //x1
                                        0,   //y1
                                        220, //x2
                                        440);//y2
    line.setAttribute("stroke","blue");
    line.setAttribute("stroke-width","12");
    

    //Draw a black ellipse by providing values for the
    // four default attributes of the makeEllipse method
    // that specify the location and size of the ellipse.
    // The ellipse is black because the attribute that
    // controls the color was not set.
    SvgGraphics.makeEllipse(document,//This document
                            g,//Owner
                            110,//Center x-coordinate
                            100,//Center y-coordinate
                            100,//Width
                            40); //Height

    //Draw an ellipse by providing values for the four
    // default attributes of the makeEllipse method that
    // specify the location and size of the ellipse. Then
    // supplement those attributes by invoking the
    // setAttribute method on the reference to the ellipse
    // twice to fill the ellipse with red color and to
    // cause the filled ellipse to have 60% opacity.
    Element ellipse2 = SvgGraphics.makeEllipse(
                           document,
                           g,//Owner
                           110,//Center x-coordinate
                           200,//Center y-coordinate
                           100,//Width
                           40); //Height
    ellipse2.setAttribute("style","fill:red");
    ellipse2.setAttribute("opacity","0.6");
    
    //Draw a green ellipse with 60% opacity rotated by
    // 15-degrees clockwise, using the makeNode method,
    // for which there are no default attributes.
    //This method lets you set all, none, or any
    // combination of attribute values in order to
    // take advantage of none, any, or all of the
    // available attributes with no assumptions being
    // made about any of the attributes. This is the
    // most general of the three approaches.
    
    Element ellipse3 = SvgGraphics.makeNode(
      document,
      g,//parent
      "ellipse",//node type
      new String[]{"cx","110",
                   "cy","300",
                   "rx","100",
                   "ry","40",
                   "style","fill:green",
                   "opacity","0.6",
                   "transform","translate(110,300) "
                             + "rotate(15) "
                             + "translate(-110,-300)"
                  });//end makeNode method  
    
    //Transform the DOM and write the output file.
    SvgGraphics.transformTheDom(document,"junk.svg");

  }// end main()
  //----------------------------------------------------//
  
}// class Svg08
//======================================================//

//This is an abbreviated library used solely to support 
// this program for the purpose of demonstrating the
// method named makeNode.
class SvgGraphics{
  //----------------------------------------------------//
  
  /*
  The purpose of this method is to create a general node
   having any name, and any number of attributes with any 
   attribute names and any String values for the 
   attributes, or no attributes at all.
   
  The first parameter is a reference to the document to
   which the new node belongs.
  
  The second parameter is a reference to the parent node
   to which this node is to be appended so as to become a
   child of that node. If this parameter is null, the new
   node is appended to the document.  Otherwise, it is
   appended to the specified parent node.
   
  The third parameter is a String that specifies the type
   of node.
  
  The fourth parameter to the method must be a reference
   to an array object of type String.  This array must 
   contain an even number of elements.  Each pair of 
   elements constitutes the name and the value of an 
   attribute, in the order name, value, name, value, etc.
  
  An example of the recommended usage of the method
   follows:
    Element abc = SvgGraphics.makeNode(
                      document,
                      def,//parent could be null
                      "ghi",//node type
                      new String[]{"name","value",
                                   "name","value",
                                   "name","value",
                                  });//end makeNode method
  */
  static Element makeNode(Document document,
                                Element parent,
                                String nodeType,
                                String[] data){
  
    Element element = 
                (Element)document.createElement(nodeType);
    
    if(parent == null){
      //For the special case of parent equal to null,
      // append the new node to the document.
      document.appendChild(element);
    }else{
      //Otherwise, append the new node to the specified
      // parent.
      parent.appendChild(element);
    }//end else
  
    //Deal with elements that have no attributes.
    if(data == null){
      return element;
    }//end if
    
    for(int cnt=0;cnt<data.length;cnt+=2){
      String name = data[cnt];
      String value = data[cnt+1];
      element.setAttribute(name,value);
    }//end for loop
    
    return element;
  }//end makeNode
  //----------------------------------------------------//

  //This method returns a reference to an ellipse. The
  // xCoor and yCoor parameters specify the center of the
  // ellipse.  The xRadius and yRadius parameters specify
  // the width and height of the  ellipse respectively
  // while it is in the horizontal plane before being
  // rotated.  Numeric attributes are set at type String.
  static Element makeEllipse(Document document,
                             Element parent,
                             int xCoor,
                             int yCoor,
                             int xRadius,
                             int yRadius){
    Element ellipse  = 
               (Element)document.createElement("ellipse");
    parent.appendChild(ellipse);
    ellipse.setAttribute("cx",""+xCoor);
    ellipse.setAttribute("cy",""+yCoor);
    ellipse.setAttribute("rx",""+xRadius);
    ellipse.setAttribute("ry",""+yRadius);
    return ellipse;
  }//end makeEllipse
  //----------------------------------------------------//

  //This is a utility method that is used to execute code
  // that is the same regardless of the graphic image
  // being produced. This method is not new to this
  // program.
  static Document getDocument(){
    Document document = null;
    try{
      DocumentBuilderFactory factory = 
                     DocumentBuilderFactory.newInstance();

      DocumentBuilder builder = 
                             factory.newDocumentBuilder();
      document = builder.newDocument();
      document.setXmlStandalone(false);
    }catch(Exception e){
      e.printStackTrace(System.err);
      System.exit(0);
    }//end catch
    return document;
  }//end getDocument
  //----------------------------------------------------//
  
  //This is a utility method that is used to execute code
  // that is the same regardless of the graphic image
  // being produced.  This method transforms the DOM into
  // raw XML code and writes that code into the output
  // file. This method is not new to this program.
  static void transformTheDom(Document document,
                              String filename){
    try{
      //Get a TransformerFactory object.
      TransformerFactory xformFactory =
                         TransformerFactory.newInstance();
           
      //Get an XSL Transformer object.
      Transformer transformer = 
                            xformFactory.newTransformer();
      
      //Sets the standalone property in the first line of
      // the output file.
      transformer.setOutputProperty(
                              OutputKeys.STANDALONE,"no");
      
      //Get a DOMSource object that represents the
      // Document object
      DOMSource source = new DOMSource(document);


      //Get an output stream for the output file.
      PrintWriter outStream = new PrintWriter(filename);

      //Get a StreamResult object that points to the
      // output file.  Then transform the DOM sending XML
      // code to the file
      StreamResult fileResult = 
                              new StreamResult(outStream);
      transformer.transform(source,fileResult);
    }//end try block

    catch(Exception e){
      e.printStackTrace(System.err);
    }//end catch
  }//end transformTheDom
  //----------------------------------------------------//
  
  //This method returns a reference to a line. x1 and y1
  // specify the starting point of the line before it is
  // rotated. x2 and y2 specify the end point.  By
  // default, the stroke is set to black one pixel wide.
  // This can be overridden to specify other colors and
  // other widths if you need to do so.
  static Element makeLine(Document document,
                          Element parent,
                          int x1,
                          int y1,
                          int x2,
                          int y2){
    Element line  = 
                  (Element)document.createElement("line");
    parent.appendChild(line);
    line.setAttribute("x1",""+x1);
    line.setAttribute("y1",""+y1);
    line.setAttribute("x2",""+x2);
    line.setAttribute("y2",""+y2);
    line.setAttribute("stroke","black");
    line.setAttribute("stroke-width","1");
    return line;
  }//end makeLine
  //----------------------------------------------------//
  
}//end class SvgGraphics


Copyright

Copyright 2007, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

Resources

Java 2D Graphics
300 Java 2D Graphics, Nested Top-Level Classes and Interfaces 
302 Java 2D Graphics, The Point2D Class 
304 Java 2D Graphics, The Graphics2D Class 
306 Java 2D Graphics, Simple Affine Transforms 
308 Java 2D Graphics, The Shape Interface, Part 1 
310 Java 2D Graphics, The Shape Interface, Part 2 
312 Java 2D Graphics, Solid Color Fill 
314 Java 2D Graphics, Gradient Color Fill 
316 Java 2D Graphics, Texture Fill 
318 Java 2D Graphics, The Stroke Interface 
320 Java 2D Graphics, The Composite Interface and Transparency 
322 Java 2D Graphics, The Composite Interface, GradientPaint, and Transparency 
324 Java 2D Graphics, The Color Constructors and Transparency
Java 2D API Specification
Java 2D API

Java API for XML Processing (JAXP)
2200 Java API for XML Processing (JAXP), Getting Started
2202 Getting Started with Java JAXP and XSL Transformations (XSLT)
2204 Java JAXP, Exposing a DOM Tree
2206 Java JAXP, Implementing Default XSLT Behavior in Java
2208 Java JAXP, Writing Java Code to Emulate an XSLT Transformation
2210 Java JAXP, Transforming XML to XHTML
Links to numerous XML tutorials by Richard G. Baldwin

Scalable Vector Graphics (SVG)
Java JAXP, Creating graphics using Java and SVG
Scalable Vector Graphics (SVG) 1.1 Specification
Adobe SVG Viewer plug-in
Create vector graphics in the browser with SVG by Uche Ogbuji
SVG Tutorial
SVG Basics

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP).  His first job after he earned his Bachelor's degree was doing DSP in the Seismic Research Department of Texas Instruments.  (TI is still a world leader in DSP.)  In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

Baldwin@DickBaldwin.com






Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel