Creating a Graphical Browser

In Java, text is just a form of graphics, so we've already been working with graphics. In this next example, I'll create a nontext browser that reads an XML document and uses it to draw graphics figurescircles. Here's what a document that this browser might read, ch11_06.xml, looks like. I'm specifying the (x, y) origin of the circle and the radius of the circle as attributes of the <CIRCLE> element:

Listing ch11_06.xml
 <?xml version = "1.0" ?> <!DOCTYPE DOCUMENT [ <!ELEMENT DOCUMENT (CIRCLE   ELLIPSE)*> <!ELEMENT CIRCLE EMPTY> <!ELEMENT ELLIPSE EMPTY> <!ATTLIST CIRCLE     X CDATA #IMPLIED     Y CDATA #IMPLIED     RADIUS CDATA #IMPLIED> <!ATTLIST ELLIPSE     X CDATA #IMPLIED     Y CDATA #IMPLIED     WIDTH CDATA #IMPLIED     HEIGHT CDATA #IMPLIED> ]> <DOCUMENT>     <CIRCLE X='200' Y='160' RADIUS='50' />     <CIRCLE X='170' Y='100' RADIUS='15' />     <CIRCLE X='80' Y='200' RADIUS='45' />     <CIRCLE X='200' Y='140' RADIUS='35' />     <CIRCLE X='130' Y='240' RADIUS='25' />     <CIRCLE X='270' Y='300' RADIUS='45' />     <CIRCLE X='210' Y='240' RADIUS='25' />     <CIRCLE X='60' Y='160' RADIUS='35' />     <CIRCLE X='160' Y='260' RADIUS='55' /> </DOCUMENT> 

I'll call this example circles.java. We'll need to decode the XML document and store the specification of each circle. To store that data, I'll create an array named x to hold the x coordinates of the circles, y to hold the y coordinates, and radius to hold the radii of the circles. I'll also store our current location in these arrays in an integer named numberFigures :

 public class circles  {     static int numberFigures = 0;     static  int x[] = new int[100];     static int y[] = new int[100];     static int radius[] = new int[100];     .     .     . 

As we parse the document, I'll filter out elements and search for <CIRCLE> elements. When I find a <CIRCLE> element, I'll store its x, y, and radius values in the appropriate array. To check whether the current node is a <CIRCLE> element, I'll compare the node's name , which I get with the getNodeName method, to "CIRCLE" using the Java String method equals , which you must use with String objects instead of the == operator:

 if (node.getNodeType() == Node.ELEMENT_NODE) {  if (node.getNodeName().equals("CIRCLE")) {   .   .   .   }  .     .     . 

To find the value of the X , Y , and RADIUS attributes, I'll use the getAttributes method to get a NamedNodeMap object representing all the attributes of this element. To get the value of specific attributes, I get the node corresponding to that attribute with the getNamedItem method. I get the attribute's actual value with getNodeValue like this, where I'm converting the attribute data from strings to integers using the Java Integer class's parseInt method:

 if (node.getNodeType() == Node.ELEMENT_NODE) {     if (node.getNodeName().equals("CIRCLE")) {  NamedNodeMap attrs = node.getAttributes();   x[numberFigures] = Integer.parseInt((String)attrs.getNamedItem("X").getNodeValue( graphics/ccc.gif ));   y[numberFigures] = Integer.parseInt((String)attrs.getNamedItem("Y").getNodeValue( graphics/ccc.gif ));   radius[numberFigures] = Integer.parseInt ((String)attrs.getNamedItem("RADIUS"). graphics/ccc.gif getNodeValue());  numberFigures++;     }     .     .     . 

You can find the methods of the NamedNodeMap interface in Table 11-8.

Table 11-8. NamedNodeMap Interface Methods
Method Summary
int getLength() Returns the number of nodes in this map
Node getNamedItem(java.lang.String name) Gets a node indicated by name
Node getNamedItemNS(java.lang.String namespaceURI, java.lang.String localName) Gets a node indicated by local name and namespace URI
Node item(int index) Gets an item in the map by index
Node removeNamedItem(java.lang.String name) Removes a node given by name
Node removeNamedItemNS(java.lang.String namespaceURI, java.lang.String localName) Removes a node given by local name and namespace URI
Node setNamedItem(Node arg) Adds a node specified by its nodeName attribute
Node setNamedItemNS(Node arg) Adds a node specified by its namespaceURI and localName attribute

After parsing the document, the required data is in the x , y , and radius arrays. All that's left is to display the corresponding circles, and I'll use the Java Graphics object's drawOval method to do that. This method draws ellipses and takes the (x, y) location of the figure's upper-left corner, as well as the minor and major axes lengths. To draw circles, I'll set both those lengths to the radius value for the circle. It all looks like this in the AppFrame class, which is where we draw the browser's window:

 class AppFrame extends Frame  {     int numberFigures;     int[] xValues;     int[] yValues;     int[] radiusValues;     public AppFrame(int number, int[] x, int[] y, int[] radius)     {         numberFigures = number;         xValues = x;         yValues = y;         radiusValues = radius;     }     public void paint(Graphics g)     {         for(int loopIndex = 0; loopIndex < numberFigures; loopIndex++){             g.drawOval(xValues[loopIndex], yValues[loopIndex], radiusValues[loopIndex], graphics/ccc.gif radiusValues[loopIndex]);         }     } 

And that's all it takes. You can see the results in Figure 11-4, where the browser is displaying ch11_06.xml. The complete listing appears in Listing ch11_04.java.

Figure 11-4. Creating a graphical XML browser.

graphics/11fig04.gif

Listing ch11_07.java
 import java.awt.*; import java.awt.event.*; import javax.xml.parsers.*; import org.w3c.dom.*; public class ch11_07 {     static int numberFigures = 0;     static  int x[] = new int[100];     static int y[] = new int[100];     static int radius[] = new int[100];     public static void displayDocument(String uri)     {         try {         DocumentBuilderFactory dbf =             DocumentBuilderFactory.newInstance();         DocumentBuilder db = null;         try {             db = dbf.newDocumentBuilder();         }         catch (ParserConfigurationException pce) {}         Document document = null;             document = db.parse(uri);             display(document);         } catch (Exception e) {             e.printStackTrace(System.err);         }     }     public static void display(Node node)     {         if (node == null) {             return;         }         int type = node.getNodeType();         if (node.getNodeType() == Node.DOCUMENT_NODE) {             display(((Document)node).getDocumentElement());         }         if (node.getNodeType() == Node.ELEMENT_NODE) {             if (node.getNodeName().equals("CIRCLE")) {                 NamedNodeMap attrs = node.getAttributes();                 x[numberFigures] = Integer.parseInt((String) attrs.getNamedItem("X"). graphics/ccc.gif getNodeValue());                 y[numberFigures] = Integer.parseInt((String) attrs.getNamedItem("Y"). graphics/ccc.gif getNodeValue());                 radius[numberFigures] = Integer.parseInt((String) attrs.getNamedItem( graphics/ccc.gif "RADIUS").getNodeValue());                 numberFigures++;             }             NodeList childNodes = node.getChildNodes();             if (childNodes != null) {                 int length = childNodes.getLength();                 for (int loopIndex = 0; loopIndex < length; loopIndex++) {                     display(childNodes.item(loopIndex));                 }             }         }     }     public static void main(String args[])     {         displayDocument(args[0]);         AppFrame f = new AppFrame(numberFigures, x, y, radius);         f.setSize(400, 400);         f.addWindowListener(new WindowAdapter() {public void             windowClosing(WindowEvent e) {System.exit(0);}});         f.show();     } } class AppFrame extends Frame {     int numberFigures;     int[] xValues;     int[] yValues;     int[] radiusValues;     public AppFrame(int number, int[] x, int[] y, int[] radius)     {         numberFigures = number;         xValues = x;         yValues = y;         radiusValues = radius;     }     public void paint(Graphics g)     {         for(int loopIndex = 0; loopIndex < numberFigures; loopIndex++){g.drawOval( graphics/ccc.gif xValues[loopIndex], yValues[loopIndex], radiusValues[loopIndex], radiusValues[loopIndex]);         }     } } 


Real World XML
Real World XML (2nd Edition)
ISBN: 0735712867
EAN: 2147483647
Year: 2005
Pages: 440
Authors: Steve Holzner

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net