Meeting the Catalog Viewer

   

The example I'll use in this chapter is a catalog viewer. Assume that you have been asked to develop a catalog viewer. The specifications are as follows :

  • Customers and prospective customers receive a new version of the catalog viewer every month. The monthly update presents the latest offerings (such as new products and promotions).

  • The list of products is managed in the company's central database, and a file with the month's offering will be automatically extracted from the database.

  • Product descriptions include the product name and either a picture of the product or a textual description. The management expects to enhance product descriptions with video and HTML in the future.

  • Customers browse through the catalog and mark those products they are interested in buying.

  • The catalog viewer creates a file with the customer's selection. Customers can submit their selections by email and receive more information on those products relevant to them.

The catalog viewer looks similar to Figure 1.2.

Note

A catalog can be as simple or as complex as one likes. In its simplest form it is just a list of product names ; in the most complex form it can include videos . It also can compute the correct price (including any discounts ) and even support online ordering.

In this chapter, I strove for the middle ground with a set of data rich enough to explore all the problems you are likely to face in a real catalog application. However, I used a limited user interface and a limited set of features so as not to bury the XML techniques in a lot of Java programming.


Figure 1.2. The catalog viewer.

graphics/01fig02.gif

The catalog viewer needs a simple, inexpensive file format to store the list of products and the prospective buyers 'selections. Because the list of products is stored in a central database, you need a format recognized by the database.

Figure 1.3 is the class model (in UML [Unified Modeling Language]) for the catalog. This model abstracts product descriptions: The Product class holds only basic information about products (such as the name). Descendants of Product implement more complete descriptions (in this case, through an image or through text).

In particular, each product object is responsible for drawing its own description onscreen. Therefore, if a future version of the catalog includes video, it suffices to add descendants to the Product class.

Figure 1.3. The catalog class model.

graphics/01fig03.gif

Building the Catalog

Listings 1.1 “1.6 implement this class model in Java. Listing 1.1 is the Catalog class. And as you can see, Catalog is simply a list of Product objects.

Warning

Ignore the reference to the CatalogElement and CatalogVisitor interfaces as well as the accept() method for the time being. These will be introduced in subsequent sections.


Listing 1.1 Catalog.java
 package com.psol.catalog; import java.util.Vector; import java.io.IOException; public class Catalog    implements CatalogElement {    protected Product[] products;    public Catalog(Vector products)    {       this.products = new Product[products.size()];       products.copyInto(this.products);    }    public Product productAt(int i)    {       return products[i];    }    public int getSize()    {       return products.length;    }    public void accept(CatalogVisitor visitor)       throws IOException    {       visitor.visitCatalog(this);    } } 

The Product class is declared in Listing 1.2. Product is an abstract class that implements properties shared by all descendants, namely the product's name and whether the product was selected (checked) by a customer.

Product also defines the abstract method getComponent() . Descendants of Product implement this method and return an AWT component that knows how to draw the product description.

For example, VisualProduct objects return a component that draws the image of the product. TextualProduct objects return text labels.

If a VideoProduct class is introduced in the future, it will return components that play the product's video.

Listing 1.2 Product.java
 package com.psol.catalog; import java.io.IOException; import java.awt.Component; public abstract class Product    implements CatalogElement {    protected String text,                     id;    protected boolean checked;    public Product(String text,                   String id,                   boolean checked)    {       this.text = text;       this.id = id;       this.checked = checked;    }    public String getText()    {       return text;    }    public String getId()    {       return id;    }    public void setChecked(boolean checked)    {       this.checked = checked;    }    public boolean isChecked()    {       return checked;    }    public abstract Component getComponent(); } 

Browsing the Catalog

The abstract method getComponent() is responsible for painting the product description, which greatly simplifies the user interface. Listing 1.3 is the CatalogPanel class, a simple graphical interface to the catalog.

CatalogPanel accepts a catalog in its constructor, builds a list of products on the right side of the screen, and paints the appropriate product on the left side, as the customer browses through the list. It also provides a checkbox for the customer to select the product.

itemStateChanged events are generated as the customer browses the list of products. Then the event handler calls getComponent() to draw the appropriate product. Note that the event handler does not know whether a given product is a VisualProduct or a TextualProduct , but it doesn't need to know:

 public void itemStateChanged(ItemEvent evt)    {       if(evt.getStateChange() == ItemEvent.SELECTED)       {       viewer.removeAll();       int idx = list.getSelectedIndex();       Product product = catalog.productAt(idx);       viewer.add(product.getComponent());       checkbox.setState(product.isChecked());       checkbox.setEnabled(true);       validate();    } } 
