RSS Viewer Applet: Ready to Rumble (4/6) - exploring XML | WebReference

RSS Viewer Applet: Ready to Rumble (4/6) - exploring XML

RSS Viewer Applet: Ready to Rumble

Drawing Logic

If an error occurred in the initialization phase of the applet, the paint() routine writes out the respective exception. Most often there is a problem with the URL of the RSS file, or the format of the RSS file itself. If everything is okay, the user interface is drawn by delegating to the paintBox(), paintTitle(), paintItem() methods:
  public void paint(Graphics g) {
    if (ex != null) { // error occurred
      g.drawString("Error loading RSS file:", 0, 10);
      g.drawString(ex.getMessage(), 0, 20);
    Rectangle bounds = new Rectangle(0, 0, getSize().width, getSize().height);
    paintBox(g, bounds);
    paintTitle(g, bounds);
    bounds.x += itemMargin;
    bounds.width -= 2 * itemMargin;
    for (int i=0; i < channel.getNumberOfItems(); i++) {
      paintItem(g, bounds, i);

Painting the bounding box is as simple as drawing to filled rectangles inside each other with the right colors and bounds. Both title and item drawing are delegated further to paintline():

  private void paintBox(Graphics g, Rectangle bounds) {
    g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
    bounds.x += boxBorder; bounds.y += boxBorder;
    bounds.width -= 2 * boxBorder; bounds.height -= 2 * boxBorder;
    g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
  private void paintTitle(Graphics g, Rectangle bounds) {
    paintLine(g, bounds, titleBackground, titleBackgroundOnMouseOver,
      titleForeground, titleForegroundOnMouseOver, channel.getChannelTitle(),
      titleFont, titleAlign, -1, titleLineHeight, titleLineBase);
  private void paintItem(Graphics g, Rectangle bounds, int i) {
    paintLine(g, bounds, itemBackground, itemBackgroundOnMouseOver,
      itemForeground, itemForegroundOnMouseOver, channel.getItemTitle(i),
      itemFont, itemAlign, i, itemLineHeight, itemLineBase);
The workhorse in the drawing logic is paintLine() below which draws a single line of text in the right colors, pruned to the available width and properly aligned:
  private void paintLine(Graphics g, Rectangle bounds, Color background,
    Color backgroundOnMouseOver, Color foreground, Color foregroundOnMouseOver,
    String title, Font font, String align, int i, int lineHeight, int lineBase) {
    if (currentItem == i) g.setColor(backgroundOnMouseOver);
    else g.setColor(background);
    g.fillRect(bounds.x, bounds.y, bounds.width, lineHeight);
    if (currentItem == i) g.setColor(foregroundOnMouseOver);
    else g.setColor(foreground);
    int textX = bounds.x + 1; int textW = bounds.width - 2;
    String prunedString = getPrunedString(title, font, textW);
    g.drawString(prunedString, textX + getStringStartPosX(prunedString, font, textW, align), bounds.y + lineBase);
    bounds.y += lineHeight + itemMargin;

Depending on the mouse position the right colors are set for the text line, and the to-be-displayed text is pruned to the available width. The result is drawn at the right position according to the specified alignment. Furthermore the status line now shows the target URL for every channel item, so it finally becomes intuitive to click on the entries:

  private void showStatus() {
    String status;
    if (currentItem == -2 || currentItem >= channel.getNumberOfItems()) status = "";
    else if (currentItem == -1) status = channel.getChannelLink().toString();
    else status = channel.getItemLink(currentItem).toString();

Next is standard applet stuff and event handling.

Produced by Michael Claßen
All Rights Reserved. Legal Notices.

Created: Mar. 12, 2000
Revised: Mar. 12, 2000