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 figures—circles. Here's what a document this browser might read, circles.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:

<?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());

        y[numberFigures] =
        Integer.parseInt((String)attrs.getNamedItem("Y").getNodeValue());

        radius[numberFigures] =
        Integer.parseInt((String)attrs.getNamedItem("RADIUS").getNodeValue());

        numberFigures++;
    }
    .
    .
    .

You can find the methods of the NamedNodeMap interface in Table 11.7.

Table 11.7. NamedNodeMap Interface Methods
MethodDescription
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 a 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 a 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

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 origin, as well as the minor and major axes' length. 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], radiusValues[loopIndex]);
        }
    }

And that's all it takes; you can see the results in Figure 11.4, where the browser is displaying circles.xml. The complete listing appears in Listing 11.4.

Figure 11.4. Creating a graphical XML browser.


Code Listing 11.4. circles.java
import java.awt.*;
import java.awt.event.*;

import org.w3c.dom.*;
import org.apache.xerces.parsers.DOMParser;

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];

    public static void displayDocument(String uri)
    {
        try {
            DOMParser parser = new DOMParser();
            parser.parse(uri);
            Document document = parser.getDocument();

            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").getNodeValue());

                y[numberFigures] =
            Integer.parseInt((String)attrs.getNamedItem("Y").getNodeValue());

                radius[numberFigures] =
        Integer.parseInt((String)attrs.getNamedItem("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(xValues[loopIndex], yValues[loopIndex],
                radiusValues[loopIndex], radiusValues[loopIndex]);
        }
    }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.213.214