Listing 1.3 CatalogPanel.java
 package com.psol.catalog; import java.awt.*; import java.awt.event.*; public class CatalogPanel    extends Panel {    protected List list;    protected Checkbox checkbox;    protected Container viewer;    protected Catalog catalog;    public CatalogPanel(Catalog _catalog)    {       catalog = _catalog;       setLayout(new GridBagLayout());       list = new List();       GridBagConstraints constraints = new GridBagConstraints();       add(list,constraints);       for(int i = 0;i < catalog.getSize();i++)          list.add(catalog.productAt(i).getText());       list.addItemListener(new ItemListener()       {          public void itemStateChanged(ItemEvent evt)          {             if(evt.getStateChange() == ItemEvent.SELECTED)             {                viewer.removeAll();                int idx = list.getSelectedIndex();                Product product = catalog.productAt(idx);                viewer.add(product.getComponent());                checkbox.setState(product.isChecked());                checkbox.setEnabled(true);                validate();             }          }       } );       viewer = new Panel();       constraints.gridwidth = GridBagConstraints.REMAINDER;       constraints.weightx = 1.0;       constraints.weighty = 1.0;       add(viewer,constraints);       checkbox = new Checkbox("More info?",false);       constraints.gridwidth = 1;       constraints.weightx = 0.0;       constraints.weighty = 0.0;       add(checkbox,constraints);       checkbox.setEnabled(false);       checkbox.addItemListener(new ItemListener()       {          public void itemStateChanged(ItemEvent evt)          {             int stateChange = evt.getStateChange();             if(ItemEvent.SELECTED == stateChange                 ItemEvent.DESELECTED == stateChange)             {                int idx = list.getSelectedIndex();                Product product = catalog.productAt(idx);                product.setChecked(                   ItemEvent.SELECTED == stateChange);             }          }       } );    } } 

Extending the Product

Listing 1.4 is a TextualProduct . A TextualProduct is a collection of Description objects. To render itself onscreen, the TextualProduct creates a component with as many labels as there are Description objects:

 public Component getComponent()    {       LayoutManager layout =          new GridLayout(descriptions.length + 1,1);       Panel panel = new Panel(layout);       panel.add(new Label("Description:"));       for(int i = 0;i < descriptions.length;i++)       {          String language = descriptions[i].getLanguage(),                 text = descriptions[i].getText();          Label label = new Label(language + ": " + text);          panel.add(label);       }       return panel;    } 
Listing 1.4 TextualProduct.java
 package com.psol.catalog; import java.awt.*; import java.util.Vector; import java.io.IOException; public class TextualProduct    extends Product {    protected Description[] descriptions;    public TextualProduct(String text,                          String id,                          boolean checked,                          Vector descriptions)    {       super(text,id,checked);       this.descriptions = new Description[descriptions.size()];       descriptions.copyInto(this.descriptions);    }    public Component getComponent()    {       LayoutManager layout =          new GridLayout(descriptions.length + 1,1);       Panel panel = new Panel(layout);       panel.add(new Label("Description:"));       for(int i = 0;i < descriptions.length;i++)       {          String language = descriptions[i].getLanguage(),                 text = descriptions[i].getText();          Label label = new Label(language + ": " + text);          panel.add(label);       }       return panel;    }    public Description descriptionAt(int i)    {       return descriptions[i];    }    public int getSize()    {       return descriptions.length;    }    public void accept(CatalogVisitor visitor)       throws IOException    {       visitor.visitTextualProduct(this);    } } 

Listing 1.5 is Description , which is simply a description and the description's language. We can have multilingual catalogs!

Listing 1.5 Description.java
 package com.psol.catalog; import java.io.IOException; import java.awt.Component; public class Description    implements CatalogElement {    protected String language,                     text;    public Description(String language,                       String text)    {       this.language = language;       this.text = text;    }    public String getLanguage()    {       return language;    }    public String getText()    {       return text;    }    public void accept(CatalogVisitor visitor)       throws IOException    {       visitor.visitDescription(this);    } } 

Compare Listing 1.4 with Listing 1.6, the VisualProduct . Both are similar, but a VisualProduct is rendered as an image onscreen.

Listing 1.6 VisualProduct.java
 package com.psol.catalog; import java.awt.*; import java.io.IOException; public class VisualProduct    extends Product {    protected String image;    protected class ImageCanvas       extends Component    {       protected Image image = null;       public ImageCanvas(String filename)       {          Toolkit toolkit = getToolkit();          image = toolkit.getImage(filename);       }       public void paint(Graphics g)       {          if(null != image)             g.drawImage(image,0,0,this);       }       public Dimension getPreferredSize()       {          int width = image.getWidth(this),              height = image.getHeight(this);          if(width == -1)             width = 100;          if(height == -1)             height = 100;          return new Dimension(width,height);       }    }    public VisualProduct(String text,                         String id,                         boolean checked,                         String image)    {       super(text,id,checked);       this.image = image;    }    public String getImage()    {       return image;    }    public Component getComponent()    {       return new ImageCanvas(image);    }    public void accept(CatalogVisitor visitor)       throws IOException    {       visitor.visitVisualProduct(this);    } } 
   


Applied XML Solutions
Applied XML Solutions
ISBN: 0672320541
EAN: 2147483647
Year: 1999
Pages: 142

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